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

示例图片:



这是我的代码:

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)

而且有效。我使用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))

我尝试对每个单元进行细分,但结果相当不理想。只有具有“孔”的单元的内部才被分割。

第一张图片显示了我的结果,第二张图片显示了它的大致外观:



然后,我手动填补了漏洞,只是为了查看我的细分代码是否有效-并且可以正常工作。该错误应该在我绘制轮廓的部分和我计算欧几里德距离的部分之间的某个地方。有人可以向我解释什么可能是错误的吗?我无能为力。

最佳答案

您的问题出在以下几行:

labels = watershed(-D, markers, mask=thresh)

您将通过阈值传递的反转的,未校正的结果作为遮罩传递:

python - 使用cv2在python中填充图像的 “holes”不起作用-LMLPHP

给您这种不好的细分:

python - 使用cv2在python中填充图像的 “holes”不起作用-LMLPHP

而您应该通过更正并填写的掩码:
labels = watershed(-D, markers, mask=newimg)

python - 使用cv2在python中填充图像的 “holes”不起作用-LMLPHP

给您您可能期望的结果:

python - 使用cv2在python中填充图像的 “holes”不起作用-LMLPHP

07-26 07:03