我正在尝试使用分水岭算法从原始图像中分割白细胞。我想在分割过程之后将ROI或boundingbox保存为新图像,但我不知道如何在python中做
这是我的主要代码
import numpy as np
import cv2
from matplotlib import pyplot as plt
import matplotlib.image as mpimg
from skimage.morphology import extrema
from skimage.morphology import watershed as skwater
def ShowImage(title,img,ctype):
if ctype=='bgr':
b,g,r = cv2.split(img) # get b,g,r
rgb_img = cv2.merge([r,g,b]) # switch it to rgb
plt.imshow(rgb_img)
elif ctype=='hsv':
rgb = cv2.cvtColor(img,cv2.COLOR_HSV2RGB)
plt.imshow(rgb)
elif ctype=='gray':
plt.imshow(img,cmap='gray')
elif ctype=='rgb':
plt.imshow(img)
else:
raise Exception("Unknown colour type")
plt.title(title)
plt.show()
img=cv2.imread('29-39.jpg')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ShowImage('Color Threshold',img,'bgr')
cell_hsvmin = (120,100,100) #Lower end of the HSV range defining the nuclei
cell_hsvmax = (155,255,255) #Upper end of the HSV range defining the nuclei
#Transform image to HSV color space
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
#Threshold based on HSV values
color_thresh = cv2.inRange(hsv, cell_hsvmin, cell_hsvmax)
#ShowImage('Color Threshold',color_thresh,'gray')
'''
masked = cv2.bitwise_and(img,img, mask=color_thresh)
ShowImage('Color Threshold Maksed',masked,'bgr')'''
kernel = np.ones((8,8),np.uint8)
opening = cv2.morphologyEx(color_thresh,cv2.MORPH_OPEN, kernel, iterations = 2)
#ShowImage('Opening',opening,'gray')
'''
fraction_foreground = 0.6
dist = cv2.distanceTransform(opening,cv2.DIST_L2,5)
ret, sure_fg = cv2.threshold(dist,fraction_foreground*dist.max(),255,0)
ShowImage('Distance',dist_transform,'gray')
ShowImage('Surely Foreground',sure_fg,'gray')'''
#Identify areas which are surely foreground
h_fraction = 0.1
dist = cv2.distanceTransform(opening,cv2.DIST_L2,5)
maxima = extrema.h_maxima(dist, h_fraction*dist.max())
print("Peaks found: {0}".format(np.sum(maxima)))
#Dilate the maxima so we can see them
maxima = cv2.dilate(maxima, kernel, iterations=2)
ShowImage('Distance',dist,'gray')
ShowImage('Surely Foreground',maxima,'gray')
# Finding unknown region
unknown = cv2.subtract(opening,maxima)
#ShowImage('Unknown',unknown,'gray')
# Marker labelling
ret, markers = cv2.connectedComponents(maxima)
ShowImage('Connected Components',markers,'rgb')
# 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==np.max(unknown)] = 0
ShowImage('markers',markers,'rgb')
dist = cv2.distanceTransform(opening,cv2.DIST_L2,5)
labels = skwater(-dist,markers,watershed_line=True)
ShowImage('Watershed',labels,'rgb')
"""imgout = img.copy()
imgout[markers == 0] = [0,0,255] #Label the watershed_line
ShowImage('img',imgout,'bgr')
"""
print("[INFO] {} unique segments found".format(len(np.unique(labels)) - 1))
def grab_contours(cnts):
# if the length the contours tuple returned by cv2.findContours
# is '2' then we are using either OpenCV v2.4, v4-beta, or
# v4-official
if len(cnts) == 2:
cnts = cnts[0]
# if the length of the contours tuple is '3' then we are using
# either OpenCV v3, v4-pre, or v4-alpha
elif len(cnts) == 3:
cnts = cnts[1]
# otherwise OpenCV has changed their cv2.findContours return
# signature yet again and I have no idea WTH is going on
else:
raise Exception(("Contours tuple must have length 2 or 3, "
"otherwise OpenCV changed their cv2.findContours return "
"signature yet again. Refer to OpenCV's documentation "
"in that case"))
# return the actual contours array
return cnts
for label in np.unique(labels):
# if the label is zero, we are examining the 'background'
# so simply ignore it
if label == 0:
continue
# otherwise, allocate memory for the label region and draw
# it on the mask
mask = np.zeros(gray.shape, dtype="uint8")
mask[labels == label] = 255
# detect contours in the mask and grab the largest one
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = grab_contours(cnts)
c = max(cnts, key=cv2.contourArea)
# draw a circle enclosing the object
((x, y), r) = cv2.minEnclosingCircle(c)
cv2.circle(img, (int(x), int(y)), int(r), (0, 255, 0), 2)
cv2.putText(img, "#{}".format(label), (int(x) - 10, int(y)),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
source和结果图像like this。我需要将每个标签(#1,#2,#3等)分开作为新图像
如何解决这些问题?非常感谢您的帮助。