【问题标题】:How to add multiple binary masks?如何添加多个二进制掩码?
【发布时间】:2019-11-04 05:06:49
【问题描述】:

我有一组图像(不同焦距),在这些图像上我找到了二进制掩码。其中一些蒙版是重叠的,现在我想将所有这些蒙版添加在一起以生成一个大的图像蒙版。有没有办法将这些蒙版添加在一起并只考虑一次重叠区域。在考虑重叠区域时,它应该只考虑具有最大边缘的区域(来自边缘检测)。

所以现在掩码拥有所有图像的所有掩码。现在我想把这些面具加在一起。任何帮助表示赞赏。

这些是原始图像及其蒙版。 Link to images

因此,如果橙色在重叠区域中有更多的边缘检测点,则应考虑使用它,而绿色应仅具有不常见的点。橙色和绿色是这里的两个面具。

for file in glob.glob("images/*.jpg")
      img = cv2.imread(file)  
      ret, mask = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY)  

【问题讨论】:

  • 我不明白关于“最大边”的评论。请澄清和/或提供您的面具图片,以便我们更好地理解。
  • @fmw42 最大边缘是指通过边缘检测获得的最大边缘点数。我会添加口罩的参考照片。
  • 掩码是二进制的。如果你只想要一个面具,那么当你组合它们时,你只需将它们加在一起。因此,重叠将不知道要使用哪个图像,因为结果仍然是二进制的。您必须使用掩码将生成的掩码图像与某些优先级排序结合起来,方法是使用掩码区域标记掩码图像,或者更好地按区域对掩码进行排序,然后以相反的优先级顺序覆盖它们,以便最后处理最大的..我目前没有代码。
  • @fmw42 感谢分享。但是如何添加蒙版以获得一个蒙版?
  • 只需添加它们并在 OpenCV 中进行剪辑 cv.add(mask1, mask2, ... maskN).clip(0,255)。但这不会使用一个掩码使用最大掩码的区域,因为所有关于掩码大小的知识都已丢失。

标签: python numpy opencv image-processing computer-vision


【解决方案1】:

这是使用 Python/OpenCV 一起添加多个掩码的一种方法。

  • 读取掩码并转换为 0 到 1 范围内的浮点数
  • 使用 Python 加法添加掩码并乘以 255
  • 将生成的蒙版剪切到 0 到 255 的范围内,然后转换回 int。


import cv2

# read masks
mask1 = cv2.imread('mask1.png').astype("float32")
mask2 = cv2.imread('mask2.png').astype("float32")
mask3 = cv2.imread('mask3.png').astype("float32")
mask4 = cv2.imread('mask4.png').astype("float32")

# add masks
result = 255*(mask1 + mask2 + mask3 + mask4)
result = result.clip(0, 255).astype("uint8")

# show results
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save results
cv2.imwrite('mask1-4.png', result)

面具:

生成的组合掩码:

补充:

你也可以这样做:

import cv2
import numpy as np

# read masks
mask1 = cv2.imread('mask1.png')
mask2 = cv2.imread('mask2.png')
mask3 = cv2.imread('mask3.png')
mask4 = cv2.imread('mask4.png')

# make list
masks = [mask1, mask2, mask3, mask4]

# add masks
h, w, c = mask1.shape
result = np.full((h,w,c), (0,0,0), dtype=np.uint8)
for mask in masks:
    result = cv2.add(result, mask)

# show results
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save results
cv2.imwrite('mask1-4.png', result)


【讨论】:

  • 这看起来很棒。我尝试循环读取我的蒙版,然后应用剪辑,但结果是黑屏。任何指针我做错了什么。这是我尝试过的。 for i in mask: result = 255*(mask[i]) result = result.clip(0, 255).astype("uint8")
  • 你的面具是浮动图像吗?如果不是,则不要乘以 255。在您的情况下,结果似乎被每个新掩码覆盖。他们没有被添加。也许你的意思是 +=。或者为每个掩码尝试 result = cv2.add(result, mask)。
  • 在我的答案中查看我的添加,了解一种无需先转换为浮动的循环方式。
【解决方案2】:

二进制标记只是具有 0 或 1 值的图像大小的矩阵,当应用掩码时,所有发生的事情都是每个值与其掩码值相乘,如果要删除像素,则掩码值为 0,因此当相乘时,您会得到一个黑色像素,如果不将其移除,则保留原始值,因为它与 1 相乘。

要合并蒙版,只需将蒙版添加在一起,任何不应该被蒙版的区域都将保持为 0。

简单之后做这样的事情

combined_masks[combined_masks > 1] = 1

这将再次将您的掩码转换为二进制掩码

所以基本上把它想象成一个维恩图,如果有 2 个重叠的圆圈作为你的蒙版,这些圆圈的并集就是组合蒙版

如下图所示,A 和 B 是你的掩码,灰色区域,它们的“联合”是你的组合掩码

更新 ::: 如果您只想要这些掩码中的公共区域,您仍然可以将掩码添加在一起并执行以下操作

combined_masks /= total_num_masks
combined_masks[combined_masks < 1] = 0

更新 ::: 假设您有 n 个形状为 img_w、img_h 的掩码,这就是您将它们组合起来的方式。

unified_masks = np.zeros((img_w, img_h))

for mask in list_of_masks:
    unified_masks += mask

unified_masks[unified_masks > 1] = 1

【讨论】:

  • 感谢分享。但是在处理重叠区域时,我想考虑点数最多的区域;意思是说考虑这个维恩图的相交区域,其中两个区域 A 和 B 有一些共同的区域。假设 A 在公共区域中有 10 个点,而 B 只有 5 个。那么对于最终的掩码,我想考虑整个 A 区域和区域 B,不包括公共区域中的点(没有重复点)。现在将这些区域视为边缘检测图像,A 有 10 个边缘点,而 B 有 5 个 I 只有 A 区域,B 不包括公共区域中的点。
  • 并且它应该与集合中的所有图像进行比较。就像我的情况一样说6。我已附上图片供您参考
  • 你能不能以某种方式说明这一点,它有点难以理解
  • 我添加了一张图片来说明这一点。
  • 我明白了,所以如果你的橙色圆圈有更大的点,我们会取整个区域,只取绿色区域中不重叠的部分,对吧?
【解决方案3】:

非常简单的解决方案就是使用二进制操作。如果您想将所有掩码连接在一起,只需使用 |运营商:

combined_mask = mask1 | mask2 | mask3 

解决方案摘自:https://answers.opencv.org/question/123613/how-to-make-a-composite-mask/

【讨论】:

    猜你喜欢
    • 2020-04-13
    • 1970-01-01
    • 2021-08-16
    • 2021-07-31
    • 2021-08-14
    • 1970-01-01
    • 2015-04-15
    • 2013-08-09
    • 2017-03-19
    相关资源
    最近更新 更多