OpenCV计算机视觉实战(23)——目标检测详解

OpenCV计算机视觉实战(23)------目标检测详解

    • [0. 前言](#0. 前言)
    • [1. HOG + SVM 行人检测](#1. HOG + SVM 行人检测)
      • [1.1 实现过程](#1.1 实现过程)
      • [1.2 优化思路](#1.2 优化思路)
    • [2. Haar 级联分类器](#2. Haar 级联分类器)
      • [2.1 实现过程](#2.1 实现过程)
      • [2.2 优化思路](#2.2 优化思路)
    • [3. 自定义分类器训练](#3. 自定义分类器训练)
      • [3.1 实现过程](#3.1 实现过程)
    • 小结
    • 系列链接

0. 前言

在现代视觉系统中,从监控安防到智能驾驶,准确且高效地识别并定位图像中的目标对象是核心能力。本文在介绍经典的 HOG + SVM 行人检测、Haar 级联分类器以及自定义 HOG + SVM 分类器训练的基础上,深入探讨了非极大值抑制、ROI 加速、级联细化、硬负样本挖掘等实战优化技巧。

1. HOG + SVM 行人检测

使用 OpenCV 内置的 HOG 描述符与预训练的线性 SVM,对图像或视频流中的行人进行实时检测。

1.1 实现过程

  • 创建 HOG 描述符并加载默认行人 SVM 权重
  • 读取图像/视频帧
  • 调用 detectMultiScale 执行滑窗检测,返回一系列候选行人矩形框
  • 绘制检测结果 并显示
python 复制代码
import cv2

# 功能:在摄像头或视频中实时检测行人
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

cap = cv2.VideoCapture('r2.mp4')

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # 可选:调整尺寸加快检测
    frame_resized = cv2.resize(frame, (860, 480))

    # 多尺度检测
    rects, weights = hog.detectMultiScale(
        frame_resized,
        winStride=(8, 8),
        padding=(8, 8),
        scale=1.05
    )

    # 绘制检测框
    for (x, y, w, h) in rects:
        cv2.rectangle(frame_resized, (x, y), (x+w, y+h), (0, 255, 0), 2)

    cv2.imshow('HOG + SVM Pedestrian Detection', frame_resized)
    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()

关键函数解析:

  • cv2.HOGDescriptor():创建 HOG 特征提取器
  • hog.setSVMDetector(...):加载预训练的行人检测 SVM 权重
  • detectMultiScale(image, winStride, padding, scale):滑窗+图像金字塔检测目标
    • winStride:滑窗步长
    • padding:检测窗口周围填充
    • scale:金字塔缩放因子

1.2 优化思路

HOG + SVM 很适合行人检测,但默认 detectMultiScale 经常返回大量重叠框。加入非极大值抑制 (Non-Maximum Suppression, NMS) 能显著提高精度,并减少冗余框。若检测场景单一,可先定义感兴趣区域 (Region of Interest, ROI) 加速检测。

python 复制代码
import cv2
import numpy as np

# 功能:HOG+SVM 行人检测,加入 ROI 限定与 NMS
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

def non_max_suppression(boxes, overlapThresh=0.65):
    if len(boxes) == 0:
        return []
    boxes = np.array(boxes)
    pick = []
    x1 = boxes[:,0]
    y1 = boxes[:,1]
    x2 = boxes[:,0] + boxes[:,2]
    y2 = boxes[:,1] + boxes[:,3]
    areas = (x2 - x1) * (y2 - y1)
    idxs = np.argsort(y2)
    while len(idxs) > 0:
        i = idxs[-1]
        pick.append(i)
        xx1 = np.maximum(x1[i], x1[idxs[:-1]])
        yy1 = np.maximum(y1[i], y1[idxs[:-1]])
        xx2 = np.minimum(x2[i], x2[idxs[:-1]])
        yy2 = np.minimum(y2[i], y2[idxs[:-1]])
        w = np.maximum(0, xx2 - xx1)
        h = np.maximum(0, yy2 - yy1)
        overlap = (w * h) / areas[idxs[:-1]]
        idxs = np.delete(idxs, np.concatenate(([len(idxs)-1],
            np.where(overlap > overlapThresh)[0])))
    return boxes[pick].astype(int)

cap = cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()
    if not ret: break

    # 定义 ROI------只检测画面下半部分
    h, w = frame.shape[:2]
    roi = frame[h//3*2:h, :]

    rects, weights = hog.detectMultiScale(
        roi, winStride=(8,8), padding=(16,16), scale=1.05
    )
    # 坐标映射回原图
    rects = [(x, y + 2*h//3, w_, h_) for (x,y,w_,h_) in rects]
    # 应用 NMS
    rects_nms = non_max_suppression(rects, 0.6)

    for (x, y, w_, h_) in rects_nms:
        cv2.rectangle(frame, (x,y), (x+w_, y+h_), (0,255,0), 2)

    cv2.imshow('HOG+SVM with NMS', frame)
    if cv2.waitKey(1) & 0xFF == 27: break

cap.release()
cv2.destroyAllWindows()

关键函数解析:

  • non_max_suppression(boxes, overlapThresh):剔除重叠度高于阈值的冗余检测框,只保留最具代表性的
  • detectMultiScale 后先 ROI 裁剪,减少无关区域计算量

2. Haar 级联分类器

使用 OpenCV 提供的 Haar 级联 XML 模型,在图像中快速检测人脸、眼睛、车辆等常见对象。

2.1 实现过程

  • 加载级联分类器 XML 文件
  • 读取图像并转换为灰度
  • 调用 detectMultiScale,得到一系列检测框
  • 据置信度或最小/最大尺寸过滤,并绘制结果
python 复制代码
import cv2

# 功能:使用 Haar 级联检测人脸
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

img = cv2.imread('10.jpeg')
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), (255, 0, 0), 2)

cv2.imshow('Haar Cascade Face Detection', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

关键函数解析:

  • cv2.CascadeClassifier(xml_path):加载 HaarLBP 级联模型
  • detectMultiScale(image, scaleFactor, minNeighbors, minSize):多尺度扫描检测
    • minNeighbors:每个候选窗口至少需通过的相邻检测次数,越高越严格
    • minSize:目标最小尺寸,剔除过小噪声。

2.2 优化思路

Haar 级联检测器适合实时人脸、车牌、行人检测。通过调整 scaleFactorminNeighbors,以及分阶段检测(先粗后细),可在速度与准确度之间找到平衡。

python 复制代码
import cv2

# 功能:Haar 级联人脸+眼睛 检测,分级优化
face_cas = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cas  = cv2.CascadeClassifier('haarcascade_eye_tree_eyeglasses.xml')

img = cv2.imread('10.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 1. 粗级人脸检测
faces = face_cas.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(50,50))
for (x,y,w,h) in faces:
    cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)
    roi_gray = gray[y:y+h, x:x+w]
    roi_color= img[y:y+h, x:x+w]

    # 2. 细级眼睛检测
    eyes = eye_cas.detectMultiScale(roi_gray, scaleFactor=1.1, minNeighbors=5, minSize=(15,15))
    for (ex,ey,ew,eh) in eyes:
        cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh), (0,255,0), 1)

cv2.imshow('Haar Cascade Face & Eyes', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

关键函数解析:

  • 两级检测:先以较小 minNeighbors、大 scaleFactor 快速定位,再在 ROI 内用更严格参数细化
  • haarcascade_eye_tree_eyeglasses.xml:在人脸 ROI 内检测眼睛,可验证人脸准确度并应对侧脸漏检

3. 自定义分类器训练

使用自定义正/负样本,通过 HOG 提取特征并用 scikit-learn 的线性 SVM 训练一个简单的对象检测器。

3.1 实现过程

  • 准备数据集:将正样本(含目标)与负样本(不含目标)分别放在 pos/neg/ 目录
  • 遍历读取图像,对每张图像计算 HOG 特征向量,并打标签
  • 训练线性 SVM,使用 sklearn.svm.LinearSVC
  • 保存模型
  • 加载模型并在新图像上滑窗检测
python 复制代码
import cv2, os
import numpy as np
from sklearn.svm import LinearSVC
from sklearn.externals import joblib

# 功能:基于自定义样本训练 HOG+SVM 检测器
def extract_hog(image):
    hog = cv2.HOGDescriptor()
    return hog.compute(image).flatten()

# 1. 读取正/负样本并提取特征
features, labels = [], []
for fname in os.listdir('pos/'):
    img = cv2.imread(os.path.join('pos', fname), cv2.IMREAD_GRAYSCALE)
    img = cv2.resize(img, (64, 128))
    features.append(extract_hog(img))
    labels.append(1)
for fname in os.listdir('neg/'):
    img = cv2.imread(os.path.join('neg', fname), cv2.IMREAD_GRAYSCALE)
    img = cv2.resize(img, (64, 128))
    features.append(extract_hog(img))
    labels.append(0)

X = np.array(features)
y = np.array(labels)

# 2. 训练 SVM
svm = LinearSVC()
svm.fit(X, y)
joblib.dump(svm, 'custom_hog_svm.pkl')

# 3. 滑窗检测示例
model = joblib.load('custom_hog_svm.pkl')
test = cv2.imread('test_scene.jpg')
gray = cv2.cvtColor(test, cv2.COLOR_BGR2GRAY)
h, w = 128, 64
for y0 in range(0, gray.shape[0]-h, 16):
    for x0 in range(0, gray.shape[1]-w, 16):
        window = gray[y0:y0+h, x0:x0+w]
        feat = extract_hog(window).reshape(1, -1)
        pred = model.predict(feat)
        if pred == 1:
            cv2.rectangle(test, (x0,y0), (x0+w,y0+h), (0,255,0), 2)

cv2.imshow('Custom HOG+SVM Detection', test)
cv2.waitKey(0)
cv2.destroyAllWindows()

关键函数解析

  • hog.compute(image):计算固定窗口的 HOG 特征
  • LinearSVC():训练一个线性支持向量机
  • predict(feature_vector):对滑窗提取的特征做二分类预测
  • joblib.dump/load():序列化模型,便于后续快速加载使用

小结

本文系统梳理了基于传统机器学习方法的目标检测技术,涵盖从 HOG + SVMHaar 级联分类器的应用与优化,并进一步拓展至自定义分类器的训练实战。在具体实现中,介绍了滑窗、多尺度检测的基础流程,还引入了非极大值抑制、ROI 加速、级联细化检测等提升检测效率和精度的关键策略。此外,通过训练自定义 HOG + SVM 模型,读者可以灵活应对特定场景下的目标识别任务,为构建轻量、高效的视觉系统奠定坚实基础。

系列链接

OpenCV计算机视觉实战(1)------计算机视觉简介
OpenCV计算机视觉实战(2)------环境搭建与OpenCV简介
OpenCV计算机视觉实战(3)------计算机图像处理基础
OpenCV计算机视觉实战(4)------计算机视觉核心技术全解析
OpenCV计算机视觉实战(5)------图像基础操作全解析
OpenCV计算机视觉实战(6)------经典计算机视觉算法
OpenCV计算机视觉实战(7)------色彩空间详解
OpenCV计算机视觉实战(8)------图像滤波详解
OpenCV计算机视觉实战(9)------阈值化技术详解
OpenCV计算机视觉实战(10)------形态学操作详解
OpenCV计算机视觉实战(11)------边缘检测详解
OpenCV计算机视觉实战(12)------图像金字塔与特征缩放
OpenCV计算机视觉实战(13)------轮廓检测详解
OpenCV计算机视觉实战(14)------直方图均衡化
OpenCV计算机视觉实战(15)------霍夫变换详解
OpenCV计算机视觉实战(16)------图像分割技术
OpenCV计算机视觉实战(17)------特征点检测详解
OpenCV计算机视觉实战(18)------视频处理详解
OpenCV计算机视觉实战(19)------特征描述符详解
OpenCV计算机视觉实战(20)------光流法运动分析
OpenCV计算机视觉实战(21)------模板匹配详解
OpenCV计算机视觉实战(22)------图像拼接详解

相关推荐
WSSWWWSSW10 小时前
警告:OPENCV_FFMPEG_READ_ATTEMPTS (current value is 4096)
人工智能·opencv·ffmpeg
CoovallyAIHub10 小时前
PL-YOLOv8:基于YOLOv8的无人机实时电力线检测与植被风险预警框架,实现精准巡检与预警
深度学习·算法·计算机视觉
lovod11 小时前
【视觉SLAM十四讲】相机与图像
线性代数·计算机视觉·机器人·相机
飞翔的佩奇11 小时前
【完整源码+数据集+部署教程】PHC桩实例分割系统源码和数据集:改进yolo11-Faster-EMA
python·yolo·计算机视觉·目标跟踪·yolo11·phc桩实例分割
深瞳智检1 天前
深度学习环境搭建运行(一) Ubuntu22.04 系统安装 CUDA11.8 和 CUDNN8.6.0 详细步骤(新手入门)
人工智能·python·深度学习·yolo·计算机视觉
大学生毕业题目1 天前
毕业项目推荐:64-基于yolov8/yolov5/yolo11的蝴蝶种类检测识别系统(Python+卷积神经网络)
人工智能·python·yolo·目标检测·cnn·pyqt·蝴蝶检测
卡尔曼的BD SLAMer1 天前
计算机视觉与深度学习 | 传统图像处理技术的未来发展前景分析
图像处理·算法·计算机视觉
星期天要睡觉1 天前
(纯新手教学)计算机视觉(opencv)实战十一——轮廓近似(cv2.approxPolyDP)
opencv·算法·计算机视觉
封奚泽优1 天前
提取动漫图像轮廓并拟合为样条曲线(MATLAB)
图像处理·人工智能·计算机视觉·matlab·deepseek