前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >人脸识别初探之人脸检测(一)

人脸识别初探之人脸检测(一)

作者头像
用户9831583
发布2022-06-16 14:08:48
8.7K0
发布2022-06-16 14:08:48
举报
文章被收录于专栏:码出名企路

还记的这篇OpenCV即时上手可学习可商用的项目

接下来准备把其中的代码公开,欢迎一起交流学习

人脸识别是个说小不小的工程,在完成这个项目之前,先把人脸检测熟悉一下。人脸检测用到的函数如下:

代码语言:javascript
复制
 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() );
 

Opencv中给出了四种人脸训练模型如下:

代码语言:javascript
复制
1.haarcascade_frontalface_alt.xml

2.haarcascade_frontalface_alt_tree.xml

3.haarcascade_frontalface_alt2.xml

4.haarcascade_frontalface_default.xml

图片中的人脸检测:

代码语言:javascript
复制

#include<opencv2/opencv.hpp>
#include<iostream>
 
using namespace std;
using namespace cv;
 
int main(int argc,char *argv[])
{
  Mat img = imread("../img/2.png");
  namedWindow("display");
  imshow("display", img);
  
  /*********************************** 1.加载人脸检测器  ******************************/
  // 建立级联分类器
  CascadeClassifier cascade;
  // 加载训练好的 人脸检测器(.xml)
  //const string path = "../haarcascades/haarcascade_frontalface_alt.xml";
  //还有两种模型自己检测
    const string path = "../haarcascades/haarcascade_frontalface_default.xml";
    //友好错误信息提示
  try{
    cascade.load(path);
  }
  catch (cv::Exception e){}
  if (cascade.empty())
  {
    std::cerr << "脸部检测器不能加载 (";
    std::cerr << path << ")!" << std::endl;
    exit(1);
  }

  //计时
  double t = 0;
  t = (double)getTickCount();
  /*********************************** 2.人脸检测 ******************************/
  vector<Rect> faces(0);
  cascade.detectMultiScale(img, faces, 1.1, 2, 0 ,Size(30,30));
 
  cout << "detect face number is :" << faces.size() << endl;
  /********************************  3.显示人脸矩形框 ******************************/
  
  if (faces.size() > 0)
  {
    for (size_t i = 0;i < faces.size();i++)
    {
      rectangle(img, faces[i], Scalar(150, 0, 0), 3, 8, 0);
 
    }
  }
  else cout << "未检测到人脸" << endl;
 
  t = (double)getTickCount() - t;  //getTickCount():  Returns the number of ticks per second.
  cout << "检测人脸用时:" << t * 1000 / getTickFrequency() << "ms (不计算加载模型的时间)" << endl;
 
  namedWindow("face_detect");
  imshow("face_detect", img);
  while(waitKey(0)!='k') ;
  destroyWindow("display");
  destroyWindow("face_detect");
    return 0;
}

效果如图:

打开相机进行人脸检测:

代码语言:javascript
复制
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
 
using namespace cv;
using namespace std;

void Pic2Gray(Mat camerFrame,Mat &gray)
{
  //普通台式机3通道BGR,移动设备为4通道
  if (camerFrame.channels() == 3)
  {
    cvtColor(camerFrame, gray, CV_BGR2GRAY);
  }
  else if (camerFrame.channels() == 4)
  {
    cvtColor(camerFrame, gray, CV_BGRA2GRAY);
  }
  else
    gray = camerFrame;
}
 
 
int main()
{
  //加载Haar或LBP对象或人脸检测器
  CascadeClassifier faceDetector;
  std::string faceCascadeFilename = "../haarcascades/haarcascade_frontalface_default.xml";

   if ( ! faceDetector.load(faceCascadeFilename))
  {
    cout << "cascade load failed!\n";
  }

   if ( ! eyes_cascade.load(faceCascadeFilename))
  {
    cout << "cascade load failed!\n";
  }
 
  //打开摄像头
  VideoCapture camera(0);
  while (true)
  {
    Mat camerFrame;
    camera >> camerFrame;
    if (camerFrame.empty())
    {
      std::cerr << "无法获取摄像头图像" << std::endl;
      getchar();
      exit(1);
    }
    Mat displayedFrame(camerFrame.size(),CV_8UC3);
 
 
    //人脸检测只试用于灰度图像
    Mat gray;
    Pic2Gray(camerFrame, gray);
 
    //直方图均匀化(改善图像的对比度和亮度)
    Mat equalizedImg;
    equalizeHist(gray, equalizedImg);
 
    //人脸检测用Cascade Classifier::detectMultiScale来进行人脸检测
 
    int flags = CASCADE_FIND_BIGGEST_OBJECT|CASCADE_DO_ROUGH_SEARCH;  //只检测脸最大的人
    //int flags = CASCADE_SCALE_IMAGE;  //检测多个人
    Size minFeatureSize(30, 30);
    float searchScaleFactor = 1.1f;
    int minNeighbors = 4;
    std::vector<Rect> faces;
    faceDetector.detectMultiScale(equalizedImg, faces, searchScaleFactor, minNeighbors, flags, minFeatureSize);
 
    //画矩形框
    cv::Mat face;
    cv::Point text_lb;
    for (size_t i = 0; i < faces.size(); i++)
    {

        
      if (faces[i].height > 0 && faces[i].width > 0)
      {
    
        cv::rectangle(equalizedImg, faces[i], cv::Scalar(255, 0, 0), 1, 8, 0);
        cv::rectangle(gray, faces[i], cv::Scalar(255, 0, 0), 1, 8, 0);
        cv::rectangle(camerFrame, faces[i], cv::Scalar(0, 255, 0), 1, 8, 0);
      }

    }
 
 
    imshow("junyihua", equalizedImg);
    imshow("huidu", gray);
    imshow("yuantu", camerFrame);
 
    waitKey(20);
  }
 
  getchar();
  return 0;
}

效果如下:

涉及到个人隐私,还是不贴图了巴拉巴拉

另外补充人脸+眼睛检测:

代码语言:javascript
复制
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"

#include <stdio.h>

using namespace std;
using namespace cv;

/** Function Headers */
void detectAndDisplay(Mat frame);

/** Global variables */
String face_cascade_name, eyes_cascade_name;
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
String window_name = "Capture - Face detection";

/** @function main */
int main(int argc, const char** argv)
{
  face_cascade_name = "../haarcascades/haarcascade_frontalface_default.xml";
  eyes_cascade_name = "../haarcascades/haarcascade_eye_tree_eyeglasses.xml";
  VideoCapture capture;
  Mat frame;

  //-- 1. Load the cascades
  if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading face cascade\n"); return -1; };
  if (!eyes_cascade.load(eyes_cascade_name)) { printf("--(!)Error loading eyes cascade\n"); return -1; };

  //-- 2. Read the video stream
  capture.open(0); //打开摄像头
  if (!capture.isOpened()) { printf("--(!)Error opening video capture\n"); return -1; }

  while (capture.read(frame)) //读取帧
  {
    if (frame.empty())
    {
      printf(" --(!) No captured frame -- Break!");
      break;
    }

    //-- 3. Apply the classifier to the frame
    detectAndDisplay(frame);

    if (waitKey(10) == 'k') { break; } // escape
  }
  return 0;
}

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

  cvtColor(frame, frame_gray, COLOR_BGR2GRAY);  //BGR 转化为灰度图
  equalizeHist(frame_gray, frame_gray);   //直方图均衡化

  //-- Detect faces
  face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(60, 60));

  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), 4, 8, 0); // 椭圆

    Mat faceROI = frame_gray(faces[i]);
    std::vector<Rect> eyes;

    //-- In each face, detect eyes
    eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));

    for (size_t j = 0; j < eyes.size(); j++)
    {
      Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2); //眼睛的中心
      int radius = cvRound((eyes[j].width + eyes[j].height)*0.25); //取整
      circle(frame, eye_center, radius, Scalar(255, 0, 0), 4, 8, 0);
    }
  }
  //-- Show what you got
  imshow(window_name, frame);
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档