有没有办法填补图像中两个部分之间的空白?

2024-04-25 07:14:22 发布

您现在位置:Python中文网/ 问答频道 /正文

Threshold image

Mouth part

Extracted teeth

我正在尝试仅从裁剪的口腔图像中提取牙齿部分,但阈值和遮罩方式遗漏了一些牙齿,如提取的牙齿图像所示

我使用python获取阈值图像,然后根据阈值图像查找轮廓并提取检测到的轮廓, 根据该守则:

labels = measure.label(threshold, connectivity=2, background=0)
mask = np.zeros(threshold.shape, dtype="uint8")
for label in np.unique(labels):
    if label == 0:
        continue
    labelMask = np.zeros(threshold.shape, dtype="uint8")
    labelMask[labels == label] = 255
    numPixels = cv2.countNonZero(labelMask)
    if numPixels > 600:
        mask = cv2.add(mask, labelMask)

cv2.imshow("mask", mask)


_, contours, _ = cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(equa, contours, -1, (0, 0, 255), 2)
cv2.imshow("thre",equa)
img_contours= cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)[-2]
img_contours = sorted(img_contours, key=cv2.contourArea)

for i in img_contours:

    if cv2.contourArea(i) > 1000:

        break

mask = np.zeros(mask.shape[:2], np.uint8)
cv2.drawContours(mask, [i],-1, 255, -1)
new_img = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow("Image with background removed", new_img)

那么,究竟有没有办法拔牙并获得所有牙齿,或者填补拔牙之间的空隙呢


Tags: 图像imgthresholdlabelsnpzerosmask阈值
2条回答

依我看,你这个问题的答案基本上是否定的

二值图像的信息含量较低,牙齿缺失与牙齿周围和牙齿之间的正常间距之间没有差异

由于没有牙齿形状的先验信息,任何低级视觉操作(过滤器)都无法提供帮助。通过映射具有牙齿布局的几何模型,您可能会得到一些改进,但这不会反映手头的特定解剖结构,并且很难实现

在二值化之前,您一定要解决这个问题

我建议使用不同的方法: 转换到HSV颜色空间并仅使用色调通道,然后执行一些阈值和变形以获得遮罩

img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(img_hsv)

在阈值化之前,可能需要模糊h通道

h_blur = cv2.GaussianBlur(h, (5, 5), 1)

对于h通道上的阈值设置,我建议您使用GUI进行一些交互式调整

ret, thh_blur = cv2.threshold(h_blur, 9, 255, cv2.THRESH_BINARY)

您可以使用thh_blur作为掩码,看看它是否对您有好处,或者使用一些e变形:

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
morphed_th = cv2.morphologyEx(thh_blur, cv2.MORPH_OPEN, kernel, iterations = 1)
morphed_th = cv2.morphologyEx(morphed_th, cv2.MORPH_CLOSE, kernel, iterations = 2)

最后使用morphed_th作为掩码:

res = img.copy()
res[morphed_th == 0] = 0
res

我得到了下面的图像

enter image description here

我不知道它是否对你有好处,因为它在较暗的角落漏掉了侧牙,但你可以从s通道中提取它们并添加到面具中

如果您想消除ET(较暗区域)之间的间隙,您可以遵循或多或少相同的逻辑,从res开始作为输入图像,播放通道、阈值等


添加左侧需要使用参数。

这是代码。对另一侧执行同样的操作

# blur the s channel
s_blur = cv2.GaussianBlur(s, (5, 5), 1)

# custom thresholding
val1 = 240
val2 = 170
ths_blur = s_blur.copy()
ths_blur[ths_blur > val1] = 0
ths_blur[ths_blur > val2] = 255
ths_blur[ths_blur <= val2] = 0

# add to the previous and slice the left part
mask = cv2.add(morphed_th, ths_blur)
left = np.s_[:,0:70]

# apply morphology to the left slice
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
morphed_mask_left = cv2.morphologyEx(mask[left], cv2.MORPH_CLOSE, kernel, iterations = 6)

# override the mask with the morphed left part
final_mask = morphed_th.copy()
final_mask[left] = morphed_mask_left

# use the mask
res_final = img.copy()
res_final[final_mask == 0] = (0, 0, 0)
res_final

这就是我得到的

enter image description here

为了更好地理解我为什么这样做,请绘制每个步骤。也许这可以让您找到更好的解决方案。

相关问题 更多 >