使用 cv2 填充 python 中图像的“孔”不起作用

Lum*_*aja 5 python opencv image-processing

我试图在执行二进制阈值后填充图像中红细胞的“孔”。当反转二进制阈值时,几乎所有红细胞都有一个黑色中心。我想删除它们。

示例图片:

示例图像


这是我的代码:

import cv2 
from PIL import Image
import numpy as np
from scipy import ndimage
from skimage.feature import peak_local_max
from skimage.morphology import watershed

image = cv2.imread("blood_cells.jpg")

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
darker = cv2.equalizeHist(gray)
ret,thresh = cv2.threshold(darker,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
newimg = cv2.bitwise_not(thresh)

im2, contours, hierarchy = cv2.findContours(newimg,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:
    cv2.drawContours(newimg,[cnt],0,255,-1)
Run Code Online (Sandbox Code Playgroud)

它奏效了。findContours()我使用和填补了这些漏洞drawContours()

但是当我尝试计算欧几里德距离时,为了应用分水岭算法,我只得到 52 个独特的段,但应该有更多。这是代码,如果有帮助的话:

D = ndimage.distance_transform_edt(newimg)
localMax = peak_local_max(D, indices=False, min_distance=20, labels=thresh)
markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]
labels = watershed(-D, markers, mask=thresh)
print("[INFO] {} unique segments found".format(len(np.unique(labels)) - 1))
Run Code Online (Sandbox Code Playgroud)

我尝试对每个细胞进行分割,但结果却很糟糕。只有具有“孔”的细胞内部才被分割。

第一张图显示了我的结果,第二张图显示了它的大致样子:

第一张图显示了我的结果,第二张图显示了它大致的样子

然后我手动填补了这些漏洞,只是为了看看我的分段代码是否有效 - 它确实有效。错误应该是在我绘制轮廓的部分和我计算欧几里得距离的部分之间。有人能向我解释一下可能出了什么问题吗?我一无所知。

Dan*_*šek 6

您的问题在于以下行:

labels = watershed(-D, markers, mask=thresh)
Run Code Online (Sandbox Code Playgroud)

您将阈值处理的反转的、未经校正的结果作为掩码传递:

面具不好

给你这个糟糕的分割:

不好的结果

而您应该通过更正后的填充掩码:

labels = watershed(-D, markers, mask=newimg)
Run Code Online (Sandbox Code Playgroud)

好面膜

为您提供您可能期望的结果:

好结果