【问题标题】:OpenCV contour detectionOpenCV 轮廓检测
【发布时间】:2018-11-30 08:26:36
【问题描述】:

我一直在尝试使用 OpenCV 检测轮廓。我正在尝试检测白细胞的细胞核。我在我的其他图像上对其进行了测试,结果证明没问题,除了原子核彼此相距太远的图像。这是我制作的程序的结果:

在底部,核没有被检测为一个,但它们被检测为两个,因为它们没有连接或粘在一起。如何让程序将其检测为仅一个单元格?

这是我的代码:

import cv2
import numpy as np

limit_area = 1000   
x = 0   
y = 0   
w = 0   
h = 0   
nuclei = []   
count = 0   
number_name = 1   

img1 = cv2.imread('7.bmp')
img = cv2.add(img1, 0.70)
img_3 = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask1 = cv2.inRange(img_3, (90,140,0), (255,255,255))   
mask2 = cv2.inRange(img_3, (90,90,0), (255,255,255))   
mask1 = cv2.equalizeHist(mask1)
mask2 = cv2.equalizeHist(mask2)
mask = mask1 + mask2   
kernel = np.ones((1,4),np.uint8)   
mask = cv2.dilate(mask,kernel,iterations = 1)   
kernel_close = np.ones((3,3),np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel_close)   
blur2 = cv2.medianBlur(mask,7)   
canny = cv2.Canny(blur2, 100,200)   
im2, contours, hierarchy = cv2.findContours(canny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)   

for cnt in contours:   
    if cv2.contourArea(cnt) >= limit_area:   
        nuclei.append(cnt)   
        print(cv2.contourArea(cnt))
        x, y, w, h = cv2.boundingRect(cnt)   
        roi = blur2[y:y+h, x:x+w]
        outfile = '%d.jpg' % number_name
        image_roi = cv2.resize(roi, (128,128), interpolation=cv2.INTER_AREA)
        image_roi = cv2.medianBlur(image_roi, 5)
        (T, thresh) = cv2.threshold(image_roi, 10, 255, cv2.THRESH_BINARY)
        _, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        contours = [i for i in contours if cv2.contourArea(i) <= 5000]
        cv2.fillPoly(thresh, contours, color=(0,0,0))
        image_roi = thresh
        cv2.imshow(outfile, image_roi)
        cv2.rectangle(img, (x, y), (x+w, y+h), (0,255,0), 7)  
        number_name += 1   

    count += 1   

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

这是原始图像:

【问题讨论】:

  • 请上传测试图像和代码的最低工作示例。
  • 在您的二进制掩码上尝试cv2.erode()cv2.dilate(),并使用足够的内核大小来合并两个轮廓。
  • 添加代码和原图
  • @ZdaR 我试过那个,但我测试的其他图像在分割核时产生了更差的结果
  • 尝试检测粉色区域,而不是紫色区域。另外,我不明白你为什么在那里使用直方图均衡,这是在处理来自显微镜的图像时要避免的功能,因为它会混淆强度的含义,而强度的含义在显微镜图像中是明确定义的。

标签: python opencv image-processing


【解决方案1】:

一种简单的方法是合并紧密检测到的区域。 Image Localization 中有一个叫做 Intersection over Union 的概念,如果两个边界框的 IoU 分数大于某个阈值,则将它们合并。一个psuedo cade就像

xi1 = max(box1[0], box2[0])
yi1 = max(box1[1], box2[1])
xi2 = min(box1[2], box2[2])
yi2 = min(box1[3], box2[3])
inter_area = max((xi2 - xi1), 0) * max((yi2 - yi1), 0)
box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1])
box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1])
union_area = box1_area + box2_area - inter_area
iou = inter_area/union_area

您可以尝试的另一种方法是Flood Fill Algorithm,我认为它应该可以正常工作,因为核心毕竟是一个实体(完全连接)。在拨号之前试试这个,这可能是你的轮廓分成两部分的原因。

【讨论】:

    猜你喜欢
    • 2014-07-27
    • 1970-01-01
    • 2016-10-24
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多