首页 文章

我的Sobel边缘检测算子输出很奇怪

提问于
浏览
1

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

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

Original Image:

Original Image

Result Image:

Resulted Image

1 回答

  • 2

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

    • 当使用尺寸为3x3的内核时,从[1,1]到宽度-1,高度-1 [,而不是]宽度-2,高度-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; 取决于您,但不是必需的 .

    • 最后 the main problem 进入你的代码 . 结果(或你的情况下是临时的)图像和原始图像必须是不同的 . 否则,您在处理图像的同时修改图像 . 这就解释了为什么你有这么大的白色区域 .

相关问题