产品咨询:19113907060
联系我们
产品咨询
资讯内容banner 咨询banner-移动

基于OpenCV的简单抽烟识别框架核心技术思路与关键代码实现示例

作者:万物纵横
发布时间:2025-09-16 10:33
阅读量:

使用 OpenCV 进行抽烟识别是一个典型的计算机视觉应用,通常需要结合目标检测、特征分析和行为判断等步骤。以下是实现这一任务的基本方法和思路:


一、核心技术思路


抽烟识别的关键在于检测两个核心目标:手部 / 手臂动作和烟雾特征,并结合两者的时空关系判断是否为抽烟行为。主要步骤如下:


视频帧捕获与预处理


从摄像头或视频文件中读取帧序列


预处理:灰度化、去噪(高斯模糊)、增强对比度等,提高后续检测准确性


人体 / 手部检测


定位画面中的人体(尤其是上半身)和手部区域,可使用:


传统方法:Haar 级联分类器(适合简单场景);


深度学习方法:YOLO、SSD 等目标检测模型(推荐,精度更高)。


烟雾特征分析


烟雾的视觉特征:颜色(多为灰白色)、动态扩散性、半透明性、边缘模糊等。


分析方法:


颜色空间分析:在 HSV 空间中提取特定颜色范围(烟雾通常在低饱和度区域);


动态变化检测:通过帧差法或光流法检测手部区域附近的动态模糊区域;


形态学操作:通过膨胀 / 腐蚀去除噪声,提取烟雾轮廓。


行为判断


当检测到手部靠近口部且附近存在符合烟雾特征的区域,且该状态持续一定时间(排除误判),则判定为抽烟行为。


基于OpenCV的简单抽烟识别框架核心技术思路与关键代码实现示例(图1)


二、关键代码实现示例


以下是一个基于 OpenCV 的简单抽烟识别框架(需结合实际模型优化):


import cv2

import numpy as np

# 1. 视频捕获

cap = cv2.VideoCapture(0)  # 0表示默认摄像头

# 2. 预处理函数

def preprocess_frame(frame):

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 灰度化

blur = cv2.GaussianBlur(gray, (5, 5), 0)  # 高斯去噪

return blur

# 3. 手部检测(示例使用Haar分类器,实际建议用YOLO)

hand_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_hand.xml')  # 需要手部数据集训练

# 4. 烟雾检测函数(基于颜色和动态特征)

def detect_smoke(frame, hand_roi):

# 提取手部区域附近的ROI(感兴趣区域)

x, y, w, h = hand_roi

roi = frame[y:y+h+50, x:x+w]  # 扩大区域检测烟雾

# 转换到HSV空间,提取低饱和度区域(烟雾特征)

hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)

lower_smoke = np.array([0, 0, 50])  # 调整阈值适应场景

upper_smoke = np.array([180, 50, 200])

smoke_mask = cv2.inRange(hsv, lower_smoke, upper_smoke)

# 计算烟雾区域面积

smoke_area = np.sum(smoke_mask) / 255  # 白色像素占比

return smoke_area > 50  # 设定阈值判断是否存在烟雾

# 5. 主循环

smoke_counter = 0  # 连续检测计数器

while cap.isOpened():

ret, frame = cap.read()

if not ret:

break

# 预处理

processed = preprocess_frame(frame)

# 检测手部

hands = hand_cascade.detectMultiScale(processed, 1.1, 5)

# 遍历手部区域,检测烟雾

smoking_detected = False

for (x, y, w, h) in hands:

# 绘制手部框

cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

# 检测烟雾

if detect_smoke(frame, (x, y, w, h)):

cv2.putText(frame, "Smoke detected", (x, y-10),

cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

smoke_counter += 1

smoking_detected = True

else:

smoke_counter = max(0, smoke_counter - 1)  # 计数器衰减

# 持续检测到烟雾超过阈值,判定为抽烟

if smoke_counter > 10:  # 连续10帧检测到

cv2.putText(frame, "Smoking Behavior!", (50, 50),

cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)

# 显示结果

cv2.imshow('Smoking Detection', frame)

if cv2.waitKey(1) & 0xFF == ord('q'):

break

cap.release()

cv2.destroyAllWindows()


三、优化方向


使用深度学习提升检测精度


用 YOLOv5/YOLOv8 训练专门的烟雾和手部检测模型(需标注抽烟场景数据集);结合姿态估计(如 MediaPipe)判断手部是否靠近口部。


特征融合


结合烟雾的动态特征(如光流向量)和静态特征(颜色、纹理);使用背景减除(如 MOG2 算法)提取运动区域,排除静态干扰。


抗干扰处理


针对光照变化:使用自适应阈值或白平衡校正;


针对相似物体(如白色杯子):增加形状和纹理分析。


四、注意事项


实际应用中需大量标注数据训练模型,否则传统方法易受环境干扰;可结合边缘计算设备(如 Jetson Nano)实现实时检测;抽烟行为的判定需要时间序列分析(非单帧判断),避免误检。


通过上述方法,可以构建一个基础的抽烟识别系统,实际部署时需根据场景进行参数调优和模型训练。

- END -
分享:
留言 留言 样机申请
电话咨询 电话咨询 电话联系
19113907060
微信在线客服 微信在线客服 在线客服
返回官网顶部 返回官网顶部 回到顶部
关闭窗口
产品订购
  • *

  • *

  • *

  • *

  • *