当前位置: 首页 > news >正文

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

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

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

0. 前言

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

1. HOG + SVM 行人检测

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

1.1 实现过程

  • 创建 HOG 描述符并加载默认行人 SVM 权重
  • 读取图像/视频帧
  • 调用 detectMultiScale 执行滑窗检测,返回一系列候选行人矩形框
  • 绘制检测结果 并显示
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:breakcap.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) 加速检测。

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]# 应用 NMSrects_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: breakcap.release()
cv2.destroyAllWindows()

关键函数解析:

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

2. Haar 级联分类器

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

2.1 实现过程

  • 加载级联分类器 XML 文件
  • 读取图像并转换为灰度
  • 调用 detectMultiScale,得到一系列检测框
  • 据置信度或最小/最大尺寸过滤,并绘制结果
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,以及分阶段检测(先粗后细),可在速度与准确度之间找到平衡。

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
  • 保存模型
  • 加载模型并在新图像上滑窗检测
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)——图像拼接详解

http://www.dtcms.com/a/362969.html

相关文章:

  • 在Docker中安装MySQL时3306端口占用问题
  • 广度优先搜索(BFS, Breadth-First Search)
  • 书写腾讯天气遇到的问题
  • LeetCode 777.在LR字符串中交换相邻字符
  • PyTorch 面试题及详细答案120题(106-115)-- 理论与拓展
  • LeetCode 刷题【61. 旋转链表】
  • SAP-MM 配置工厂的名称时候,容易疏忽的点
  • Linux操作系统(6)
  • 《驾驭云原生复杂性:隐性Bug的全链路防御体系构建》
  • 线程安全问题及解决方案
  • STM32 - Embedded IDE - GCC - 如何在工程中生成.bin格式固件
  • 从API到AI Agent:落地模型上下文协议(MCP)的设计模式与核心步骤
  • 【提示词】...(后续单元)在Prompt 的作用
  • [Dify 专栏] 如何通过 Prompt 在 Dify 中模拟 Persona:即便没有专属配置,也能让 AI 扮演角色
  • 【51单片机】【protues仿真】基于51单片机呼叫系统
  • 【Qt】QToolBar、QToolButton的常用用法
  • VR智慧楼宇技术:打造智能办公空间的卓越方案​
  • 【Linux笔记】命令行与vim基础
  • qt使用笔记三之 QGraphicsView、QGraphicsScene 和 QGraphicsPixmapItem 详解
  • 深度学习——基于卷积神经网络实现食物图像分类(数据增强)
  • 教资科三【信息技术】— 教学知识(18~21题): 课程理论知识 教学评价 教学实施 教学设计
  • think
  • Ansible角色:高效开发与管理的秘密
  • Day11--HOT100--25. K 个一组翻转链表,138. 随机链表的复制,148. 排序链表
  • 开源SOTA:阶跃发布端到端语音大模型Step-Audio 2 mini!
  • Cloudflare安全规则实用指南:从路径拦截到IP限制的10个经典范例
  • 使用coil加载图片更新不及时
  • 详解CAD批量打印PDF的黑白模式设置,快速搞定批量输出
  • 【C++框架#2】gflags 和 gtest 安装使用
  • Web3 开发者周刊 65 | DAT的崛起