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

CV2 Find Contours误检测地面而非目标:地板黑胶带检测的阈值调节难题

解决黑色胶带检测的阈值困境

我太懂这种两难了——全局阈值就像一把一刀切的刀,要么把地面误当成胶带,要么把胶带本身给切没了。咱们换几个思路来搞定这个问题:

1. 先试试自适应阈值,告别全局一刀切

全局阈值的问题在于它对整个图像用同一个标准,而地面和胶带的局部灰度差异可能没那么大。自适应阈值会根据每个像素周围的区域计算专属阈值,能更好地应对这种情况:

from cv2 import cv2 
import numpy as np 

img = cv2.imread('tape4.jpeg', cv2.IMREAD_UNCHANGED) 
img_grey = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 

# 替换全局阈值为自适应阈值
thresh_img = cv2.adaptiveThreshold(
    img_grey, 
    255, 
    cv2.ADAPTIVE_THRESH_GAUSSIAN_C,  # 用高斯加权的邻域计算阈值
    cv2.THRESH_BINARY_INV,  # 反转阈值,让黑色胶带变成白色(方便后续找轮廓)
    11,  # 邻域大小(必须是奇数,可根据图像尺寸微调)
    2    # 阈值微调值,控制阈值的偏移量
)

# 后续轮廓检测流程
contours, hierarchy = cv2.findContours(thresh_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
img_contours = np.zeros(img.shape, dtype=np.uint8)  # 指定dtype避免保存图像异常
cv2.drawContours(img_contours, contours, -1, (0,255,0), 3) 
cv2.imwrite('contours_adaptive.png',img_contours)

2. 用HSV颜色空间直接锁定黑色,比灰度更精准

黑色在HSV颜色空间里有非常明确的范围,咱们直接基于颜色提取胶带,避开灰度值重叠的问题:

from cv2 import cv2 
import numpy as np 

img = cv2.imread('tape4.jpeg', cv2.IMREAD_UNCHANGED) 
# 转换到HSV颜色空间
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 定义黑色的HSV范围(可根据实际图像微调V的上限)
lower_black = np.array([0, 0, 0])
upper_black = np.array([180, 255, 50])

# 生成黑色区域的掩码
mask = cv2.inRange(hsv, lower_black, upper_black)
# 形态学闭操作,去掉小噪点并填补胶带的微小缝隙
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((5,5), np.uint8))

# 找轮廓并绘制
contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
img_contours = np.zeros(img.shape, dtype=np.uint8)
cv2.drawContours(img_contours, contours, -1, (0,255,0), 3) 
cv2.imwrite('contours_hsv.png',img_contours)

3. 最后再加一层轮廓过滤,干掉误检的小轮廓

哪怕前面的步骤还有一些地面的误检轮廓,咱们可以通过轮廓的面积、宽高比来筛选出真正的胶带:

# 在找到contours之后,添加过滤逻辑
filtered_contours = []
for cnt in contours:
    area = cv2.contourArea(cnt)
    # 过滤掉面积太小的轮廓(数值根据你的图像尺寸调整)
    if area > 500:
        # 新增宽高比判断:胶带是长条状,宽高比要么远大于1要么远小于1
        x, y, w, h = cv2.boundingRect(cnt)
        aspect_ratio = float(w)/h
        if aspect_ratio > 3 or aspect_ratio < 0.3:
            filtered_contours.append(cnt)

# 只绘制过滤后的有效轮廓
cv2.drawContours(img_contours, filtered_contours, -1, (0,255,0), 3) 

你可以先从HSV颜色空间的方法开始试,这通常是检测特定颜色物体最靠谱的路子,再配合形态学操作和轮廓过滤,基本就能解决你的阈值困境啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 03:27:43