Sobel filter - 如何正确显示卷积结果?
Sobel filter - How to correctly display convolution result?
我目前正在尝试实现我自己的 Sobel-Filter/Operator 版本。我试图从维基百科 (https://en.wikipedia.org/wiki/Sobel_operator) 和 YouTube 上的大量解释中获取尽可能多的信息,但我找不到解决问题的方法。
所以在对我的图像进行灰度缩放后:
public BufferedImage grayscale(String path) {
BufferedImage img = readImage(path);
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
Color oldColor = new Color(img.getRGB(x, y));
int red = oldColor.getRed();
int green = oldColor.getGreen();
int blue = oldColor.getBlue();
int grayValue = (int) (0.244 * red + 0.587 * green + 0.114 * blue);
Color newColor = new Color(grayValue, grayValue, grayValue);
img.setRGB(x, y, newColor.getRGB());
}
}
return img;
}
我试图提取图像中应该与 Sobel-Operator Sx 进行卷积的部分。由于我对整个图像进行了灰度化,因此我认为使用红色部分应该没问题,因为所有值都应该相同:
public void sobel(BufferedImage grayScaledImg) {
for (int x = 1; x < grayScaledImg.getWidth() - 1; x++) {
for (int y = 1; y < grayScaledImg.getHeight() - 1; y++) {
int field1 = new Color(grayScaledImg.getRGB(x - 1, y - 1)).getRed();
int field2 = new Color(grayScaledImg.getRGB(x, y - 1)).getRed();
int field3 = new Color(grayScaledImg.getRGB(x + 1, y - 1)).getRed();
int field4 = new Color(grayScaledImg.getRGB(x - 1, y)).getRed();
int field5 = new Color(grayScaledImg.getRGB(x, y)).getRed();
int field6 = new Color(grayScaledImg.getRGB(x + 1, y)).getRed();
int field7 = new Color(grayScaledImg.getRGB(x - 1, y + 1)).getRed();
int field8 = new Color(grayScaledImg.getRGB(x, y + 1)).getRed();
int field9 = new Color(grayScaledImg.getRGB(x + 1, y + 1)).getRed();
int[] currentPartOfImage = {field1, field2, field3, field4, field5, field6, field7, field8, field9};
而且我很确定在下面的代码中我做错了什么,但我不知道是什么..
int newGrayScale = sobelX(currentPartOfImage);
grayScaledImg.setRGB(x, y, new Color(newGrayScale, newGrayScale, newGrayScale).getRGB());
}
}
}
sobelX 函数如下所示:
public int sobelX(int[] image) {
return Math.abs(image[2] + (2 * image[5]) + image[8] - image[0] - (2 * image[3]) - image[6]);
}
问题
我在进行卷积时得到的一些值大于 255,这意味着它们不是有效的 RGB 值。所以我目前不确定如何正确使用这些值?
在此先感谢您的帮助! :)
Some of the values i get while doing the convolution are larger than 255
这通常可以通过使用 "clamp" function 来解决。它是一个检查参数是否在允许范围内的函数,如果不在,returns最接近的允许值。
int clamp(int value) {
if (value > 255) return 255;
if (value < 0) return 0;
return value;
}
这就是您的使用方式:
int newGrayScale = clamp(sobelX(currentPartOfImage));
我目前正在尝试实现我自己的 Sobel-Filter/Operator 版本。我试图从维基百科 (https://en.wikipedia.org/wiki/Sobel_operator) 和 YouTube 上的大量解释中获取尽可能多的信息,但我找不到解决问题的方法。
所以在对我的图像进行灰度缩放后:
public BufferedImage grayscale(String path) {
BufferedImage img = readImage(path);
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
Color oldColor = new Color(img.getRGB(x, y));
int red = oldColor.getRed();
int green = oldColor.getGreen();
int blue = oldColor.getBlue();
int grayValue = (int) (0.244 * red + 0.587 * green + 0.114 * blue);
Color newColor = new Color(grayValue, grayValue, grayValue);
img.setRGB(x, y, newColor.getRGB());
}
}
return img;
}
我试图提取图像中应该与 Sobel-Operator Sx 进行卷积的部分。由于我对整个图像进行了灰度化,因此我认为使用红色部分应该没问题,因为所有值都应该相同:
public void sobel(BufferedImage grayScaledImg) {
for (int x = 1; x < grayScaledImg.getWidth() - 1; x++) {
for (int y = 1; y < grayScaledImg.getHeight() - 1; y++) {
int field1 = new Color(grayScaledImg.getRGB(x - 1, y - 1)).getRed();
int field2 = new Color(grayScaledImg.getRGB(x, y - 1)).getRed();
int field3 = new Color(grayScaledImg.getRGB(x + 1, y - 1)).getRed();
int field4 = new Color(grayScaledImg.getRGB(x - 1, y)).getRed();
int field5 = new Color(grayScaledImg.getRGB(x, y)).getRed();
int field6 = new Color(grayScaledImg.getRGB(x + 1, y)).getRed();
int field7 = new Color(grayScaledImg.getRGB(x - 1, y + 1)).getRed();
int field8 = new Color(grayScaledImg.getRGB(x, y + 1)).getRed();
int field9 = new Color(grayScaledImg.getRGB(x + 1, y + 1)).getRed();
int[] currentPartOfImage = {field1, field2, field3, field4, field5, field6, field7, field8, field9};
而且我很确定在下面的代码中我做错了什么,但我不知道是什么..
int newGrayScale = sobelX(currentPartOfImage);
grayScaledImg.setRGB(x, y, new Color(newGrayScale, newGrayScale, newGrayScale).getRGB());
}
}
}
sobelX 函数如下所示:
public int sobelX(int[] image) {
return Math.abs(image[2] + (2 * image[5]) + image[8] - image[0] - (2 * image[3]) - image[6]);
}
问题
我在进行卷积时得到的一些值大于 255,这意味着它们不是有效的 RGB 值。所以我目前不确定如何正确使用这些值?
在此先感谢您的帮助! :)
Some of the values i get while doing the convolution are larger than 255
这通常可以通过使用 "clamp" function 来解决。它是一个检查参数是否在允许范围内的函数,如果不在,returns最接近的允许值。
int clamp(int value) {
if (value > 255) return 255;
if (value < 0) return 0;
return value;
}
这就是您的使用方式:
int newGrayScale = clamp(sobelX(currentPartOfImage));