问题描述
我正在为二进制图像中的像素宽轮廓实施轮廓查找算法。它需要对删除单个像素(即像素宽的间隙)具有鲁棒性。
对膨胀和腐蚀内核的各种尝试都没有产生可靠的解决方案。
相反,我想要实现的可靠解决方案是在图像上传递一个模式匹配内核,它可以根据周围的像素直接填充间隙。例如,当在某个位置观察到左侧的确切模式时,将其替换为右侧(其中 * 表示通配符):
[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,1,1]],dtype=np.uint8)
kernel = np.array(
[[0.5,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,0.5]])
connected_img = np.maximum(img,np.clip(cv2.filter2D(img,1))