OpenCV - 如何通过二进制图像传递模式匹配内核?

标签 opencv image-processing contour

我正在为二进制图像中的像素宽轮廓实现轮廓查找算法。它需要对删除单个像素(即像素宽的间隙)具有鲁棒性。

膨胀和侵 eclipse 内核的各种尝试都没有产生可靠的解决方案。

相反,我想要实现的可靠解决方案是在图像上传递一个模式匹配内核,它可以根据周围的像素直接填充间隙。例如,当在某个位置观察到左侧的确切模式时,将其替换为右侧(其中 * 表示通配符):

[1 * *]          [1 * *]
[* 0 *]   ==>    [* 1 *]
[* * 1]          [* * 1]

[1 0 *]          [1 0 *]
[* 0 1]   ==>    [* 1 1]
[* * *]          [* * *]

[* 1 *]          [* 1 *]
[* 0 *]   ==>    [* 1 *]
[* 1 *]          [* 1 *]

并定义大约 14 个必要的替换,以填补每个 3x3 窗口中可能存在的空白。

它可以在原始 Python 中实现,但如果没有低级矢量化操作,它可能会非常慢。

这可以通过 OpenCV 或其他一些快速操作来完成吗?

最佳答案

感谢@beaker 上面的评论,我实现了一个解决方案。设计一个内核,其相邻像素为 0.5,中心为 1,如果缺少像素,它将用 1 填充中心,尽管其他一些像素将为 2。然后将值裁剪为 1,您将获得所需的结果.

它需要独立应用于间隙的每个方向,这并不理想但仍然有效。

img_with_gap = np.array(
           [[1,0,0,0,0],
            [0,1,0,0,0],
            [0,0,0,0,0],
            [0,0,0,1,0],
            [0,0,0,0,1]], dtype=np.uint8)


kernel = np.array(
              [[0.5,  0,   0],
               [0  ,  1,   0],
               [0  ,  0, 0.5]])


connected_img = np.minimum(cv2.filter2D(img_with_gap, -1, kernel), 1)
connected_img

一个更严格的实现是通过惩罚零来进行精确的模式匹配,剪裁到 {0,1} 并确保没有从原始图像中删除任何内容:

kernel = np.array([[0.5,  -10.0,   -10.0],
                   [-10.0  ,  1,   -10.0],
                   [-10.0  ,  -10.0, 0.5]])

connected_img = np.maximum(img, np.clip(cv2.filter2D(img, -1, kernel), 0, 1))

关于OpenCV - 如何通过二进制图像传递模式匹配内核?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65774635/

相关文章:

c++ - iPhone OpenCV形状识别教程

python - python 3.6.4 中的错误 Opencv 3

c++ - 使用 opencv 进行 qt5 部署,如何修复 lib 安装路径?

python - python中的连接组件属性

python - cv2.findContours 无法检测轮廓

c++ - OpenCV 3.0.0 MSER 二进制掩码

opencv - 当我只绘制更大的轮廓对象时,Python Opencv drawContours 失败

python - OpenCV 匿名/保证唯一窗口

c++ - 无法使用 ubuntu opencv c++ 打开相机

python - 设置Python OpenCV warpPerspective的背景