Python暴力画面识别
作者:综合 来源:时尚 浏览: 【大 中 小】 发布时间:2026-10-17 06:05:50 评论数:
去年秋天帮朋友处理一批交通监控截图,暴力三千多张,画面要从中挑出所有出现摩托车的识别画面。手动翻了半小时,暴力眼睛快瞎了,画面效率约等于零。识别当时第一反应是暴力上深度学习,YOLO或者Faster R-CNN。画面但装完环境跑了一遍,识别发现更麻烦——标注数据没有,暴力训练要时间,画面调参要经验。识别我需要的暴力只是"图里有没有摩托车",不是画面"摩托车在哪个像素位置"。
这就引出一个被很多人忽略的识别事实:画面识别不等于深度学习。 如果你的目标只是粗筛、分类、找异常,暴力方法往往比神经网络更快落地。
什么叫"暴力"
这里的暴力不是贬义。它指的是不训练模型、不依赖预训练权重,直接用像素级运算做判断。OpenCV 是干这事最顺手的工具。
举个例子。监控画面里找运动物体,最土的办法是帧差法:
import cv2 import numpy as np cap = cv2.VideoCapture('monitor.mp4') ret, prev = cap.read() prev_gray = cv2.cvtColor(prev, cv2.COLOR_BGR2GRAY) while True: ret, frame = cap.read() if not ret: break gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) diff = cv2.absdiff(prev_gray, gray) _, thresh = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY) changed = np.sum(thresh) / 255 if changed > 5000: print(f"第{ cap.get(cv2.CAP_PROP_POS_FRAMES)}帧有大面积变化") prev_gray = gray 十几行代码,不需要GPU,不需要标注。帧间差异超过阈值就报警。对于固定机位的监控,这招命中率相当可观。
颜色和轮廓比你想的好用
回到摩托车那个任务。我最后没上深度学习,走了一条野路子:摩托车骑手通常戴头盔,头盔颜色鲜艳且呈圆形。先用HSV色彩空间过滤出高饱和度区域,再找轮廓,算圆形度。
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv, (0, 120, 100), (180, 255, 255)) contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for c in contours: area = cv2.contourArea(c) if area < 300: continue perimeter = cv2.arcLength(c, True) circularity = 4 * np.pi * area / (perimeter ** 2) if circularity > 0.7: print("可能是头盔") 误报当然有。红色消防栓、圆形广告牌都会触发。但三千张里筛出两百张候选,我再人工过一遍,十分钟搞定。比训练模型省了至少两天。
什么时候暴力方法会翻车
光照突变。傍晚路灯刚亮那一瞬间,帧差法会报出满屏变化。我试过加高斯模糊和自适应阈值,能缓解,不能根治。
还有遮挡和重叠。两个行人并排走,轮廓粘在一起,圆形度计算直接失效。这种场景下传统方法确实打不过神经网络。
但话说回来,很多实际需求根本到不了那个复杂度。工厂流水线上检测产品有没有放歪,用模板匹配就够了。停车场统计空位,对每个车位区域算像素方差就行。这些场景上深度学习,属于拿大炮打蚊子。
一个实用的判断标准
我自己的经验法则:如果人能在一秒内用一句话描述判断依据——"颜色不对""位置偏了""比昨天多了一块"——那大概率可以用暴力方法实现。反过来,如果判断依据说不清,比如"看起来像猫但不是猫",那就老老实实标数据训模型。
Python 在这件事上的优势不是语言本身,是 OpenCV、NumPy、Pillow 这套生态。装完就能跑,不用配 CUDA,不用下几百兆的权重文件。原型验证阶段,这种轻量感比精度重要得多。
那批监控截图最后处理完了。脚本跑了四十分钟,我喝了杯咖啡。要是等模型训练完,咖啡得喝一整天。
