【问题标题】:My Sobel Edge Detection Operator Output is weird我的 Sobel 边缘检测算子输出很奇怪
【发布时间】:2016-10-03 19:45:29
【问题描述】:

我的 Sobel 边缘检测算子的输出很奇怪。 这是我的代码:

    BufferedImage temp = img;
    float kernelx[][] = {{-1, 0, 1},{-2, 0, 2},{-1, 0, 1}};
    float kernely[][] = {{-1, -2, -1},{0,  0,  0},{1,  2,  1}};
    float valx = 0;
    float valy = 0;
    float val = 0;
        for(int i=1;i<width-2;i++) {
           for(int j=1;j<height-2;j++) {
               valx = (kernelx[0][0]*new Color(img.getRGB(i-1, j-1)).getRed()) + (kernelx[0][2]*new Color(img.getRGB(i+1, j-1)).getRed()) +
                     (kernelx[1][0]*new Color(img.getRGB(i-1, j)).getRed()) + (kernelx[1][2]*new Color(img.getRGB(i+1, j)).getRed()) +
                     (kernelx[2][0]*new Color(img.getRGB(i-1, j+1)).getRed()) + (kernelx[2][2]*new Color(img.getRGB(i+1, j+1)).getRed());

               valy = (kernely[0][0]*new Color(img.getRGB(i-1, j-1)).getRed()) + (kernely[0][1]*new Color(img.getRGB(i, j-1)).getRed()) + (kernely[0][2]*new Color(img.getRGB(i+1, j-1)).getRed()) +
                       (kernely[2][0]*new Color(img.getRGB(i-1, j+1)).getRed()) + (kernely[2][1]*new Color(img.getRGB(i, j+1)).getRed()) + (kernely[2][2]*new Color(img.getRGB(i+1, j+1)).getRed());

               val = (float)sqrt(valx*valx+valy*valy);

               val = val/1443*255;
               if(val <= 127) {
                   val = 0;
               } else {
                   val = 255;
               }
               temp.setRGB(i, j, new Color((int)val,(int)val,(int)val).getRGB());
           }
           File outputfile = new File("src/image/edge.png");
           ImageIO.write(temp, "png", outputfile);
        }

我的代码有什么问题吗?请帮我。 这是结果的图片。

原图:

结果图片:

【问题讨论】:

    标签: java image-processing edge-detection sobel


    【解决方案1】:

    您的代码中存在不同的问题:

    • 使用尺寸为 3x3 的内核时,您从 [1,1] 变为 ]width-1,height-1[,而不是 ]width-2,height-2[。
    • 在 java 中,使用 image.getRaster().getSample(x, y, channel),而不是 'new Color(img.getRGB(i-1, j-1)).getRed())'。它会更快,更容易理解。写image.getRaster().setSample(x, y, channel, value)时也是如此
    • 当在 [0,max] 上编码的图像上计算 Sobel 梯度时,每个方向(X 和 Y)都会为您提供 [-4*max, 4*max] 上的值。因此,削减超出的值是积极的。您可能希望执行直方图拉伸,然后您将保留更多信息。
    • 标准化val = val/1443*255; 由您决定,但不是必需的。
    • 最后是主要问题进入您的代码。结果(或在您的情况下为临时)图像和原始图像必须不同。否则,您在处理图像的同时修改图像。这就解释了为什么你有这么大的白色区域。

    【讨论】:

    • 啊,我明白了,谢谢你的回答,让我尝试修复我的代码,我会告诉你结果..
    • 是的,最后一点是主要问题,也是第一个问题。不要忘记第三个以获得更好(更精确)的结果。第二个是一个好习惯:-)
    猜你喜欢
    • 2016-11-07
    • 2014-10-17
    • 2021-06-02
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2015-01-02
    相关资源
    最近更新 更多