基于OpenCV分水岭算法的图像分割液体占比计算及报错解决
报错根因
cv2.watershed函数对输入参数有严格类型要求:第二个参数(标记数组)必须为单通道32位有符号整型(CV_32SC1),你当前代码里的markers继承自二值化结果thresh,属于8位无符号整型,类型不匹配,因此触发断言报错。
适配场景的优化实现
你的需求场景颜色区分度高,在原有逻辑基础上调整类型问题、补充占比计算即可实现需求,修改后完整代码如下:
import cv2 import numpy as np # 读取图像 img = cv2.imread('image001.jpg') hh, ww = img.shape[:2] hh2, ww2 = hh // 2, ww // 2 radius = hh2 # 生成容器掩码,排除背景干扰 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) mask = np.zeros_like(gray) mask = cv2.circle(mask, (ww2, hh2), radius, 255, -1) masked_gray = cv2.bitwise_and(gray, mask) # 二值化预处理 ret, thresh = cv2.threshold(masked_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) # 生成符合watershed要求的32位整型标记数组 markers = np.zeros_like(gray, dtype=np.int32) # 手动设置标记:1=上层液体,2=下层液体,3=容器外背景 markers = cv2.circle(markers, (ww2, 50), 5, 1, -1) markers = cv2.circle(markers, (ww2, hh2+50), 5, 2, -1) markers = cv2.circle(markers, (15, 15), 5, 3, -1) # 执行分水岭算法 markers = cv2.watershed(img, markers) # 标记边界为红色 img[markers == -1] = [0, 0, 255] # 计算两种液体占比 # 统计容器内总有效像素(排除背景标记3) total_pixels = np.sum(mask == 255) # 统计上层液体像素(标记1) upper_pixels = np.sum(markers == 1) # 统计下层液体像素(标记2) lower_pixels = np.sum(markers == 2) upper_ratio = upper_pixels / total_pixels lower_ratio = lower_pixels / total_pixels print(f"上层液体占比:{upper_ratio:.2%}") print(f"下层液体占比:{lower_ratio:.2%}") # 结果展示 cv2.imshow("分割结果", img) cv2.waitKey(0) cv2.destroyAllWindows()
补充说明
如果你的图像批次亮度差异较大,也可以替换手动标记逻辑为自动阈值生成前景/背景标记,进一步提升泛用性。
内容的提问来源于stack exchange,提问作者CodeViper
相关产品推荐
相关产品推荐

