我的Sobel边缘检测算子输出很奇怪 [英] My Sobel Edge Detection Operator Output is weird

查看:167
本文介绍了我的Sobel边缘检测算子输出很奇怪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My output of Sobel edge detection operator is weird. Here's my code :

    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);
        }

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

Anything wrong about my code? Please help me. And this is the picture of the result.

原始图片:

结果图片:

推荐答案

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

There are different issues in your code:


  • 使用尺寸为3x3的内核时,从[1,1]到宽度-1,高度-1 [,而不是]宽度-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)

  • 计算Sobel梯度时在[0,max]上编码的图像,每个方向(X和Y)将给出[-4 * max,4 * max]的值。因此,削减超出的值是积极的。您可能希望执行直方图拉伸,然后您将保留更多信息。

  • 标准化 val = val / 1443 * 255; 取决于你,但没有必要。

  • 最后主要问题进入你的代码。结果(或你的情况下的温度)图像和原始图像必须不同。否则,您在处理图像的同时修改图像。这就解释了为什么你有这么大的白色区域。

  • When using a kernel of dimensions 3x3, you go from [1,1] to ]width-1,height-1[, not ]width-2, height-2[.
  • In java, use image.getRaster().getSample(x, y, channel), instead of 'new Color(img.getRGB(i-1, j-1)).getRed())'. It's going to be much faster and easier to understand. Same thing when writing image.getRaster().setSample(x, y, channel, value)
  • When computing a Sobel gradient on an image encoded on [0,max], each direction (X and Y) is going to give you values on [-4*max, 4*max]. So it's aggressive to cut the exceeded values. You may want to perform a histogram stretching instead, then you will keep much more information.
  • The normalization val = val/1443*255; is up to you, but not necessary.
  • And finally the main problem into your code. The resulting (or temp in your case) image and the original image MUST be different. Else you modify the image at the same time you process it. That explain why your have all this huge white area.

这篇关于我的Sobel边缘检测算子输出很奇怪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆