HaarCascade与HOGDescriptor在人像检测项目中的性能对比及优化咨询
优化后的C++代码
修复原代码中像素计数bug、重复计算问题,并加入检测区域裁剪优化:
#include <opencv2/opencv.hpp> #include <iostream> #include <vector> using namespace cv; // HSV蓝色阈值 Scalar lower_blue(110, 50, 50); Scalar upper_blue(130, 255, 255); // 统计蓝色区域像素数(用OpenCV原生函数替代循环,提升速度) int countBluePixels(const Mat& image) { Mat imgHSV, mask; cvtColor(image, imgHSV, COLOR_BGR2HSV); inRange(imgHSV, lower_blue, upper_blue, mask); return countNonZero(mask); } // 找到蓝色区域最多的人脸 int findTargetFace(const std::vector<Mat>& faceImages) { if (faceImages.empty()) return -1; int maxCount = 0; int targetIndex = 0; for (int i = 0; i < faceImages.size(); ++i) { int cnt = countBluePixels(faceImages[i]); if (cnt > maxCount) { maxCount = cnt; targetIndex = i; } } return targetIndex; } int main() { Mat img, frame; std::string faceXml = "Resources/haarcascade_frontalface_default.xml"; std::vector<Rect> faces; std::vector<Mat> faceCrops; CascadeClassifier faceCascade; VideoCapture cap(0); if (!faceCascade.load(faceXml)) { std::cerr << "Failed to load Haar cascade file" << std::endl; return -1; } if (!cap.isOpened()) { std::cerr << "Failed to open camera" << std::endl; return -1; } while (true) { cap >> img; if (img.empty()) break; // 裁剪检测区域:只检测画面上半部分(帽子区域) Mat roi = img(Rect(0, 0, img.cols, img.rows * 0.7)); // 缩小输入尺寸提速 resize(roi, frame, Size(640, 360)); // 优化Haar检测参数 faceCascade.detectMultiScale(frame, faces, 1.2, 5); faceCrops.clear(); for (const auto& face : faces) { // 还原裁剪区域的坐标 Rect originalFace(face.x, face.y, face.width, face.height); // 扩展区域包含帽子 originalFace.y -= 40; originalFace.height += 60; // 避免越界 originalFace &= Rect(0, 0, img.cols, img.rows); faceCrops.push_back(img(originalFace)); } int targetIdx = findTargetFace(faceCrops); // 绘制检测结果 for (int i = 0; i < faces.size(); ++i) { Rect drawFace(faces[i].x, faces[i].y, faces[i].width, faces[i].height); drawFace.y -= 40; drawFace.height += 60; drawFace &= Rect(0, 0, img.cols, img.rows); if (i == targetIdx) { rectangle(img, drawFace, Scalar(0, 255, 255), 3); // 目标用黄色框 } else { rectangle(img, drawFace, Scalar(255, 255, 0), 2); // 其他人用青色框 } } imshow("Blue Hat Tracker", img); if (waitKey(1) == 27) break; } cap.release(); destroyAllWindows(); return 0; }
无NumPy的Python代码示例
使用OpenCV原生函数实现,不依赖NumPy:
import cv2 # HSV蓝色阈值 lower_blue = (110, 50, 50) upper_blue = (130, 255, 255) def count_blue_pixels(image): img_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) mask = cv2.inRange(img_hsv, lower_blue, upper_blue) # 用OpenCV原生函数计数 return cv2.countNonZero(mask) def find_target_face(face_images): if not face_images: return -1 max_count = 0 target_idx = 0 for i, img in enumerate(face_images): cnt = count_blue_pixels(img) if cnt > max_count: max_count = cnt target_idx = i return target_idx def main(): face_cascade = cv2.CascadeClassifier("Resources/haarcascade_frontalface_default.xml") cap = cv2.VideoCapture(0) if not face_cascade.load("Resources/haarcascade_frontalface_default.xml"): print("Failed to load Haar cascade file") return if not cap.isOpened(): print("Failed to open camera") return while True: ret, img = cap.read() if not ret: break # 裁剪上半部分作为检测区域 roi = img[0:int(img.shape[0]*0.7), :] # 缩小尺寸提速 frame = cv2.resize(roi, (640, 360)) # 优化Haar检测参数 faces = face_cascade.detectMultiScale(frame, scaleFactor=1.2, minNeighbors=5) face_crops = [] for (x, y, w, h) in faces: # 还原原始坐标并扩展区域包含帽子 original_x = x original_y = y original_y -= 40 original_h = h + 60 # 避免越界 if original_y < 0: original_y = 0 if original_y + original_h > img.shape[0]: original_h = img.shape[0] - original_y face_crop = img[original_y:original_y+original_h, original_x:original_x+w] face_crops.append(face_crop) target_idx = find_target_face(face_crops) # 绘制结果 for i, (x, y, w, h) in enumerate(faces): draw_x = x draw_y = y - 40 draw_w = w draw_h = h + 60 # 边界检查 if draw_y < 0: draw_y = 0 if draw_y + draw_h > img.shape[0]: draw_h = img.shape[0] - draw_y if i == target_idx: cv2.rectangle(img, (draw_x, draw_y), (draw_x+draw_w, draw_y+draw_h), (0,255,255), 3) else: cv2.rectangle(img, (draw_x, draw_y), (draw_x+draw_w, draw_y+draw_h), (255,255,0), 2) cv2.imshow("Blue Hat Tracker", img) if cv2.waitKey(1) == 27: break cap.release() cv2.destroyAllWindows() if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者shlok bhadani
相关产品推荐
相关产品推荐

