在现有代码基础上改,要求自建点位用分水岭检测将左边这根骨头提取出来
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread("hand.png")
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh=cv2.threshold(gray,150,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
opening=cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,iterations=2)
sure_bg=cv2.dilate(opening,kernel,iterations=2)
sure_fg=cv2.erode(opening,kernel,iterations=3)
unknown=cv2.subtract(sure_bg,sure_fg)
#距离变换
dist_transform=cv2.distanceTransform(opening,cv2.DIST_L2,5)
#归一化图像
cv2.normalize(dist_transform,dist_transform,0,1.0,cv2.NORM_MINMAX)
ret,sure_fg=cv2.threshold(dist_transform,0.1*dist_transform.max(),255,0)
sure_fg=np.uint8(sure_fg)
unknown=cv2.subtract(sure_bg,sure_fg)
#标记marker
ret,markers=cv2.connectedComponents(sure_fg)
#如果是背景区域,marker加1
markers=markers+1
#如果是不确定点,marker为0
markers[unknown==255]=0
markers_copy=markers.copy()
markers_copy[markers==0]=150
markers_copy[markers==1]=0
markers_copy[markers>1]=255
markers_copy=np.uint8(markers_copy)
#使用分水岭算法执行基于标记的图像分割,将图像中的对象与背景分离
markers=cv2.watershed(img,markers)
img[markers==-1]=[200,207,27]
img=cv2.cvtColor(img,cv2.COLOR_RGB2BGR)
plt.figure(1)
plt.imshow(markers,cmap='gray')
plt.figure(2)
plt.imshow(img,cmap='gray')
plt.show()
1 例程是 基于距离变换的分水岭算法 的典型例程,应该可以把所有骨骼都找出来吧,如果找不出来可以调一下参数。
2 在此基础上要找出左边的骨骼,其实不是找了,而是标记出来。有几个方法可以考虑:
(1)鼠标交互标记的分水岭算法;估计这是出题的原意。
(2)直接 ROI 获取目标区域,然后用例程,相当于先把其它骨骼排除了。
(3)在分水岭的结果中用 ROI 获取结果,相当于从多个识别目标中选中所要的。