Обнаружение контуров OpenCV - PullRequest
0 голосов
/ 30 ноября 2018

Я пытался определить контуры с помощью OpenCV.Я пытаюсь обнаружить ядро ​​белых кровяных клеток.Я проверил это на других моих изображениях, и оказалось, что все в порядке, за исключением изображений, где ядра находятся слишком далеко друг от друга.Это результат программы, которую я сделал: result image

В нижней части ядро ​​не было обнаружено как одно, но они обнаруживаются как два, потому что они не соединены или не прилипаютвсе вместе.Как сделать так, чтобы программа распознала его только как одну ячейку?

Вот мой код:

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

Вот исходное изображение: original image

1 Ответ

0 голосов
/ 30 ноября 2018

Одним простым способом может быть объединение близко обнаруженных областей.Существует концепция, называемая пересечением над объединением в локализации изображения, в которой два ограничивающих прямоугольника объединяются, если их показатель 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 , я думаю, что он должен работать нормально, поскольку ядро ​​- это одна сущность в конце концов (полностью подключенная),Попробуйте это перед набором номера, что, вероятно, является причиной того, что ваши контуры разбиваются на две части.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...