Python 和 opencv : how do I convert the ALL of the background of this image to one colour or transparent

标签 python image opencv

我在图像 1 上使用阈值蒙版(图像 2)创建了以下图像(图像 3)。我试图将图像 3(肺)的中心图像之外的所有像素转换为一种颜色(例如黑色)使用 opencv。基本上这样我就只剩下肺部在统一背景(甚至透明)下的图像。我的问题是图像 3 上最外层的像素与肺部内部的像素相似。使用 opencv 可以做到这一点吗?

IMAGE 1

IMAGE 2

IMAGE3

最佳答案

简单floodFill()图像边界的蒙版为黑色。请参阅我的答案中的洪水填充步骤 here看看它在另一个场景中的使用。

同样,您可以使用 floodFill() 来查找哪些像素连接到图像的边缘,这意味着您可以使用它来消除肺部的孔洞以防止阈值化。看我的回答here有关此孔填充过程的不同示例。

我直接从上面的答案中复制粘贴了代码,只修改了变量名:

import cv2
import numpy as np 

img = cv2.imread('img.jpg', 0)
mask = cv2.imread('mask.png', 0)

# flood fill to remove mask at borders of the image
h, w = img.shape[:2]
for row in range(h):
    if mask[row, 0] == 255:
        cv2.floodFill(mask, None, (0, row), 0)
    if mask[row, w-1] == 255:
        cv2.floodFill(mask, None, (w-1, row), 0)
for col in range(w):
    if mask[0, col] == 255:
        cv2.floodFill(mask, None, (col, 0), 0)
    if mask[h-1, col] == 255:
        cv2.floodFill(mask, None, (col, h-1), 0)

# flood fill background to find inner holes
holes = mask.copy()
cv2.floodFill(holes, None, (0, 0), 255)

# invert holes mask, bitwise or with mask to fill in holes
holes = cv2.bitwise_not(holes)
mask = cv2.bitwise_or(mask, holes)

# display masked image
masked_img = cv2.bitwise_and(img, img, mask=mask)
masked_img_with_alpha = cv2.merge([img, img, img, mask])
cv2.imwrite('masked.png', masked_img)
cv2.imwrite('masked_transparent.png', masked_img_with_alpha)

编辑:顺便说一句,“透明度”基本上是一个 mask :值告诉您每个像素的不透明度。如果像素为 0,则它是完全透明的,如果它是 255(对于 uint8),则它是完全不透明的,如果它介于两者之间,则它是部分透明的。因此,可以将此处最后使用的完全相同的掩码堆叠到图像上以创建第四个 alpha channel (您可以使用 cv2.merge 或 numpy 进行堆叠),它将使面具完全透明;只需将图像保存为 png 以获得透明度。上面的代码创建了一个具有 alpha 透明度的图像以及一个具有黑色背景的图像。

Masked lungs with transparency

这里的背景看起来是白色的,因为它是透明的,但是如果将图像保存到系统中,您会发现它实际上是透明的。仅供引用,OpenCV 实际上在 imshow() 期间忽略了 alpha channel ,因此您只会在保存图像时看到透明度。


编辑:最后一点……这里您的阈值已经移除了一些肺部。我已经在肺部 内部 发生的阈值处理中添加了孔,但这会遗漏一些沿着边界被移除的 block 。如果您在蒙版上进行轮廓检测,如果它很重要,您实际上也可以将它们平滑一些。查看 OpenCV 的 contour features tutorial 上的“轮廓近似”部分.基本上它会尝试使轮廓平滑,但会保持在距实际轮廓一定的 epsilon 距离内。这可能很有用并且易于实现,所以我想我会把它作为建议放在最后。

关于Python 和 opencv : how do I convert the ALL of the background of this image to one colour or transparent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47483411/

相关文章:

python - 使用 Python 打开新窗口时,selenium window_handles 不正确

html - 如何将图像并排放置?

c++ - 锐化图像 - 访问邻近像素

Python:从处理后的图像中创建视频

c++ - 检测图像中的填充矩形

python - 有没有一种方法可以测试两个形状是否可以在numpy中广播?

python - Sympy 函数替换

python - pytz 时区的 STD 偏移量

java.awt.Image getWidth 和 getHeight 方法不能正常工作?

c# - Picture Box 图片来源是否可能?