简体   繁体   English

OpenCV轮廓检测

[英]OpenCV contour detection

I have been trying to detect contours using OpenCV. 我一直在尝试使用OpenCV检测轮廓。 I am trying to detect the nucleus of white blood cells. 我正在尝试检测白细胞的核。 I tested it on other images of mine and it turned out to be okay except for images where the nuclei are too far away from each other. 我在我的其他图像上进行了测试,结果发现除了原子核彼此之间距离太远以外,其他图像都还不错。 This is the result from the program I made: 这是我制作的程序的结果: 结果图片

At the bottom part, the nucleus was not detected as one but they are detected as two because they are not conjoined or sticking together. 在底部,未将原子核检测为一个,但将其检测为两个,因为它们没有连接或粘在一起。 How can I make the program to detect it as only one cell? 如何制作程序以将其检测为仅一个单元格?

Here is my code: 这是我的代码:

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()

Here is the Original Image: 这是原始图像: 原始图像

One simple way can be to merge closely detected regions. 一种简单的方法可以是合并紧密检测的区域。 There is a concept called Intersection over Union in Image Localization, in which two bounding boxes are merged if their IoU score is greater than a certain threshold. 在图像本地化中有一个称为联合的交集的概念,其中两个边界框如果它们的IoU分数大于某个阈值,则将其合并。 A psuedo cade will be like 一个伪造的课程就像

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

Another approach you can try is the Flood Fill Algorithm , I think it should work fine as the nucleus is one entity after all (fully connected). 您可以尝试的另一种方法是Flood Fill Algorithm ,我认为它应该可以正常工作,因为原子核毕竟是一个实体(完全连接)。 Try this before dialation which probably is the reason your contours are breaking into two. 在拨号前尝试一下,这可能是轮廓分成两部分的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM