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

OpenCV中基于距离变换图的Watershed算法报错求助

问题原因与修复方案

错误提示src.type() == CV_8UC3 && dst.type() == CV_32SC1明确指出两个核心问题:

  • 输入的3通道图像必须是uint8类型(8位无符号整数)
  • 标记图markers必须是int32类型(32位有符号整数)

你的代码里,距离变换生成的dist是浮点型图像,转3通道后依然是浮点类型,不满足第一个要求;另外标记图的布尔值判断也存在潜在问题。


修复步骤

1. 修正距离变换图像的类型

距离变换输出的是01范围的浮点图,需要先缩放至0255并转换为uint8,再转3通道:

filled_img = filled_img.astype(np.uint8)
dist = cv2.distanceTransform(filled_img, cv2.DIST_L2, 0)
# 缩放并转换为uint8类型
dist = (dist / dist.max() * 255).astype(np.uint8)
dist3d = cv2.cvtColor(dist, cv2.COLOR_GRAY2BGR)

2. 确保标记图类型与赋值正确

cv2.connectedComponents返回的标记图默认是int32,但建议显式确认;同时修正未知区域的赋值逻辑:

ret, markers = cv2.connectedComponents(sure_fg)
markers = markers + 1
# 用像素值判断而非布尔值,避免潜在类型问题
markers[unknown == 255] = 0
# 显式转为int32,确保符合要求
markers = markers.astype(np.int32)

3. 修正分割线绘制代码

原代码是比较操作而非赋值,同时需要复制图像避免修改原图:

watershed_img = crop_img.copy()
# 替换为赋值操作
watershed_img[watershed_markers == -1] = [255, 0, 0]

完整修复后的核心代码

# 处理距离变换图像
filled_img = filled_img.astype(np.uint8)
dist = cv2.distanceTransform(filled_img, cv2.DIST_L2, 0)
dist = (dist / dist.max() * 255).astype(np.uint8)
dist3d = cv2.cvtColor(dist, cv2.COLOR_GRAY2BGR)

# 生成并修正标记图
ret, markers = cv2.connectedComponents(sure_fg)
markers = markers + 1
markers[unknown == 255] = 0
markers = markers.astype(np.int32)

# 执行分水岭分割
watershed_markers = cv2.watershed(dist3d, markers)

# 绘制分割结果
watershed_img = crop_img.copy()
watershed_img[watershed_markers == -1] = [255, 0, 0]

plt.figure(figsize=(20,20))
plt.imshow(watershed_img, 'jet')
plt.show()

补充说明

你之前在原始彩色图上能成功执行分水岭,是因为原图本身就是uint8类型的3通道图像,天然满足OpenCV的输入要求;而距离变换后的图像你保留了浮点类型,才触发了类型不匹配的断言错误。

内容的提问来源于stack exchange,提问作者dvdrplus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:45:34