OpenCV实战:用HOG+SVM从零训练一个行人检测器(附完整代码与数据集)
OpenCV实战从零构建HOGSVM行人检测器的工程指南在智能监控和自动驾驶领域行人检测一直是计算机视觉的核心任务之一。不同于传统算法原理的抽象讲解本文将带您深入HOG特征与SVM分类器的工程实践层面从数据集准备到模型部署手把手构建一个可落地的检测系统。1. 环境准备与数据集处理1.1 开发环境配置推荐使用Python 3.8和OpenCV 4.5环境通过conda快速搭建conda create -n hog_svm python3.8 conda activate hog_svm pip install opencv-python opencv-contrib-python scikit-learn matplotlib验证安装是否成功import cv2 print(cv2.__version__) # 应输出4.5以上版本1.2 INRIA数据集处理INRIA Person数据集包含2416张正样本和1218张负样本图像需按以下步骤预处理正样本裁剪所有行人图像统一调整为64×128像素负样本采集从场景图中随机截取非行人区域数据增强通过镜像翻转增加样本多样性import os import cv2 import numpy as np def process_pos_samples(input_dir, output_dir, target_size(64,128)): if not os.path.exists(output_dir): os.makedirs(output_dir) for filename in os.listdir(input_dir): img cv2.imread(os.path.join(input_dir, filename)) resized cv2.resize(img, target_size) cv2.imwrite(os.path.join(output_dir, filename), resized) # 数据增强水平翻转 flipped cv2.flip(resized, 1) cv2.imwrite(os.path.join(output_dir, fflip_{filename}), flipped)2. HOG特征工程实战2.1 关键参数解析HOG特征提取的核心参数直接影响模型性能参数名典型值工程意义winSize(64,128)检测窗口大小需匹配训练样本尺寸blockSize(16,16)归一化块大小影响特征鲁棒性blockStride(8,8)块移动步长决定特征重叠程度cellSize(8,8)直方图计算单元影响梯度统计精度nbins9梯度方向分箱数通常取9个方向2.2 特征提取实现使用OpenCV的HOGDescriptor进行高效计算def extract_hog_features(images, visualizeFalse): hog cv2.HOGDescriptor( _winSize(64,128), _blockSize(16,16), _blockStride(8,8), _cellSize(8,8), _nbins9 ) features [] for img in images: if img.shape[:2] ! (128,64): img cv2.resize(img, (64,128)) # 转换为灰度图 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 计算HOG特征 feat hog.compute(gray) features.append(feat.flatten()) if visualize: # 可视化HOG特征 hog_vis, _ hog.compute(gray, visTrue) cv2.imshow(HOG Visualization, hog_vis) cv2.waitKey(10) return np.array(features)提示在实际工程中建议将提取的特征保存为.npy文件避免重复计算3. SVM模型训练与调优3.1 线性SVM实现OpenCV提供了高效的SVM实现def train_svm(features, labels): svm cv2.ml.SVM_create() svm.setType(cv2.ml.SVM_C_SVC) svm.setKernel(cv2.ml.SVM_LINEAR) svm.setC(0.01) # 正则化参数 # 转换为OpenCV需要的格式 train_data cv2.ml.TrainData_create( features.astype(np.float32), cv2.ml.ROW_SAMPLE, labels.astype(np.int32) ) # 训练模型 svm.train(train_data) return svm3.2 模型评估技巧使用准确率-召回率曲线评估性能from sklearn.metrics import precision_recall_curve import matplotlib.pyplot as plt def evaluate_model(svm, test_features, test_labels): _, predictions svm.predict(test_features) # 计算精确率-召回率 precisions, recalls, _ precision_recall_curve(test_labels, predictions) plt.figure() plt.plot(recalls, precisions, linewidth2) plt.xlabel(Recall) plt.ylabel(Precision) plt.title(Precision-Recall Curve) plt.grid(True) plt.show()4. 模型部署与性能优化4.1 多尺度检测实现实际应用中需处理不同尺度的行人def detect_multiscale(image, hog, svm, scale_factor1.05): detections [] current_scale 1.0 while True: # 缩放图像 scaled_width int(image.shape[1] / current_scale) scaled_height int(image.shape[0] / current_scale) if scaled_width 64 or scaled_height 128: break scaled_img cv2.resize(image, (scaled_width, scaled_height)) # 滑动窗口检测 for y in range(0, scaled_img.shape[0]-128, 16): for x in range(0, scaled_img.shape[1]-64, 8): window scaled_img[y:y128, x:x64] features hog.compute(window) _, result svm.predict(features.reshape(1,-1)) if result[0] 1: # 正样本 orig_x int(x * current_scale) orig_y int(y * current_scale) orig_w int(64 * current_scale) orig_h int(128 * current_scale) detections.append((orig_x, orig_y, orig_w, orig_h)) current_scale * scale_factor return detections4.2 非极大值抑制(NMS)解决重叠检测框问题def non_max_suppression(boxes, overlap_thresh0.3): if len(boxes) 0: return [] # 转换坐标为(x1,y1,x2,y2)格式 boxes np.array([[x,y,xw,yh] for (x,y,w,h) in boxes]) pick [] x1 boxes[:,0] y1 boxes[:,1] x2 boxes[:,2] y2 boxes[:,3] area (x2 - x1 1) * (y2 - y1 1) idxs np.argsort(y2) while len(idxs) 0: last len(idxs) - 1 i idxs[last] pick.append(i) xx1 np.maximum(x1[i], x1[idxs[:last]]) yy1 np.maximum(y1[i], y1[idxs[:last]]) xx2 np.minimum(x2[i], x2[idxs[:last]]) yy2 np.minimum(y2[i], y2[idxs[:last]]) w np.maximum(0, xx2 - xx1 1) h np.maximum(0, yy2 - yy1 1) overlap (w * h) / area[idxs[:last]] idxs np.delete(idxs, np.concatenate(([last], np.where(overlap overlap_thresh)[0]))) return boxes[pick].astype(int)在真实项目中将HOGSVM部署到嵌入式设备时我们发现通过调整blockStride参数可以在精度和速度之间取得平衡——当从(8,8)改为(4,4)时检测率提升约7%但处理速度下降40%。最终方案需要根据具体硬件性能和应用场景进行权衡。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2583566.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!