如何利用Python OpenCV实现黑色背景上黑色胶带的检测
检测黑色背景上黑色胶带的可行方案
看了你的需求:黑背景上检测黑胶带,核心线索是无胶带时的实线在贴胶带后会明显变浅,这个特征其实很好利用,咱们可以围绕这个差异设计检测逻辑,下面给你几个实用的思路和优化代码:
推荐的图像处理思路
1. 灰度基准对比法(最直接适配你的场景)
既然无胶带时的线条和背景有固定的灰度差,贴胶带后这个差异消失,咱们可以:
- 先保存一张无胶带状态下的ROI灰度图作为基准模板
- 每次检测时,计算当前ROI和模板的灰度差值,或者直接对比两者的平均灰度
- 因为胶带覆盖后线条变浅,当前ROI的平均灰度会比基准模板高很多,设定一个合理阈值就能判断胶带是否存在
2. 边缘检测+轮廓统计
无胶带时的实线边缘清晰,贴胶带后线条被黑胶带覆盖,边缘几乎消失:
- 对ROI做Canny边缘检测,无胶带时能得到清晰的线条轮廓
- 统计检测到的边缘总长度或者轮廓面积,当数值低于某个阈值时,就说明胶带存在
3. 替换自适应阈值(优化你当前的阈值处理)
你现在用的固定阈值cv2.threshold容易受光照波动影响,换成自适应阈值能更好适配局部明暗变化:
# 自适应阈值处理,针对局部区域计算阈值 thresh = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
这种方式能更精准地捕捉线条的明暗变化,减少误判。
优化后的代码示例(基于灰度基准对比)
我给你写了一个可直接测试的版本,结合你的现有代码做了修改:
import cv2 import os import imutils from pathlib import Path import numpy as np def on_mouse(event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: print("X: {} | Y: {}".format(x, y)) # 第一步:提前准备无胶带的基准模板(把无胶带时的ROI灰度图保存好) dirPath = Path(__file__).parents[2] template_path = os.path.join(dirPath, "img", "template_no_tape.png") # 确保模板尺寸和你的ROI一致:591-520=71,337-298=39 template_gray = cv2.imread(template_path, cv2.IMREAD_GRAYSCALE) template_gray = imutils.resize(template_gray, width=71, height=39) imgPath = os.path.join(dirPath, "img", "img.png") win_name = "Image" cv2.namedWindow(win_name) cv2.setMouseCallback(win_name, on_mouse) img = cv2.imread(imgPath) img = imutils.resize(img, width=800) roiImg = img[298:337, 520:591] img_gray = cv2.cvtColor(roiImg, cv2.COLOR_BGR2GRAY) # 计算当前ROI和模板的灰度差异 diff_map = cv2.absdiff(img_gray, template_gray) mean_diff = np.mean(diff_map) mean_current_gray = np.mean(img_gray) mean_template_gray = np.mean(template_gray) # 核心判断逻辑:胶带覆盖后线条变浅,当前ROI平均灰度会显著高于模板 # 阈值10可以根据你的实际图像调整,比如测试几张有/无胶带的图找合适值 tape_exists = mean_current_gray > mean_template_gray + 10 print(f"检测结果:{'存在黑色胶带' if tape_exists else '无黑色胶带'}") # 可视化辅助调试 cv2.imshow(win_name, img) cv2.imshow("ROI 灰度图", img_gray) cv2.imshow("灰度差异图", diff_map) cv2.waitKey(0) cv2.destroyAllWindows()
额外小建议
- 如果你是做视频流检测,可以多采集几张无胶带的图像,计算平均模板,减少单张模板的偶然误差
- 对连续帧的检测结果做简单滤波(比如连续3帧都检测到胶带才判定存在),能提升检测的稳定性
- 也可以试试直方图对比:计算当前ROI和模板的直方图相似度,相似度低于阈值时判定有胶带
内容的提问来源于stack exchange,提问作者S Andrew
相关产品推荐
相关产品推荐

