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

如何利用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 18:12:26