OpenCV-人脸检测

//---------------------------------【头文件、命名空间包含部分】----------------------------
//        描述:包含程序所使用的头文件和命名空间
//-------------------------------------------------------------------------------------------------
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;


void detectAndDisplay(Mat frame);

//--------------------------------【全局变量声明】----------------------------------------------
//        描述:声明全局变量
//-------------------------------------------------------------------------------------------------
//注意,需要把"haarcascade_frontalface_alt.xml"和"haarcascade_eye_tree_eyeglasses.xml"这两个文件复制到工程路径下
String face_cascade_name = "haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
string window_name = "Capture - Face detection";
RNG rng(12345);

//-----------------------------------【main( )函数】--------------------------------------------
//        描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main(void)
{
    VideoCapture capture;
    Mat frame;


    //-- 1. 加载级联(cascades)
    if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading\n"); return -1; };

    //-- 2. 读取视频
    capture.open(0);
    if (capture.isOpened())
    {
        for (;;)
        {
            capture >> frame;

            //-- 3. 对当前帧使用分类器(Apply the classifier to the frame)
            if (!frame.empty())
            {
                detectAndDisplay(frame);
            }
            else
            {
                printf(" --(!) No captured frame -- Break!"); break;
            }

            int c = waitKey(10);
            if ((char)c == 'c') { break; }

        }
    }
    return 0;
}


void detectAndDisplay(Mat frame)
{
    std::vector<Rect> faces;
    Mat frame_gray;

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    equalizeHist(frame_gray, frame_gray);

    //-- 人脸检测
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));


    for (size_t i = 0; i < faces.size(); i++)
    {
        Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
        ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 2, 8, 0);

        Mat faceROI = frame_gray(faces[i]);

        
    }
    //-- 显示最终效果图
    imshow(window_name, frame);
}

//---------------------------------【头文件、命名空间包含部分】----------------------------
//        描述:包含程序所使用的头文件和命名空间
//-------------------------------------------------------------------------------------------------
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;


void detectAndDisplay(Mat frame);

//--------------------------------【全局变量声明】----------------------------------------------
//        描述:声明全局变量
//-------------------------------------------------------------------------------------------------
//注意,需要把"haarcascade_frontalface_alt.xml"和"haarcascade_eye_tree_eyeglasses.xml"这两个文件复制到工程路径下
String face_cascade_name = "haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
string window_name = "Capture - Face detection";
RNG rng(12345);

//-----------------------------------【main( )函数】--------------------------------------------
//        描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main(void)
{
    VideoCapture capture;
    Mat frame;


    //-- 1. 加载级联(cascades)
    if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading\n"); return -1; };

    //-- 2. 读取视频
    capture.open(0);
    if (capture.isOpened())
    {
        for (;;)
        {
            capture >> frame;

            //-- 3. 对当前帧使用分类器(Apply the classifier to the frame)
            if (!frame.empty())
            {
                detectAndDisplay(frame);
            }
            else
            {
                printf(" --(!) No captured frame -- Break!"); break;
            }

            int c = waitKey(10);
            if ((char)c == 'c') { break; }

        }
    }
    return 0;
}


void detectAndDisplay(Mat frame)
{
    std::vector<Rect> faces;
    Mat frame_gray;

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    equalizeHist(frame_gray, frame_gray);

    //-- 人脸检测
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));


    for (size_t i = 0; i < faces.size(); i++)
    {
        Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
        ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 2, 8, 0);

        Mat faceROI = frame_gray(faces[i]);

        
    }
    //-- 显示最终效果图
    imshow(window_name, frame);
}

//---------------------------------【头文件、命名空间包含部分】----------------------------
//        描述:包含程序所使用的头文件和命名空间
//-------------------------------------------------------------------------------------------------
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;


void detectAndDisplay(Mat frame);

//--------------------------------【全局变量声明】----------------------------------------------
//        描述:声明全局变量
//-------------------------------------------------------------------------------------------------
//注意,需要把"haarcascade_frontalface_alt.xml"和"haarcascade_eye_tree_eyeglasses.xml"这两个文件复制到工程路径下
String face_cascade_name = "haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
string window_name = "Capture - Face detection";
RNG rng(12345);

//-----------------------------------【main( )函数】--------------------------------------------
//        描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main(void)
{
    VideoCapture capture;
    Mat frame;


    //-- 1. 加载级联(cascades)
    if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading\n"); return -1; };

    //-- 2. 读取视频
    capture.open(0);
    if (capture.isOpened())
    {
        for (;;)
        {
            capture >> frame;

            //-- 3. 对当前帧使用分类器(Apply the classifier to the frame)
            if (!frame.empty())
            {
                detectAndDisplay(frame);
            }
            else
            {
                printf(" --(!) No captured frame -- Break!"); break;
            }

            int c = waitKey(10);
            if ((char)c == 'c') { break; }

        }
    }
    return 0;
}


void detectAndDisplay(Mat frame)
{
    std::vector<Rect> faces;
    Mat frame_gray;

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    equalizeHist(frame_gray, frame_gray);

    //-- 人脸检测
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));


    for (size_t i = 0; i < faces.size(); i++)
    {
        Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
        ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 2, 8, 0);

        Mat faceROI = frame_gray(faces[i]);

        
    }
    //-- 显示最终效果图
    imshow(window_name, frame);
}

 

<think> 我们正在处理用户关于使用OpenCV-Python进行人脸检测的查询。根据引用内容,我们可以总结出以下关键点: 1. 引用[1]和[2]提供了使用OpenCV进行人脸检测的示例代码,其中引用[2]的代码更详细,展示了从读取图片到检测人脸并绘制矩形框的完整过程。 2. 引用[3]提到了安装OpenCV-Python包的方法,特别是针对树莓派等ARM架构的解决方案(提供了whl文件的链接)。 3. 引用[4]则涉及更高级的人脸特征点检测(68个点)以及Delaunay三角剖分,这需要额外的dlib库和预训练模型。 用户当前的问题是询问使用OpenCV-Python进行人脸检测的方法和教程。因此,我们将重点放在基础的人脸检测方法上,提供清晰的步骤和代码示例。 ### 步骤概述: 1. **安装OpenCV-Python**:使用pip安装,注意根据系统选择合适的版本。 2. **准备人脸检测模型**:OpenCV提供了预训练的Haar级联分类器,需要下载对应的XML文件(例如`haarcascade_frontalface_default.xml`)。 3. **读取图像并转换灰度**:人脸检测通常在灰度图像上进行。 4. **使用分类器检测人脸**:调用`detectMultiScale`方法。 5. **在图像上标注检测到的人脸**:用矩形框标出人脸位置。 6. **显示结果**。 ### 详细教程与代码示例: #### 1. 安装OpenCV-Python 在命令行中使用pip安装: ```bash pip install opencv-python ``` 如果是在树莓派等ARM设备上,可能需要从特定源安装,如引用[3]中提供的whl文件。 #### 2. 下载Haar级联分类器文件 OpenCV提供了多个预训练的人脸检测模型,这些XML文件通常包含在OpenCV的源码中。也可以从OpenCV的GitHub仓库下载: [https://github.com/opencv/opencv/tree/master/data/haarcascades](https://github.com/opencv/opencv/tree/master/data/haarcascades) 常用的有`haarcascade_frontalface_default.xml`(正面人脸)和`haarcascade_frontalface_alt2.xml`(更精确的正面人脸)等。 #### 3. 代码实现 以下是一个完整的人脸检测代码示例(基于引用[2]并做了适当调整和注释): ```python import cv2 # 加载人脸级联分类器 face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') # 注意:如果直接使用文件路径,请确保路径正确。也可以将下载的XML文件放在项目目录下,然后使用路径(如'haarcascade_frontalface_default.xml') # 读取图像 img = cv2.imread('path_to_your_image.jpg') # 替换为你的图片路径 # 转换为灰度图 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 检测人脸 # 参数说明:scaleFactor(每次图像缩小的比例,大于1),minNeighbors(每个候选矩形应保留的邻近个数,用于过滤噪声) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5) # 在图像上绘制矩形框 for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) # 绿色矩形框,线宽为2 # 显示结果 cv2.imshow('Detected Faces', img) cv2.waitKey(0) # 按任意键关闭窗口 cv2.destroyAllWindows() ``` #### 参数调整说明: - `scaleFactor`:该参数指定图像缩放的比例,以检测不同大小的人脸。通常设置为1.05到1.5之间,值越小检测越慢但更精确。 - `minNeighbors`:控制检测框的合并,值越大则检测框越少(要求更高的置信度),但可能漏检;值越小则检测框越多,但可能有噪声。 #### 4. 运行代码 确保图片路径正确,并且XML文件已正确加载(建议将XML文件放在代码同一目录下,或使用绝对路径)。如果遇到分类器加载失败的问题,请检查文件路径。 ### 注意事项: - 如果检测效果不佳,可以尝试使用不同的Haar分类器(如`haarcascade_frontalface_alt2.xml`)或调整参数。 - 对于复杂场景(如多人脸、遮挡、侧脸等),Haar级联检测器可能效果有限,此时可以考虑使用深度学习方法(如OpenCV中的DNN模块或dlib库)。 ### 进阶学习: - 引用[4]展示了使用dlib库进行68个人脸特征点检测,这需要安装dlib并下载预训练模型(`shape_predictor_68_face_landmarks.dat`)。这属于人脸检测的进阶应用,可用于人脸对齐、表情识别等。 §§相关问题§§ 1. 如何提高OpenCV人脸检测的准确率? 2. 除了Haar级联分类器,OpenCV还有哪些人脸检测方法? 3. 如何在视频流中进行实时人脸检测? </think> ### OpenCV-Python 人脸检测方法与教程 #### 一、核心方法 OpenCV 人脸检测主要使用 Haar 级联分类器,其原理是通过训练好的 XML 文件识别图像中的面部特征。核心步骤包括: 1. **加载级联分类器**:使用预训练的 Haar 特征模型 2. **图像预处理**:转换为灰度图减少计算量 3. **多尺度检测**:`detectMultiScale()` 方法处理不同尺寸的人脸 4. **结果绘制**:在检测到的人脸位置绘制矩形框 #### 二、完整代码示例 ```python import cv2 # 加载人脸检测器(需下载XML文件) face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') # 读取图像 img = cv2.imread('person.jpg') # 替换为你的图片路径 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转为灰度图 # 人脸检测(关键参数说明) # scaleFactor: 图像缩放比例 (1.01-1.5) # minNeighbors: 检测框合并阈值 (3-6) # minSize: 最小人脸尺寸 (30,30) 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), (0, 255, 0), 2) # 绘制绿色矩形框 # 显示结果 cv2.imshow('Face Detection', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` #### 三、关键资源 1. **预训练模型下载**: - 官方 Haar 模型库:[GitHub/opencv/data](https://github.com/opencv/opencv/tree/master/data/haarcascades) - 常用模型文件: - `haarcascade_frontalface_default.xml`(基础正面人脸- `haarcascade_frontalface_alt2.xml`(改进版) - `haarcascade_profileface.xml`(侧面人脸) 2. **安装指南**: ```bash pip install opencv-python # 基础包 pip install opencv-contrib-python # 包含额外模块 ``` 树莓派等 ARM 设备可安装预编译包: ```bash pip install https://www.piwheels.org/simple/opencv-python/opencv_python-4.5.1.48-cp37-cp37m-linux_armv7l.whl ``` #### 四、参数优化建议 | 参数 | 推荐值 | 作用 | |-------|---------|------| | `scaleFactor` | 1.05-1.3 | 控制图像金字塔缩放 | | `minNeighbors` | 3-6 | 过滤误检测(值越大越严格) | | `minSize` | (30,30) | 最小人脸尺寸 | | `maxSize` | 不设置 | 不限制最大尺寸 | #### 五、进阶技巧 1. **提升检测精度**: ```python # 使用更精确的模型 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml') # 添加边缘保留滤波 gray = cv2.bilateralFilter(gray, 9, 75, 75) ``` 2. **实时视频检测**: ```python cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.2, 5) # ...绘制检测框... cv2.imshow('Live Detection', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break ``` 3. **人脸特征点检测**(需 dlib 库): ```python import dlib predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") landmarks = predictor(image, face_region) ``` > 提示:复杂场景建议使用深度学习方法(如 SSD、YOLO),但 Haar 级联在 CPU 设备上仍有速度优势[^1][^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值