填补图像边界/轮廓之间的间隙

时间:2018-08-27 01:21:59

标签: opencv image-processing scikit-image smoothing flood-fill

我有两张图像想合并在一起,合并后消除/消除边界之间的间隙。左边的图像是边缘,而右边的图像是遮罩。 (忽略右图上的小补丁,但是也能够删除它会很好)

Border Predicted Mask

合并后的预期结果是

expected result

但这是到目前为止取得的当前结果

current result

我尝试了与scikit-image api不同的策略,其中包括:

ndi.binary_openingndi.binary_closingmorphology.{erosion, dilation, opening, closing},但它们似乎都不起作用。

2 个答案:

答案 0 :(得分:0)

我认为这可能是制定策略的基础...

第1步:

“边缘图片” 开始。随机选择任何白色像素。使用该像素作为种子或起点,用黑色填充黑色。这应该填充边缘的一侧。记住种子,获取新的质心(可能还有面积),并用黑色区域填充。反转填充的图像并获得图像另一部分的质心。

您现在知道了边缘两边的质心-如下面的红色标记所示:

enter image description here

第2步:

现在移至遮罩图像。也许使用膨胀/侵蚀来填充任何小孔。然后在图像上运行“标签”以获取连续的黑色斑点及其质心和区域的列表。按面积选择最大的斑点。

您现在应该具有最大斑点的质心,如下绿色标记:

enter image description here

第3步:

现在选择两个红色点中最接近绿色的点,并使用相应的种子进行填充。


在第1步中最好反复随机选择白色种子点,直到获得不同的质心为止,而不是进行反演。那是因为如果您仅反转并获得质心,就​​不会知道种子像素好。不能确定质心是好种子。

答案 1 :(得分:0)

似乎您需要找到 mask 函数的质心(CoM)来确定要填充的面,然后使用floodFill来自CoM的图像作为种子点。

您可以尝试这样的事情:

# Calculate the Center of Mass
com = np.zeros(2)
sum = np.zeros(2)
for x in range(0, nu_of_rows):
    for y in range(0, num_of_cols):
        com += image[x][y] * np.array([x,y])
        sum += image[x][y]
com /= sum

# FloodFill a new image
h, w = mask_img.shape[:2]
new_image = mask_img.copy()
temp = np.zeros((h+2,w+2),np.uint8) # Needs to be 2 pixels wider/higher
cv2.FloodFill(new_image, temp, coi, 255, flags=cv2.FLOODFILL_MASK_ONLY)

如果 edge mask 图像中的行具有值255和背景0,这将起作用。如果不是这种情况,请首先使用以下命令反转两个图像:

inverted_img = cv2.bitwise_not(img)

注意:我不是用您的图像来测试,而是用我的一个来测试。因此,您可能必须在这里和那里进行一些更改。这是我的 rough 示例工作:

enter image description here