实用知识库
柔彩主题三 · 更轻盈的阅读体验

用OpenCV做电源指示灯状态识别:几种实用的图像检测方法

发布时间:2026-01-22 18:01:43 阅读:96 次

工厂产线上常有大量设备带LED电源指示灯,靠人眼巡检容易漏看。其实用普通USB摄像头+OpenCV就能自动判断灯是亮、灭还是闪烁——关键不在硬件多高级,而在怎么从图像里稳稳抓住那一点光。

亮度阈值法:最直接也最容易翻车

取ROI区域(比如指示灯所在的小方块),算平均灰度值。超过120就判为“亮”,低于30算“灭”。代码很短:

import cv2
img = cv2.imread('led.jpg', cv2.IMREAD_GRAYSCALE)
roi = img[120:140, 210:230] # 手动框出灯的位置
avg = roi.mean()
if avg > 120:
    print('电源正常')
elif avg < 30:
    print('断电')
else:
    print('异常(可能是弱光或反光)')

但车间灯光一变,阈值就得重调;金属外壳反光可能误判成“亮”;灯老化变暗后也会失效。

颜色+形态双校验:适合彩色摄像头

很多电源灯是红色或绿色,HSV空间比RGB更抗光照干扰。先转HSV,再设色相范围(红灯:0–10 和 160–180),接着用形态学闭运算连通微小亮斑,最后找最大连通区域的面积和圆度:

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask_red = cv2.inRange(hsv, (0, 100, 100), (10, 255, 255))
mask_red |= cv2.inRange(hsv, (160, 100, 100), (180, 255, 255))
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
mask_clean = cv2.morphologyEx(mask_red, cv2.MORPH_CLOSE, kernel)
contours, _ = cv2.findContours(mask_clean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if contours:
    largest = max(contours, key=cv2.contourArea)
    area = cv2.contourArea(largest)
    x,y,w,h = cv2.boundingRect(largest)
    if area > 15 and 0.7 < w/h < 1.3:
        print('红灯亮,电源接通')

这招对固定安装的设备很稳,哪怕背景杂乱,只要灯没被遮挡,基本不误报。

帧差+时序分析:专治闪烁灯

有些设备上电后电源灯会快闪3下再常亮,或者故障时慢闪。单帧图没法判断,得看连续几秒的变化。用帧差法提取每帧的“变化像素数”,再画出波动曲线:

如果1秒内出现3次明显峰值(间隔≈300ms),就记为“启动中”;若持续等间隔脉冲(如1Hz),就是“故障告警”。实际部署时,用环形缓冲区存最近60帧的差分统计值,比存全部图像省内存又响应快。

提醒一句:别迷信“全自动”。现场调试时,先拍一段真实工况视频(含开灯、关灯、人员走动、日光灯启停),拿这段视频跑通逻辑,比看10篇论文都管用。