You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 18:18:03