Canny 边缘检测是否应该不检测纯的、非旋转的水平线?
这些是输入图像:
左 100% 水平(非旋转)非模糊线
右:旋转 1° 的同一图像
对应的输出“边缘”图像:
(为了更好的判断,图像在这里缩放了 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 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 的局限性,那么处理此类情况的常用方法是什么(简而言之)?
我是根据经验来处理这个问题的:我创建了一个白到黑的渐变图像 上面有黑色的光栅图案。光栅应代表 不同背景上原始测试图像的线条。
这是我们的输入图像:
(为更漂亮的帖子裁剪和调整大小,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
这是结果:
可以看出,Canny 无法在最小值上检测到越来越多的边缘 值侧(顶部)随着阈值的降低而增加。我预料到了这一点。尽管在最大值方面,无论给定什么阈值,Canny 都永远无法检测到边缘。
最佳答案
尝试保存图像,然后直接打开图像文件。这可能只是绘图仪如何渲染图像的问题。
我自己也遇到了同样的问题,但是已经解决了。我正在使用 matplotlib 通过 jupyter notebook 查看我的边缘图像。 100% 的水平边缘在笔记本内部显示时不会呈现。但是当我将它保存为png并直接打开图像文件时,水平边缘实际上就在那里。
https://stackoverflow.com/questions/58884116/
相关文章:
amazon-web-services - 您应该使用客户端凭据授权类型来验证服务器到服务器吗?
mysql - 在 macOS Catalina 10.15.1 下安装 DBD::mysql 时遇
python - 设置 scipy.signal.peak_widths 的绝对值
apache-spark - 使用来自 s3 存储桶的数据在 AWS EMR 上使用 pyspark
leaflet - 校正 Rayshader 的卫星图像覆盖
google-cloud-platform - 使用 --allow-unauthenticated
apache-zookeeper - Chubby Sequencer 的目的是什么
docker - 让 docker build --memory-swap=20g 使用可用的交换空