我为Sobel算子编写了一个用于边缘检测的类,但是当我使用示例图像时,我的边缘是关闭的。非常感谢有人可以帮助我。
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.Raster;
import java.util.Arrays;
class SobelFilter {
private static final float[] sobel1 = { 1.0f, 0.0f, -1.0f};
private static final float[] sobel2 = { 1.0f, 2.0f, 1.0f};
private static final boolean[] sobelBoolean = {true, false};
private SobelFilter() {}
private static ConvolveOp getSobelX(boolean fs) {
Kernel kernel = null;
if (fs) {
kernel = new Kernel(1, 3, sobel1);
}
else {
kernel = new Kernel(3, 1, sobel2);
}
return new ConvolveOp(kernel, ConvolveOp.EDGE_ZERO_FILL, null);
}
private static ConvolveOp getSobelY(boolean fs) {
Kernel kernel = null;
if (fs) {
kernel = new Kernel(1, 3, sobel2);
}
else {
kernel = new Kernel(3, 1, sobel1);
}
return new ConvolveOp(kernel, ConvolveOp.EDGE_ZERO_FILL, null);
}
public static BufferedImage getSobelFilter(BufferedImage img) {
int width = img.getWidth();
int height = img.getHeight();
int size = width * height;
int[] x = new int[size];
int[] y = new int[size];
int[] pixelM = new int[size];
//double[] pixelD = new double[size];
BufferedImage sobelX = null;
BufferedImage sobelY = null;
for(boolean i : sobelBoolean) {
sobelX = getSobelX(i).filter(img, null);
sobelY = getSobelY(i).filter(img, null);
}
sobelX.getRaster().getPixels(0, 0, width, height, x);
sobelY.getRaster().getPixels(0, 0, width, height, y);
for(int i = 0; i < size; i++) {
pixelM[i] = (int) Math.hypot(x[i], y[i]);
//pixelD[i] = Math.atan2((double) y[i], (double) x[i]);
}
BufferedImage result =
new BufferedImage(width, height,
BufferedImage.TYPE_BYTE_GRAY);
result.getRaster().setPixels(0, 0, width, height, pixelM);
return result;
}
}
我使用维基百科的阀门图片作为例子。
答案 0 :(得分:2)
您绘制的是渐变的Y分量。考虑一下:
g2.drawImage(sobelX, null, 0, 0);
g2.drawImage(sobelY, null, 0, 0);
sobelX
隐藏在sobelY
后面,因此您只能看到后者。
你想要的是渐变的标准。您必须扫描两张图片,并为z = sqrt(x*x + y*y)
的每个像素x
及其sobelX
的{{1}}计算y
。
伪代码:
sobelY