如何决定在膨胀操作中使用哪个内核(OpenCV/Python)?

3
我对OpenCV非常陌生,最近我正在尝试比较两张轨道图片:一张有火车,一张没有。在比较后,我应用了一个阈值,但是在白色区域里出现了一些“空洞”,我不想要这些。“空洞”。目前,我使用4个迭代的膨胀,并将内核设置为“无”,据我理解,“无”默认为3x3。

如何决定使用什么类型的内核,以便膨胀更好地使白色区域连续?如果可以去除背景中的小白色斑点,那就太好了。以下是代码:
resized = imutils.resize(img2, width=1050)
resized2 = imutils.resize(img3, width=1050)
grayA = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(resized2, cv2.COLOR_BGR2GRAY)
grayA = cv2.GaussianBlur(grayA,(7,7),0)
grayB = cv2.GaussianBlur(grayB,(7,7),0)
frameDelta = cv2.absdiff(grayA, grayB)
thresh = cv2.threshold(frameDelta, 20, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=4)

这里输入图像描述

本人对此完全初学者,因此非常感谢任何通用的改进比较方法的建议和意见!


2
你可以使用与你想要填充的孔或移除的斑点大致相同大小的卷积核,或者你可以迭代多次使用小型卷积核来填充或移除,其中迭代次数约为孔的大小除以滤波器的大小。 - fmw42
几个问题: 1)膨胀函数如何帮助去除斑点? 2)如何找到或估计给定图像中孔洞的大小? 3)我也尝试了非常多的迭代(10次),但它并没有真正填补孔洞。它只是让白色区域本身变得更大了。 - John
1
@John,我从你的问题中理解到,你想要制作一个单一的遮罩来训练区域(因此我建议使用closing而不是dilation,为了消除小点,可以使用Median Filter而不是Gaussian Filter,关于核大小,一种解决方案是循环使用可变的核大小,直到达到2个区域“background”和“mask”。 - Bilal
是的,这正是我想要的,谢谢。那么如何处理结构元素本身呢?另外,是否有自动检测是否存在2个区域的方法?我对循环方法有点怀疑,因为至少有3个变量在发挥作用:核大小、核形状、迭代次数,而且我不确定使用大核大小和少量迭代更好还是反之亦然,或者中间某个位置使用自定义的核。 - John
1
@John 自动检测是否存在2个区域的方法是 len(np.unique(mask))==2,其余部分需要尝试并确定最适合您需求的参数。 - Bilal
显示剩余2条评论
1个回答

5
也许这会让你对Python/OpenCV中的形态学有些了解。首先,我使用一个大小与小白斑点相当的正方形“开放”核来移除它们。然后,我使用一个水平矩形“闭合”核,大约与黑色间隙的大小相同,来填充它。 “开放”可以移除白色区域(或填充黑色间隙),而“闭合”可以移除黑色区域(或填充白色间隙)。

enter image description here

import cv2
import numpy as np

# read image as grayscale
img = cv2.imread('blob3.png', cv2.IMREAD_GRAYSCALE)

# threshold to binary
thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY)[1]

# apply morphology open with square kernel to remove small white spots
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (19,19))
morph1 = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

# apply morphology close with horizontal rectangle kernel to fill horizontal gap
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (101,1))
morph2 = cv2.morphologyEx(morph1, cv2.MORPH_CLOSE, kernel)

# write results
cv2.imwrite("blob3_morph1.png", morph1)
cv2.imwrite("blob3_morph2.png", morph2)

# show results
cv2.imshow("thresh", thresh)
cv2.imshow("morph1", morph1)
cv2.imshow("morph2", morph2)
cv2.waitKey(0)

词形学广场开放:

enter image description here

形态学矩形关闭:

enter image description here

替代形态正方形关闭:

enter image description here


谢谢!这基本上就是我想要的东西。我可以问一下您是如何决定结构元素的大小/结构的吗?仅仅是因为白点是方形的,白色间隙是水平的吗?另外,您是如何估计正方形内核的大小,例如,应该是19x19的? - John
是的,这些斑点都是正方形或矩形。如果我有圆形区域,我会使用等半径或拉长的椭圆来表示斑点的形状。核的大小大约与斑点的大小相同。最后,我尝试获取最小的核以完成任务。因此需要一些试验和调整。 - fmw42

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接