gpt4 book ai didi

java - Canny 边缘检测不检测 100% 水平/未旋转的线

转载 作者:行者123 更新时间:2023-12-05 07:17:14 25 4
gpt4 key购买 nike

Canny 边缘检测是否应该检测纯的、非旋转的水平线?

这些是输入图像:

100% 水平(非旋转)非模糊线
右:旋转 1° 的同一图像

Pure horizontal lines, input image Horizontal lines 1° rotated, input image

对应的输出“边缘”图像:

Pure horizontal lines, output image Horizontal lines 1° rotated, output image

(为了更好的判断,图像在这里缩放了 2 倍,没有平滑。)

使用阈值 low=250x0.66 和 high=250x1.33 以及内核大小 k=3 处理图像。

虽然阶梯图像产生了令人满意的结果,但前者图像却没有。

图像目前没有进一步预处理,您看到的是 Canny 中的内容。

我创建了第一张图片作为测试数据。这可能是一个构造的案例,尽管这样的线条可能会出现在现实世界的场景中。

MCVE:

public class q58884116 {
public static void main(String[] args) throws Exception {
System.load(new File(Paths.get("target", "classes", "libopencv_java412.so").toString()).getAbsolutePath());

File inFile = new File(args[0]);
File outFile = new File(args[1]);

Mat imageColor = Imgcodecs.imread(inFile.getAbsolutePath(), Imgcodecs.IMREAD_COLOR);
Mat patternProbeImage = new Mat();
Imgproc.cvtColor(imageColor, patternProbeImage, Imgproc.COLOR_BGR2GRAY);

Mat edges = new Mat();
// Value determined from histogram in Gimp.
Imgproc.Canny(patternProbeImage, edges, 250 * 0.66, 250 * 1.33, 3, true);

Imgcodecs.imwrite(outFile.getAbsolutePath(), edges);
}
}

输入图像(未缩放):input.png

  • 从 Git 编译
  • OpenCV 4.1.2
  • cmake 3.7.2
  • 海湾合作委员会 6.3.0
  • openjdk 1.8.0_232
  • 使用 Java 库。

构建步骤:

$ git clone https://github.com/opencv/opencv.git
$ cd opencv/
$ git checkout 4.1.2
$ cd cmake/
$ cmake -DCMAKE_INSTALL_PREFIX="/opt/opencv" ..
$ make -j4
$ make install

我必须承认,我不熟悉 Canny 背后的理论,甚至不熟悉一般的计算机视觉。我才刚刚开始。虽然我可以想象这可能是由 Sobel function 使用的 Gy 矩阵的零行引起的。 (在 Canny 函数文章中提到过)。

如果这确实是 Canny 的局限性,那么处理此类情况的常用方法是什么(简而言之)?


我是根据经验来处理这个问题的:我创建了一个白到黑的渐变图像上面有黑色的光栅图案。光栅应代表不同背景上原始测试图像的线条。

这是我们的输入图像:

Gradient with grating (cropped preview)

(为更漂亮的帖子裁剪和调整大小,download original。)

MCVE 被扩展以生成各种阈值范围的边缘(不是每种可能的组合都有,但数量相当):

for (int i = 0; i < 255 - 50; i++) {
Mat edges = new Mat();
Imgproc.Canny(patternProbeImage, edges, i, i + 50, 3, true);

Imgcodecs.imwrite(getOutputFile(outFile, "lb-0-" + String.format("%03d", i)).getAbsolutePath(), edges);
}

然后我们可以检查生成的边。

使用这个衬垫,可以生成所有图像的马赛克( Sprite ),以便更容易检查:

$ convert gradient-grating.out.lb-0-*.png +append  gradient-grating.out.lb.png

这是结果:

Edge image mosaic of the above input image

可以看出,Canny 无法在最小值上检测到越来越多的边缘值侧(顶部)随着阈值的降低而增加。我预料到了这一点。尽管在最大值方面,无论给定什么阈值,Canny 都永远无法检测到边缘。

最佳答案

尝试保存图像,然后直接打开图像文件。这可能只是绘图仪如何渲染图像的问题。

我自己也遇到了同样的问题,但是已经解决了。我正在使用 matplotlib 通过 jupyter notebook 查看我的边缘图像。 100% 的水平边缘在笔记本内部显示时不会呈现。但是当我将它保存为png并直接打开图像文件时,水平边缘实际上就在那里。

关于java - Canny 边缘检测不检测 100% 水平/未旋转的线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58884116/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com