一、前言
近日学习Python机器视觉开发,完成两套完整人脸检测 Demo:静态图片人脸检测、摄像头实时人脸检测。此文章整合理论知识点、可直接运行代码、常见报错解决方案等,适合 OpenCV 新手入门。
二、环境搭建
2.1 PyCharm Conda 虚拟环境配置 and 创建新项目:
- 环境选择规范 优先选择
Previously configured interpreter复用已有 Conda 环境,不要新建 Virtualenv,避免重复安装依赖。
2.2 opencv-python 与 opencv-contrib-python 区别
两者只能二选一,同时安装会引发模块冲突、函数找不到。
| | |
|---|
| OpenCV 稳定基础模块,图像 / 摄像头 / Haar 人脸检测 | |
| 基础模块 + 全部扩展算法(SIFT、人脸识别、目标跟踪等) | |
四类 OpenCV 包区分:
- opencv-python:本地开发,支持 imshow 弹窗
- opencv-contrib-python:本地完整版,含所有扩展算法
- opencv-python-headless:服务器部署,无 GUI 窗口
- opencv-contrib-python-headless:服务器完整版,无 GUI
2.3 Python 单引号 / 双引号 / 三引号区别
- 单引号
' ':仅单行,内部可直接写双引号;内部单引号需转义\'
tip = 'Snape whispered: "Always."'sentence = 'I\'m still deeply in love with Lily.'
- 双引号
" ":仅单行,内部可直接写单引号,项目编码规范首选
tip = "I'm Sirius Black, Harry's godfather."
- 支持多行字符串,自动保留换行,无需
\n;内部单双引号均不用转义 - 两大用途:长文本、函数文档注释(规范使用三双引号)
# 多行提示文本msg = """人脸检测程序操作说明1. 按 q 键关闭摄像头2. 录制视频自动存入video文件夹"""# 文档注释def face_detect(): """基于Haar级联分类器实现人脸检测""" pass
2.4 f-string 格式化字符串 f""
- 字符串前缀
f 代表 f-string,全称格式化字符串(format),Python3.6+ 支持 - 语法
{变量/表达式},运行时自动替换为内容,简化字符串拼接
# 老式写法print("实时人脸坐标:", x, y, w, h)# f-string推荐写法print(f"实时人脸坐标: {x, y, w, h}")
⚠️ 要点
紧贴引号:f"文本",禁止空格f "文本"- 大括号内支持运算:
f"人脸区域总大小:{w + h}"
三、机器视觉核心理论
3.1 标准视觉处理五链路
图像采集 → 图像预处理 → 特征提取 → 目标检测 → 可视化输出
- 图像采集:读取本地图片 / 摄像头视频流,原始像素矩阵;
- 预处理:灰度化、高斯模糊降噪、二值化,降低计算量、过滤噪声;
3.2 图像底层矩阵原理
- 彩色图像:三维数组
(高度,宽度,3),OpenCV 通道顺序为 BGR,像素值 0~255; - 灰度图像:二维数组
(高度,宽度),舍弃色彩信息,计算量减少 2/3,人脸检测必须灰度图;
3.3 Haar 级联分类器检测原理
基于 Haar 特征 + AdaBoost 算法,灰度图中多尺度滑动窗口识别人脸; detectMultiScale 核心参数:
- scaleFactor=1.1:图像缩放比例,数值越小检测越精细,速度越慢;
- minNeighbors=5:过滤无效检测框,降低误检;
- minSize/maxSize:限制人脸尺寸,过滤画面中过大 / 过小干扰区域; OpenCV 内置预训练人脸模型,推荐使用内置路径避免文件缺失报错。
四、实战代码 1:静态图片人脸检测 demo1.py
功能:读取本地图片、等比例缩放、人脸检测、绘制检测框、窗口 3 秒自动关闭
import cv2# 1.读取图片img = cv2.imread('./img/hua1_GPT.png')print("图像矩阵:", img)print("图像类型:", type(img))print("图像形状(高,宽,通道):", img.shape)# 获取原图宽高,等比例缩放不拉伸h, w = img.shape[:2]target_w = 511scale = target_w / wtarget_h = int(h * scale)img_re = cv2.resize(img, (target_w, target_h))print("缩放后图像类型:", type(img_re))print("缩放后图像形状:", img_re.shape)# 2.加载人脸检测模型(推荐内置路径,避免文件找不到)face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")# 3.执行人脸检测faces = face_cascade.detectMultiScale(img_re, 1.1, 5, minSize=(100, 100), maxSize=(2000, 2000))print("检测到所有人脸坐标:", faces)# 4.遍历人脸,绘制检测框for (x, y, w, h) in faces: print(f"人脸位置 x:{x},y:{y},宽:{w},高:{h}") cv2.rectangle(img_re, (x, y), (x + w, y + h), (210, 0, 180), 2, cv2.LINE_AA)# 5.展示窗口,3000毫秒后自动关闭cv2.imshow('img_try', img_re)cv2.waitKey(3000)cv2.destroyAllWindows()
代码关键点说明
cv2.imread读取图片,路径使用相对路径,项目根目录新建img文件夹存放图片;cv2.resizecv2.rectangle参数:画布、左上角坐标、右下角坐标、BGR 颜色、线条粗细、抗锯齿;cv2.waitKey(3000)窗口停留 3 秒,填 0 代表无限等待任意按键关闭。
五、实战代码 2:摄像头实时人脸检测 demo2.py(拓展完整版)
功能:摄像头读取、画面时间戳、人脸高斯马赛克、自动录制 MP4 视频、q 键退出释放资源
import cv2import osfrom datetime import datetime# 1.打开默认摄像头cap = cv2.VideoCapture(0)if not cap.isOpened(): print("摄像头打开失败!检查设备是否被其他软件占用") exit()# ========== 视频录制配置 ==========# 获取摄像头分辨率width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))# mp4编码格式fourcc = cv2.VideoWriter.fourcc(*'mp4v')# 自动创建视频存储文件夹if not os.path.exists("video"): print("文件夹video不存在,已重新创建!") os.mkdir("video")# 视频写入对象out = cv2.VideoWriter("video/face_record.mp4", fourcc, 30, (width, height))# 2.加载人脸检测模型face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")# 3.循环读取摄像头每一帧画面while True: ret, frame = cap.read() if not ret: break # 获取当前时间戳 now_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 转为灰度图(人脸检测必备) frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 人脸检测 faces = face_cascade.detectMultiScale(frame_gray, 1.1, 5, minSize=(100, 100), maxSize=(2000, 2000)) # 画面左上角绘制时间文字 cv2.putText(frame, now_time, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 190, 0), 2) # 遍历人脸:绘制检测框 + 人脸马赛克隐私处理 for (x, y, w, h) in faces: print(f"实时人脸坐标:{x, y, w, h}") cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 120), 2, cv2.LINE_AA) # 截取人脸区域 face_roi = frame[y:y + h, x:x + w] # 高斯模糊生成马赛克,卷积核越大模糊越强 blur_face = cv2.GaussianBlur(face_roi, (31, 31), 0) # 模糊区域覆盖原图人脸 frame[y:y + h, x:x + w] = blur_face # 将当前帧写入视频文件 out.write(frame) cv2.imshow("Face Detect", frame) # 按键监听,按q退出 key = cv2.waitKey(1) if key == ord("q"): break# 释放全部硬件资源,防止摄像头持续占用cap.release()out.release()cv2.destroyAllWindows()
功能说明
- 画面时间戳:
datetime获取系统时间,cv2.putText绘制文字; - 人脸隐私马赛克
- 视频自动保存:
cv2.VideoWriter录制每一帧,自动创建video文件夹存储 mp4; - 资源规范释放:
cap.release()释放摄像头、out.release()关闭视频流、cv2.destroyAllWindows()销毁窗口,避免资源占用报错。