opencv实践项目-人脸检测

这篇具有很好参考价值的文章主要介绍了opencv实践项目-人脸检测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. opencv CascadeClassifier人脸检测步骤

  • 从文件加载级联分类器
  • 读取图片并灰度化
  • resize灰度图
  • 直方图均衡化,得到对比度更强的输出图像
  • detectMultiScale检测

2. CascadeClassifier分类器简介

分类器是判别某个事物是否属于某种分类的器件,其结果要么是,要么不是,级联分类器,可以理解为将 N 个单类的分类器串联起来,如果一个事物能属于这一系列串联起来的的所有分类器,则最终结果就成立,若有一项不符,则判定为不成立。比如人脸,它有很多属性,我们将每个属性做一成个分类器,如果一个模型符合了我们定义的人脸的所有属性,则我们人为这个模型就是一个人脸,比如人脸需要有两条眉毛,两只眼睛,一个鼻子,一张嘴,一个大概 U 形状的下巴或者是轮廓等等。

常用方法:

2.1 从文件中加载级联分类器

CV_WRAP bool load( const String& filename );

也可用于判断级联分类器是否加载成功

2.2 目标检测方法

CV_WRAP void detectMultiScale( InputArray image, 
CV_OUT std::vector<Rect>& objects, 
double scaleFactor = 1.1, 
int minNeighbors = 3, int flags = 0, 
Size minSize = Size(), 
Size maxSize = Size() ); 

功能:检测输入图像中不同大小的对象。检测到的对象以矩形列表的形式保存
参数:
image: 包含检测对象的图像的 CV_8U 类型矩阵
objects: 矩形的向量,其中每个矩形包含被检测的对象,矩形可以部分位于原始图像之外
scaleFactor: 指定在每个图像缩放时的缩放比例
minNeighbors:指定每个候选矩形需要保留多少个相邻矩形
flags:含义与函数 cvHaarDetectObjects 中的旧级联相同,一般是 0,它不用于新的级联
minSize:对象最小大小,小于该值的对象被忽略
maxSize:最大可能的对象大小,大于这个值的对象被忽略
返回值:无

3. 代码实现

#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/core/ocl.hpp"
#include <iostream>

using namespace std;
using namespace cv;

static void help()
{
    cout << "\nThis program demonstrates the cascade recognizer. Now you can use Haar or LBP features.\n"
            "This classifier can recognize many kinds of rigid objects, once the appropriate classifier is trained.\n"
            "It's most known use is for faces.\n"
            "Usage:\n"
            "./ufacedetect [--cascade=<cascade_path> this is the primary trained classifier such as frontal face]\n"
               "   [--nested-cascade[=nested_cascade_path this an optional secondary classifier such as eyes]]\n"
               "   [--scale=<image scale greater or equal to 1, try 1.3 for example>]\n"
               "   [--try-flip]\n"
               "   [filename|camera_index]\n\n"
            "see facedetect.cmd for one call:\n"
            "./ufacedetect --cascade=\"../../data/haarcascades/haarcascade_frontalface_alt.xml\" --nested-cascade=\"../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml\" --scale=1.3\n\n"
            "During execution:\n\tHit any key to quit.\n"
            "\tUsing OpenCV version " << CV_VERSION << "\n" << endl;
}

void detectAndDraw( UMat& img, Mat& canvas, CascadeClassifier& cascade,
                    CascadeClassifier& nestedCascade,
                    double scale, bool tryflip );

int main( int argc, const char** argv )
{
    VideoCapture capture;
    UMat frame, image;
    Mat canvas;

    string inputName;
    bool tryflip;

    CascadeClassifier cascade, nestedCascade;
    double scale;

    cv::CommandLineParser parser(argc, argv,
        "{cascade|data/haarcascades/haarcascade_frontalface_alt.xml|}"
        "{nested-cascade|data/haarcascades/haarcascade_eye_tree_eyeglasses.xml|}"
        "{help h ||}{scale|1|}{try-flip||}{@filename||}"
    );
    if (parser.has("help"))
    {
        help();
        return 0;
    }
    string cascadeName = samples::findFile(parser.get<string>("cascade"));
    string nestedCascadeName = samples::findFileOrKeep(parser.get<string>("nested-cascade"));
    scale = parser.get<double>("scale");
    tryflip = parser.has("try-flip");
    inputName = parser.get<string>("@filename");
    if ( !parser.check())
    {
        parser.printErrors();
        help();
        return -1;
    }

    if ( !nestedCascade.load( nestedCascadeName ) )
        cerr << "WARNING: Could not load classifier cascade for nested objects: " << nestedCascadeName << endl;
    if( !cascade.load( cascadeName ) )
    {
        cerr << "ERROR: Could not load classifier cascade: " << cascadeName << endl;
        help();
        return -1;
    }

    cout << "old cascade: " << (cascade.isOldFormatCascade() ? "TRUE" : "FALSE") << endl;

    if( inputName.empty() || (isdigit(inputName[0]) && inputName.size() == 1) )
    {
        int camera = inputName.empty() ? 0 : inputName[0] - '0';
        if(!capture.open(camera))
            cout << "Capture from camera #" <<  camera << " didn't work" << endl;
    }
    else
    {
        inputName = samples::findFileOrKeep(inputName);
        imread(inputName, IMREAD_COLOR).copyTo(image);
        if( image.empty() )
        {
            if(!capture.open( inputName ))
                cout << "Could not read " << inputName << endl;
        }
    }

    if( capture.isOpened() )
    {
        cout << "Video capturing has been started ..." << endl;
        for(;;)
        {
            capture >> frame;
            if( frame.empty() )
                break;

            detectAndDraw( frame, canvas, cascade, nestedCascade, scale, tryflip );

            char c = (char)waitKey(10);
            if( c == 27 || c == 'q' || c == 'Q' )
                break;
        }
    }
    else
    {
        cout << "Detecting face(s) in " << inputName << endl;
        if( !image.empty() )
        {
            detectAndDraw( image, canvas, cascade, nestedCascade, scale, tryflip );
            waitKey(0);
        }
        else if( !inputName.empty() )
        {
            /* assume it is a text file containing the
            list of the image filenames to be processed - one per line */
            FILE* f = fopen( inputName.c_str(), "rt" );
            if( f )
            {
                char buf[1000+1];
                while( fgets( buf, 1000, f ) )
                {
                    int len = (int)strlen(buf);
                    while( len > 0 && isspace(buf[len-1]) )
                        len--;
                    buf[len] = '\0';
                    cout << "file " << buf << endl;
                    imread(samples::findFile(buf), IMREAD_COLOR).copyTo(image);
                    if( !image.empty() )
                    {
                        detectAndDraw( image, canvas, cascade, nestedCascade, scale, tryflip );
                        char c = (char)waitKey(0);
                        if( c == 27 || c == 'q' || c == 'Q' )
                            break;
                    }
                    else
                    {
                        cerr << "Aw snap, couldn't read image " << buf << endl;
                    }
                }
                fclose(f);
            }
        }
    }

    return 0;
}

void detectAndDraw( UMat& img, Mat& canvas, CascadeClassifier& cascade,
                    CascadeClassifier& nestedCascade,
                    double scale, bool tryflip )
{
    double t = 0;
    vector<Rect> faces, faces2;
    const static Scalar colors[] =
    {
        Scalar(255,0,0),
        Scalar(255,128,0),
        Scalar(255,255,0),
        Scalar(0,255,0),
        Scalar(0,128,255),
        Scalar(0,255,255),
        Scalar(0,0,255),
        Scalar(255,0,255)
    };
    static UMat gray, smallImg;

    t = (double)getTickCount();

    cvtColor( img, gray, COLOR_BGR2GRAY );
    double fx = 1 / scale;
    resize( gray, smallImg, Size(), fx, fx, INTER_LINEAR_EXACT );
    equalizeHist( smallImg, smallImg );

    cascade.detectMultiScale( smallImg, faces,
        1.1, 3, 0
        //|CASCADE_FIND_BIGGEST_OBJECT
        //|CASCADE_DO_ROUGH_SEARCH
        |CASCADE_SCALE_IMAGE,
        Size(30, 30) );
    if( tryflip )
    {
        flip(smallImg, smallImg, 1);
        cascade.detectMultiScale( smallImg, faces2,
                                 1.1, 2, 0
                                 //|CASCADE_FIND_BIGGEST_OBJECT
                                 //|CASCADE_DO_ROUGH_SEARCH
                                 |CASCADE_SCALE_IMAGE,
                                 Size(30, 30) );
        for( vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); ++r )
        {
            faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));
        }
    }
    t = (double)getTickCount() - t;
    img.copyTo(canvas);

    double fps = getTickFrequency()/t;
    static double avgfps = 0;
    static int nframes = 0;
    nframes++;
    double alpha = nframes > 50 ? 0.01 : 1./nframes;
    avgfps = avgfps*(1-alpha) + fps*alpha;

    putText(canvas, format("OpenCL: %s, fps: %.1f", ocl::useOpenCL() ? "ON" : "OFF", avgfps), Point(50, 30),
            FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0,255,0), 2);

    for ( size_t i = 0; i < faces.size(); i++ )
    {
        Rect r = faces[i];
        vector<Rect> nestedObjects;
        Point center;
        Scalar color = colors[i%8];
        int radius;

        double aspect_ratio = (double)r.width/r.height;
        if( 0.75 < aspect_ratio && aspect_ratio < 1.3 )
        {
            center.x = cvRound((r.x + r.width*0.5)*scale);
            center.y = cvRound((r.y + r.height*0.5)*scale);
            radius = cvRound((r.width + r.height)*0.25*scale);
            circle( canvas, center, radius, color, 3, 8, 0 );
        }
        else
            rectangle( canvas, Point(cvRound(r.x*scale), cvRound(r.y*scale)),
                       Point(cvRound((r.x + r.width-1)*scale), cvRound((r.y + r.height-1)*scale)),
                       color, 3, 8, 0);
        if( nestedCascade.empty() )
            continue;
        UMat smallImgROI = smallImg(r);
        nestedCascade.detectMultiScale( smallImgROI, nestedObjects,
            1.1, 2, 0
            //|CASCADE_FIND_BIGGEST_OBJECT
            //|CASCADE_DO_ROUGH_SEARCH
            //|CASCADE_DO_CANNY_PRUNING
            |CASCADE_SCALE_IMAGE,
            Size(30, 30) );

        for ( size_t j = 0; j < nestedObjects.size(); j++ )
        {
            Rect nr = nestedObjects[j];
            center.x = cvRound((r.x + nr.x + nr.width*0.5)*scale);
            center.y = cvRound((r.y + nr.y + nr.height*0.5)*scale);
            radius = cvRound((nr.width + nr.height)*0.25*scale);
            circle( canvas, center, radius, color, 3, 8, 0 );
        }
    }
    imshow( "result", canvas );
}

该代码为官方示例代码,基本调用方法如下:

example_tapi_ufacedetect --cascade=D:\wyw\opencv\opencv-4.5.0\data\haarcascades\haarcascade_frontalface_alt.xml --nested-cascade=D:\wyw\opencv\opencv-4.5.0\data\haarcascades\haarcascade_eye_tree_eyeglasses.xml --scale=1 --try-flip=true E:\code\other\SeetaFaceDetector\FaceDetector\x64\Release\6.jpg

本文部分引用:https://zhuanlan.zhihu.com/p/159013461文章来源地址https://www.toymoban.com/news/detail-464120.html

到了这里,关于opencv实践项目-人脸检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • openCV实践项目:图片文本检测

    上一期我们通过对实验:银行卡卡号识别 加深了对前面所学openCV图像处理的一些理解 openCV实践项目:银行卡卡号识别_老师我作业忘带了的博客-CSDN博客 本次图片文本检测相对于要容易一些,内容如下:   把一个这样的图片,通过仿射变换转换成那样的图片。 然后再通过

    2024年02月07日
    浏览(39)
  • 手把手教你完成一个Python与OpenCV人脸识别项目(对图片、视频、摄像头人脸的检测)超详细保姆级记录!

    课程来源: 一天搞定人脸识别项目!学不会up直接下跪!(python+opencv)_哔哩哔哩_bilibili 环境配置详见: 在conda虚拟环境中安装OpenCv并在pycharm中使用_conda虚拟环境安装opencv_好喜欢吃红柚子的博客-CSDN博客 目录 一、读取图片 1.1 imshow和WaitKey方法   1.2 代码实现 1.3 效果展示 

    2024年02月03日
    浏览(37)
  • OpenCV实践小项目(三) - 停车场车位实时检测

    今天整理OpenCV入门的第三个实战小项目,前面的两篇文章整理了信用卡数字识别以及文档OCR扫描, 大部分用到的是OpenCV里面的基础图像预处理技术,比如轮廓检测,边缘检测,形态学操作,透视变换等, 而这篇文章的项目呢,不仅需要一些基础的图像预处理,还需要搭建模

    2024年02月07日
    浏览(41)
  • 头歌--人脸识别系统--OpenCV人脸检测

    目录 第1关:图片基本操作 第2关:色彩空间及其转换 第3关:基于Harr特征的人脸检测分类器 第4关:绘制人脸与人眼区域 第1关:图片基本操作 第2关:色彩空间及其转换 第3关:基于Harr特征的人脸检测分类器 第4关:绘制人脸与人眼区域

    2024年02月05日
    浏览(51)
  • 人脸检测实战:使用opencv加载深度学习模型实现人脸检测(1)

    import argparse import cv2 ap = argparse.ArgumentParser() ap.add_argument(“-i”, “–image”, required=True, help=“path to input image”) ap.add_argument(“-p”, “–prototxt”, required=True, help=“path to Caffe ‘deploy’ prototxt file”) ap.add_argument(“-m”, “–model”, required=True, help=“path to Caffe pre-trained model”)

    2024年04月16日
    浏览(56)
  • Qt+Opencv:人脸检测

    话接上一篇,我们仍使用在上篇《Qt+Opencv:Qt中部署opencv》创建的Qt项目来测试opencv提供的sample。 在正式开始本篇之前,我们先说做一下准备工作: 学习最权威和最可靠的方式,就是阅读官方文档和实践模块samples。同样,opencv的文档个人觉得做的还是可以的,当然,相对于我

    2024年02月03日
    浏览(35)
  • 018 OpenCV 人脸检测

    目录 一、环境 二、分类器原理 2.1、概述 2.2、工作原理 三、人脸检测代码 本文使用环境为: Windows10 Python 3.9.17 opencv-python 4.8.0.74 CascadeClassifier是OpenCV(开源计算机视觉库)中的一个强大的类,用于实现级联分类器。这是一种机器学习技术,广泛应用于面部检测、物体识别等

    2024年02月04日
    浏览(29)
  • OpenCV实例(一)人脸检测

    作者:Xiou 计算机视觉使很多任务成为现实,其中两项任务就是人脸检测(在图像中定位人脸)和人脸识别(将人脸识别为特定的人)。OpenCV实现了一些人脸检测和识别的算法。从安全到娱乐,这些技术在现实环境中都有应用。 介绍OpenCV的一些人脸检测和识别功能,并定义特

    2024年02月09日
    浏览(34)
  • opencv/C++ 人脸检测

    本文使用的测试资源说明: opencv版本:opencv 4.6.0 Haar特征分类器是一个XML文件,描述了人体各个部位的Haar特征值。包括:人脸、眼睛、鼻子、嘴等。 opencv 4.6.0自带的Haar特征分类器,包括: haarcascade_frontalface_alt.xml haarcascade_frontalface_alt2.xml 注:识别人体其它部位,只需替换对

    2024年02月11日
    浏览(30)
  • 人工智能-OpenCV+Python实现人脸识别(人脸检测)

    在OpenCV中使用Haar特征检测人脸,那么需要使用OpenCV提供的xml文件(级联表)在haarcascades目录下。这张级联表有一个训练好的AdaBoost训练集。首先要采用样本的Haar特征训练分类器,从而得到一个级联的AdaBoost分类器。Haar特征值反映了图像的灰度变化情况。例如:脸部的一些特征

    2024年02月06日
    浏览(99)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包