使用OpenCV和MediaPipe库——抽烟检测(姿态监控)

目录

抽烟检测的运用

[1. 安全监控](#1. 安全监控)

[(1) 公共场所禁烟监管](#(1) 公共场所禁烟监管)

[(2) 工业安全](#(2) 工业安全)

[2. 智能城市与执法](#2. 智能城市与执法)

[(1) 城市违章吸烟检测](#(1) 城市违章吸烟检测)

[(2) 无人值守管理](#(2) 无人值守管理)

[3. 健康管理与医疗](#3. 健康管理与医疗)

[(1) 吸烟习惯分析](#(1) 吸烟习惯分析)

[(2) 远程监护](#(2) 远程监护)

[4. AI 监控与商业分析](#4. AI 监控与商业分析)

[(1) 保险行业](#(1) 保险行业)

[(2) 商场营销](#(2) 商场营销)

[5. 技术实现](#5. 技术实现)

[(1) 计算机视觉](#(1) 计算机视觉)

[(2) 传感器检测](#(2) 传感器检测)

[(3) 结合物联网(IoT)](#(3) 结合物联网(IoT))

[6. 挑战与优化](#6. 挑战与优化)

[(1) 误报问题](#(1) 误报问题)

[(2) 夜间检测难度](#(2) 夜间检测难度)

[(3) 隐私问题](#(3) 隐私问题)

代码实现思路

实现思路

[1. 初始化检测模型](#1. 初始化检测模型)

[2. 读取视频流](#2. 读取视频流)

[3. 手部检测](#3. 手部检测)

[4. 香烟检测](#4. 香烟检测)

[5. 嘴部检测](#5. 嘴部检测)

[6. 抽烟行为判断](#6. 抽烟行为判断)

[7. 可视化输出](#7. 可视化输出)

[8. 运行主循环](#8. 运行主循环)

完整代码

效果展示



抽烟检测的运用

1. 安全监控

(1) 公共场所禁烟监管

  • 应用场景:机场、火车站、地铁站、医院、商场、学校等禁烟区域。
  • 作用:利用摄像头自动检测吸烟行为,触发警报或通知管理人员干预,减少人工巡逻成本。

(2) 工业安全

  • 应用场景:化工厂、加油站、煤矿、仓库等易燃易爆场所。
  • 作用:实时监测抽烟行为,防止安全事故,提高生产安全管理。

2. 智能城市与执法

(1) 城市违章吸烟检测

  • 应用场景:公交站、公共厕所、电梯、餐厅等区域。
  • 作用:结合智能监控系统,对违规吸烟行为进行抓拍、存证,甚至自动处罚。

(2) 无人值守管理

  • 应用场景:智能楼宇、写字楼、电影院等无人巡逻区域。
  • 作用:通过 AI 检测+语音提醒,劝阻违规吸烟者。

3. 健康管理与医疗

(1) 吸烟习惯分析

  • 应用场景:医院、戒烟中心、健康管理 APP。
  • 作用:记录个人抽烟次数、时间、环境等数据,帮助戒烟计划制定。

(2) 远程监护

  • 应用场景:养老院、精神病院等特殊场所。
  • 作用:监测老年人或患者是否有吸烟行为,防止健康风险。

4. AI 监控与商业分析

(1) 保险行业

  • 应用场景:人寿保险、健康保险公司。
  • 作用:检测投保人是否吸烟,调整保费或健康建议。

(2) 商场营销

  • 应用场景:便利店、烟草店。
  • 作用:分析吸烟人群的特征,优化营销策略。

5. 技术实现

(1) 计算机视觉

  • 算法 :基于 YOLO、Faster R-CNN 等目标检测模型。
  • 数据:训练数据包含吸烟者的手部、嘴部、烟雾等特征。

(2) 传感器检测

  • 红外摄像头:检测烟头的温度特征。
  • 空气质量传感器:监测 PM2.5、尼古丁气味等。

(3) 结合物联网(IoT)

  • 智能监控摄像头:内置 AI 识别系统,边缘计算本地处理数据。
  • 云平台:接收数据并发出警报。

6. 挑战与优化

(1) 误报问题

  • 误将吸烟动作与喝水、拿笔等动作混淆。
  • 解决方案:使用时间序列分析、骨骼检测等方法提高准确率。

(2) 夜间检测难度

  • 夜间光照条件差,普通摄像头难以检测烟雾。
  • 解决方案:采用 红外摄像头 结合 AI 算法提高夜间识别率。

(3) 隐私问题

  • 监控摄像头涉及个人隐私,可能引发争议。
  • 解决方案:使用 边缘计算,仅上传检测结果,不存储人脸信息。



代码实现思路

实现思路

1. 初始化检测模型

  • MediaPipe Hands :用于检测 手部位置,得到手的边界框(bounding box)。
  • dlib 人脸关键点检测 :用于检测 嘴部关键点,确定嘴巴的位置。
  • YOLOv3 :用于检测 香烟 ,需要加载权重(yolov3.weights)、配置文件(yolov3.cfg)和类别标签(coco.names)。

2. 读取视频流

  • 通过 cv2.VideoCapture(0) 打开摄像头,逐帧读取视频。

3. 手部检测

  • MediaPipe Hands 处理帧图像,返回检测到的手部 关键点
  • 计算手部的 边界框x_min, y_min, x_max, y_max)。
  • 使用 cv2.rectangle() 画出手部边界框。

4. 香烟检测

  • 通过 YOLOv3 目标检测 识别图像中的物体(包括香烟)。
  • 过滤出 类别为 "cigarette" 的目标 ,并记录香烟的边界框信息(cigarette_bboxes)。
  • 使用 cv2.rectangle() 画出香烟的位置。

5. 嘴部检测

  • 通过 dlib 人脸检测器 定位人脸,并使用 68个面部关键点 识别嘴部(第48-67号点)。
  • 计算 嘴部中心位置
  • cv2.polylines() 画出嘴部区域。

6. 抽烟行为判断

  • 遍历每只 手的边界框
    1. 判断是否持有香烟 (手与香烟的 IOU 交并比 是否超过阈值 0.3)。
    2. 计算手部到嘴部的距离
      • 获取手部中心 (hand_center_x, hand_center_y)
      • 计算与 最近的嘴部中心 的欧几里得距离 distance
    3. 综合判断抽烟行为
      • 手持香烟 且 距离嘴部<100像素 ,则判定 正在抽烟
      • 手部靠近嘴部<50像素 ,但未持有香烟,则 可能在抽烟(警告)。

7. 可视化输出

  • 如果检测到 正在抽烟
    • 在屏幕上显示 "WARNING: Active Smoking Detected!"(红色警告)。
  • 如果 疑似抽烟 (手靠近嘴但未持烟):
    • 显示 "Potential Smoking!"(黄色提示)。
  • 画出所有检测到的 手部、香烟、嘴部

8. 运行主循环

  • 不断读取摄像头画面,并调用 detect_smoking(frame) 进行检测。
  • 按下 ESC 退出程序。



完整代码

python 复制代码
import cv2
import numpy as np
import dlib
import mediapipe as mp

# 初始化MediaPipe手部检测
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(
    max_num_hands=2,
    min_detection_confidence=0.7,
    min_tracking_confidence=0.5
)

# 初始化dlib人脸检测
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

# 加载YOLOv3模型(需包含自定义训练的香烟类别)
net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers().flatten()]

with open("coco.names", "r") as f:
    classes = [line.strip() for line in f.readlines()]


def is_holding_cigarette(hand_bbox, cigarette_bboxes, iou_threshold=0.3):
    """判断手部是否持有香烟(基于IOU)"""
    for cig_bbox in cigarette_bboxes:
        # 计算IOU
        x1 = max(hand_bbox[0], cig_bbox[0])
        y1 = max(hand_bbox[1], cig_bbox[1])
        x2 = min(hand_bbox[2], cig_bbox[2])
        y2 = min(hand_bbox[3], cig_bbox[3])

        intersection = max(0, x2 - x1) * max(0, y2 - y1)
        area_hand = (hand_bbox[2] - hand_bbox[0]) * (hand_bbox[3] - hand_bbox[1])
        area_cig = (cig_bbox[2] - cig_bbox[0]) * (cig_bbox[3] - cig_bbox[1])

        iou = intersection / (area_hand + area_cig - intersection)
        if iou > iou_threshold:
            return True
    return False


def detect_smoking(frame):
    # 转换为RGB格式(MediaPipe需要)
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # 手部检测
    hand_bboxes = []
    results = hands.process(rgb_frame)
    if results.multi_hand_landmarks:
        for landmarks in results.multi_hand_landmarks:
            # 获取手部边界框
            x_coords = [lm.x * frame.shape[1] for lm in landmarks.landmark]
            y_coords = [lm.y * frame.shape[0] for lm in landmarks.landmark]
            x_min, x_max = min(x_coords), max(x_coords)
            y_min, y_max = min(y_coords), max(y_coords)
            hand_bboxes.append((x_min, y_min, x_max, y_max))
            cv2.rectangle(frame, (int(x_min), int(y_min)),
                          (int(x_max), int(y_max)), (255, 0, 0), 2)

    # YOLOv3香烟检测
    cigarette_bboxes = []
    blob = cv2.dnn.blobFromImage(frame, 0.00392, (320, 320), swapRB=True)
    net.setInput(blob)
    outs = net.forward(output_layers)

    for out in outs:
        for detection in out:
            scores = detection[5:]
            class_id = np.argmax(scores)
            confidence = scores[class_id]
            if confidence > 0.5 and classes[class_id] == "cigarette":
                center_x = int(detection[0] * frame.shape[1])
                center_y = int(detection[1] * frame.shape[0])
                w = int(detection[2] * frame.shape[1])
                h = int(detection[3] * frame.shape[0])
                x = center_x - w // 2
                y = center_y - h // 2
                cigarette_bboxes.append((x, y, x + w, y + h))
                cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

    # 人脸关键点检测
    mouth_positions = []
    faces = detector(frame)
    for face in faces:
        landmarks = predictor(frame, face)
        mouth_points = [(landmarks.part(i).x, landmarks.part(i).y)
                        for i in range(48, 68)]
        mouth_center = np.mean(mouth_points, axis=0)
        mouth_positions.append(mouth_center)
        # 绘制嘴巴区域
        cv2.polylines(frame, [np.array(mouth_points, dtype=np.int32)],
                      True, (0, 0, 255), 2)

    # 综合判断逻辑
    warning = False
    for hand in hand_bboxes:
        # 判断是否持烟
        holding = is_holding_cigarette(hand, cigarette_bboxes)

        # 计算手部中心点
        hand_center = ((hand[0] + hand[2]) / 2, (hand[1] + hand[3]) / 2)

        # 找最近的人脸
        min_distance = float('inf')
        for mouth in mouth_positions:
            distance = np.sqrt((hand_center[0] - mouth[0]) ** 2 +
                               (hand_center[1] - mouth[1]) ** 2)
            min_distance = min(min_distance, distance)

        # 判断条件
        if holding and min_distance < 100:  # 持烟且距离<100像素
            warning = True
        elif min_distance < 50:  # 未持烟但手部靠近嘴部
            cv2.putText(frame, "Potential Smoking!",
                        (int(hand[0]), int(hand[1]) - 10),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)

    if warning:
        cv2.putText(frame, "WARNING: Active Smoking Detected!",
                    (20, 50), cv2.FONT_HERSHEY_SIMPLEX,
                    1, (0, 0, 255), 3, cv2.LINE_AA)

    return frame


# 视频处理主循环
cap = cv2.VideoCapture(0)
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    frame = cv2.flip(frame, 1)  # 镜像翻转
    result = detect_smoking(frame)

    cv2.imshow('Smoking Detection', result)
    if cv2.waitKey(1) == 27:
        break

cap.release()
cv2.destroyAllWindows()

效果展示

相关推荐
三天不学习7 分钟前
浅析AI大模型为何需要向量数据库?【入门基础】
数据库·人工智能·欧氏距离·向量数据库·余弦相似度
WenGyyyL17 分钟前
研读论文——《用于3D工业异常检测的自监督特征自适应》
人工智能·python·深度学习·机器学习·计算机视觉·3d
fydw_71522 分钟前
音频生成技术的前沿探索:从语音合成到智能Podcast
人工智能·音视频·语音识别
选型宝23 分钟前
腾讯怎样基于DeepSeek搭建企业应用?怎样私有化部署满血版DS?直播:腾讯云X DeepSeek!
人工智能·ai·云计算·腾讯云·选型宝
多巴胺与内啡肽.1 小时前
OpenCV进阶操作:人脸检测、微笑检测
人工智能·opencv·计算机视觉
Wnq100721 小时前
基于 NanoDet 的工厂巡检机器人目标识别系统研究与实现
人工智能·机器学习·计算机视觉·目标跟踪·机器人·巡检机器人
一年春又来1 小时前
AI-02a5a6.神经网络-与学习相关的技巧-批量归一化
人工智能·神经网络·学习
kovlistudio1 小时前
机器学习第十讲:异常值检测 → 发现身高填3米的不合理数据
人工智能·机器学习
马拉AI1 小时前
解锁Nature发文小Tips:LSTM、CNN与Attention的创新融合之路
人工智能·cnn·lstm
sufu10651 小时前
SpringAI更新:废弃tools方法、正式支持DeepSeek!
人工智能·后端