OpenCV Python 图像处理:人脸检测与物体识别
FreeGuideOnline
最新
2026-06-12
OpenCV 计算机视觉实战:人脸检测与物体识别
1. 环境准备与基础图像处理
在进入实战之前,需要安装 OpenCV 库并掌握基本的图像读写与显示操作。
安装 OpenCV
打开终端,使用 pip 安装:
pip install opencv-python opencv-contrib-python
opencv-contrib-python 包含额外模块,如用于物体识别的追踪算法。
读取、显示与保存图像
import cv2
# 读取图像
img = cv2.imread('test.jpg') # 返回 BGR 格式的 NumPy 数组
# 显示图像
cv2.imshow('Window', img)
cv2.waitKey(0) # 等待按键,0表示无限等待
cv2.destroyAllWindows()
# 保存图像
cv2.imwrite('output.jpg', img)
OpenCV 默认使用 BGR 色彩空间,若需使用 Matplotlib 显示需转换为 RGB。
色彩空间转换
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # HSV
基本几何变换
resized = cv2.resize(img, (300, 200)) # 缩放
flipped = cv2.flip(img, 1) # 水平翻转
rotated = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
2. 人脸检测实战
人脸检测是计算机视觉的经典任务,OpenCV 提供了基于 Haar 级联分类器和 DNN 的方法。
基于 Haar 级联的人脸检测
Haar 特征是一种简单的矩形特征,通过 Adaboost 训练级联分类器。OpenCV 自带预训练模型。
步骤:
- 加载分类器 XML 文件。
- 将图像转为灰度。
- 调用
detectMultiScale获取人脸矩形。 - 绘制矩形框。
import cv2
# 加载预训练分类器
face_cascade = cv2.CascadeClassifier(
cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
)
img = cv2.imread('group.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 检测人脸
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=1.1, # 每次缩小比例
minNeighbors=5, # 候选矩形保留的最小邻居数
minSize=(30, 30)
)
# 绘制结果
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('Faces', img)
cv2.waitKey(0)
参数说明:
scaleFactor:控制图像金字塔的缩放步长,值越小检测越精细但更慢。minNeighbors:每个候选矩形需要保留的最少邻近矩形数,用于降低误检。minSize:检测窗口的最小尺寸。
基于 DNN 的人脸检测(更准确)
OpenCV 3.3+ 支持加载 Caffe 或 TensorFlow 模型,推荐使用深度学习模型。
# 下载模型文件:deploy.prototxt 和 res10_300x300_ssd_iter_140000_fp16.caffemodel
net = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'res10_300x300_ssd_iter_140000_fp16.caffemodel')
blob = cv2.dnn.blobFromImage(img, 1.0, (300, 300), [104, 117, 123], False, False)
net.setInput(blob)
detections = net.forward()
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > 0.5:
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(x, y, x1, y1) = box.astype("int")
cv2.rectangle(img, (x, y), (x1, y1), (0, 0, 255), 2)
DNN 方法对角度、光照变化更鲁棒,推荐在实际项目中使用。
3. 物体识别入门:利用预训练模型
物体识别需回答“图中有什么”,OpenCV 集成了 DNN 模块,可加载常见模型如 MobileNet SSD、YOLO。
使用 MobileNet SSD 进行物体检测
MobileNet SSD 可在 CPU 上实时运行,适合入门。
准备文件:
- 模型文件:
MobileNetSSD_deploy.caffemodel - 配置文件:
MobileNetSSD_deploy.prototxt - 类别标签文件(如
coco.names或自定义)
import cv2
import numpy as np
# 加载模型
net = cv2.dnn.readNetFromCaffe('MobileNetSSD_deploy.prototxt',
'MobileNetSSD_deploy.caffemodel')
CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat",
"bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
"dog", "horse", "motorbike", "person", "pottedplant", "sheep",
"sofa", "train", "tvmonitor"]
image = cv2.imread('objects.jpg')
(h, w) = image.shape[:2]
blob = cv2.dnn.blobFromImage(image, 0.007843, (300, 300), 127.5)
net.setInput(blob)
detections = net.forward()
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > 0.5:
idx = int(detections[0, 0, i, 1])
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
label = f"{CLASSES[idx]}: {confidence:.2f}"
cv2.rectangle(image, (startX, startY), (endX, endY), (255, 0, 0), 2)
cv2.putText(image, label, (startX, startY-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
cv2.imshow('Detection', image)
cv2.waitKey(0)
使用 YOLO(You Only Look Once)进行实时检测
YOLO 速度快,适合视频流。需要下载权重和配置文件(如 yolov3.weights、yolov3.cfg、coco.names)。
net = cv2.dnn.readNetFromDarknet('yolov3.cfg', 'yolov3.weights')
with open('coco.names', 'r') as f:
classes = f.read().strip().split('\n')
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
blob = cv2.dnn.blobFromImage(image, 1/255.0, (416, 416), swapRB=True, crop=False)
net.setInput(blob)
outs = net.forward(output_layers)
# 后处理:解析每个检测框,非极大值抑制
boxes, confidences, class_ids = [], [], []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
center_x, center_y, w, h = (detection[0:4] * [W, H, W, H]).astype('int')
x = int(center_x - w/2)
y = int(center_y - h/2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
idx = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
if len(idx) > 0:
for i in idx.flatten():
x, y, w, h = boxes[i]
label = f"{classes[class_ids[i]]}: {confidences[i]:.2f}"
cv2.rectangle(image, (x, y), (x+w, y+h), (0,255,0), 2)
cv2.putText(image, label, (x, y-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
4. 实战建议与常见问题
提高检测效果的技巧
- 图像预处理:调整亮度、对比度或使用直方图均衡化。
- 参数调优:针对 Haar 级联调整
scaleFactor、minNeighbors;对 DNN 调整置信度阈值。 - 多尺度检测:某些场景可对图像进行不同尺度缩放后再检测,融合结果。
处理视频流
cap = cv2.VideoCapture(0) # 摄像头
while True:
ret, frame = cap.read()
# 对 frame 进行人脸/物体检测,绘制结果
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
注意在循环内避免耗时操作,可跳帧处理以提高帧率。
常见错误与解决
error: (-215) !empty():图片路径错误或未读取到图像,检查文件是否存在。AttributeError: module 'cv2' has no attribute 'data':未安装opencv-contrib-python或版本过旧。- 检测框不准确:调整模型置信度阈值,或更换更鲁棒的模型。
通过以上内容,你已可以独立完成人脸检测与常见物体的识别任务。下一步建议尝试训练自定义物体检测模型,或结合目标跟踪实现更复杂的应用。