def img_huizhi_lunkuo_tongji():
"""
识别小物体数量
:return:
"""
def watershed_algorithm(image):
src = image.copy()
blur = cv2.pyrMeanShiftFiltering(image, sp=21, sr=55) # 边缘保留滤波 去噪
cv2.imshow("灰度", blur)
gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)# 转成灰度图像
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 得到二值图像区间阈值
cv2.imshow('二值图像thres', binary)
# 距离变换
dist = cv2.distanceTransform(binary, cv2.DIST_L2, 3) #反映像素与背景(值为 0的像素点)的距离关系
#uint8类型的图片归一化处理
dist_out = cv2.normalize(dist, 0, 1.0, cv2.NORM_MINMAX)
cv2.imshow('距离转换distance-Transform', dist_out * 100)
#再次进行阈值转换
ret, surface = cv2.threshold(dist_out, 0.5 * dist_out.max(), 255, cv2.THRESH_BINARY)
cv2.imshow('前景图', surface)
sure_fg = np.uint8(surface) # 转成8位整型
cv2.imshow('背景图Sure foreground', sure_fg)
# image = np.hstack((gray, sure_fg))#水平合并显示
# cv2.imshow('hstack', image)
# Marker labelling
ret, markers = cv2.connectedComponents(sure_fg) # 连通区域
print(ret)
markers = markers + 1 # 整个图+1 确保背景是1不是0
# 未知区域标记(不能确定是前景还是背景)
kernel = np.ones((3, 3), np.uint8)#内核
#类形态学的变化
op=cv2.MORPH_DILATE # op = cv2.MORPH_OPEN
binary = cv2.morphologyEx(binary, op, kernel, iterations=1)#腐蚀一次
# cv2.MORPH_OPEN 开运算--先腐蚀--膨胀,分开
# cv2.MORPH_CLOSE 闭运算--膨胀-腐蚀--合并
# MORPH_GRADIENT - 形态学梯度(Morphological gradient)就是膨胀图与俯视图之差,用于保留物体的边缘轮廓
# MORPH_TOPHAT - 顶帽(Top hat) 原图像与开运算图之差,用于分离比邻近点亮一些的斑块。
# MORPH_BLACKHAT - 黑帽(Black hat) 闭运算与原图像之差,用于分离比邻近点暗一些的斑块。
# MORPH_ERODE 腐蚀,去毛刺
# MORPH_DILATE 膨胀,去小孔
# 形状:表核的形状,矩形MORPH_RECT; 交叉形MORPH_CROSS; 椭圆形MORPH_ELLIPSE;
unknown = binary - sure_fg # #腐蚀-背景
cv2.imshow('unknown', unknown)
markers[unknown == 255] = 0 #未标记区域
markers_show = np.uint8(markers)## 区域标记结果转换
cv2.imshow('markers', markers_show * 100)
# 分水岭算法分割
markers = cv2.watershed(image, markers=markers) # 标签图像将会被修改,边界区域的标记将变为 -1
# src[markers == -1] = [0, 0, 255] # 红色# 获得到的边界值为-1
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(markers)
markers_8u = np.uint8(markers)
# print(max_val)
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0),
(255, 0, 255), (0, 255, 255), (255, 128, 0), (255, 0, 128),
(128, 255, 0), (128, 0, 255), (255, 128, 128), (128, 255, 255)]
for i in range(2, int(max_val + 1)):
ret, thres1 = cv2.threshold(markers_8u, i - 1, 255, cv2.THRESH_BINARY)
ret2, thres2 = cv2.threshold(markers_8u, i, 255, cv2.THRESH_BINARY)
mask = thres1 - thres2
cv2.imshow('mask', mask)
# color = (rd.randint(0,255), rd.randint(0,255), rd.randint(0,255))
# image[markers == i] = [rd.randint(0,255), rd.randint(0,255), rd.randint(0,255)]
# image[markers == i] = [colors[i-2]]
contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cv2.drawContours(image, contours, -1, colors[(i - 2) % 12], -1)
# cv2.drawContours(src,contours,-1,colors[(i-2)%12],-1)
M = cv2.moments(contours[0])
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00']) # 轮廓重心
cv2.drawMarker(image, (cx, cy), (0, 0, 255), 1, 10, 2)
cv2.drawMarker(src, (cx, cy), (0, 0, 255), 1, 10, 2)
cv2.putText(src, "count=%d" % (int(max_val - 1)), (220, 30), 0, 1, (0, 255, 0), 2)
cv2.putText(image, "count=%d" % (int(max_val - 1)), (220, 30), 0, 1, (0, 255, 0), 2)
cv2.imshow('regions', image)
result = cv2.addWeighted(src, 0.6, image, 0.5, 0) # 图像权重叠加
cv2.imshow('result', result)
src = cv2.imread('./douzi.bmp')
# src = cv2.imread('./99.bmp')
cv2.imshow('src', src)
watershed_algorithm(src)
cv2.waitKey(0)
cv2.destroyAllWindows()
python_分水岭算法
最新推荐文章于 2022-12-03 23:34:51 发布