簡體   English   中英

分水嶺分割后圍繞單元格繪制圓圈 - openCV/Python

[英]Drawing circles around cells after watershed segmentation - openCV/Python

我遵循了一個關於分水嶺分割的教程,並用它來分割圖像中的每個紅細胞。 我是 openCV 的新手,我想知道是否可以通過使用分水嶺分割在單元格周圍繪制圓圈? 如果是這樣,請您展示它是如何完成的。

原始圖像

原始圖像

Output 的分水嶺分割

流域產出

代碼如下

import numpy as np
import cv2
from matplotlib import pyplot as plt


def fillHoles(otsuImg):
    # find contours
    contours, _ = cv2.findContours(otsuImg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    # filter out contours by size
    small_cntrs = []
    for con in contours:
        area = cv2.contourArea(con)
        # print(area)
        if area < 1000: # size threshold
            small_cntrs.append(con)
    cv2.drawContours(otsuImg, small_cntrs, -1, 0, -1)

# load the image
img = cv2.imread('resources/rbc2.png')
img_pyr = cv2.pyrMeanShiftFiltering(img, 21, 51)
img_median = cv2.medianBlur(img_pyr, 9)
img_gray = cv2.cvtColor(img_median, cv2.COLOR_BGR2GRAY)
ret, img_thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# fill holes of RBC
fillHoles(img_thresh)

# invert the image
img_thresh = cv2.bitwise_not(img_thresh)

# noise removal
kernel = np.ones((3,3),np.uint8)
opening = cv2.morphologyEx(img_thresh,cv2.MORPH_OPEN,kernel, iterations=2)

# sure background area
sure_bg = cv2.dilate(opening,kernel,iterations=3)

# Finding sure foreground area
dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform,0.1*dist_transform.max(),255,0)
# _, sure_fg = cv2.threshold(np.uint8(dist_transform), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# Finding unknown region
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)

# Marker labelling
ret, markers = cv2.connectedComponents(sure_fg)

# Add one to all labels so that sure background is not 0, but 1
markers = markers+1

# Now, mark the region of unknown with zero
markers[unknown==255] = 0

markers = cv2.watershed(img,markers)
img[markers == -1] = [255,0,0]


cv2.imshow('markers2', np.uint8(markers))
cv2.imshow('Final output', img)
cv2.waitKey(0)

我遇到了同樣的問題,最終在最后一步使用skimage.segmentation.watershed來獲取我可以用來計算分水嶺單元格輪廓的標簽。 一旦你有了輪廓,你可以像往常一樣計算和 plot 封閉圓:

# your code above
ret, markers = cv2.connectedComponents(sure_fg)
from skimage.segmentation import watershed
labels = watershed(-dist_transform,
                          markers,
                          mask=img_thresh,
                          watershed_line=False)
watershed_contours =  list(map(lambda l: cv2.findContours((cv_labels == l).astype(np.uint8),
                            cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0][0],
                            np.unique(labels)[1:]))
output = img.copy()
for contour in watershed_contours:
    (x,y),radius = cv.minEnclosingCircle(watershed_contours)
    center = (int(x),int(y))
    radius = int(radius)
    cv2.circle(output,center,radius,(0,255,0),2)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM