You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 12:18:11