Opencv之级联分类器(一):进行人脸检测

Opencv之级联分类器(一):进行人脸检测

武汉加油,中国加油

记录学习,交流共进
检测图片放一放:
在这里插入图片描述
因为任务需要,想把传统的识别算法与深度学习的算法进行比较,所以,就拿级联分类器入手咯,来看一看具体的差别。
以前只是听说传统算法精度不高,寻找特征麻烦,亲自动手尝试了一下,哎呀,额的个娘来,喂入相同样本的情况下,两者之间的差别不是一点两点,因为一开始没有用到GPU,所以实时检测的速度还不如深度学习检测的速度,过程中碰到的坑倒不少。
后面发现其实官方也提供cuda相关的分类器,换成cuda相关分类器后速度提高了一点点,这个大家可以自行测试一下
级联分类器分两部分来写,这一部分是利用官方已经训练好的模型进行检测,下一部分自己来训练模型进行检测。

人脸检测程序

VS2017+Opencv3.4.1
使用环境大家可以借鉴一下,因为4.0版本下没有训练器,具体的自行测试吧。
官方在opencv中提供了多个已经训练好的分类器,在opencv安装目录下的source/data中,包含人脸、眼睛、微笑、猫脸等多个分类器,这个可自行调用,这里使用最常见的人脸检测,haarcascade_frontalface_alt.xml。我在代码里注释的很清楚了,应该都能看懂,不懂再问,交流共进。
检测图片:

#include <opencv2/core/core.hpp>
#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;
//定义分类器
CascadeClassifier face_cascade;
//xml文件存在于opencv/source/data下,尽可能使用绝对路径,相对路径会出错
string facexml = "D:\\opencv3.4.1\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_frontalface_alt.xml";
//预处理及识别函数
void detectAndDisplay(Mat frame);
//图片的识别
int main(int argc, char** argv) {
 //读取图片并判断
 Mat image;
 image = imread("C:\\Users\\14587\\Desktop\\4.jpg", 1);
 if (!image.data) {
  printf("can not load image.../n");
  return -1;
 }
 imshow("input_image", image);
 //加载分类器并判断
 if (!face_cascade.load(facexml)) {
  printf("can not load cascade \n");
  return -1;
 } 
 detectAndDisplay(image);
 //调用人脸检测函数 
 waitKey(0); 
 return 0;
}
//预处理及识别函数
void detectAndDisplay(Mat face) {
 std::vector<Rect> faces;
 Mat face_gray;
 //灰度
 cvtColor(face, face_gray, CV_BGR2GRAY);
 //直方图 
 equalizeHist(face_gray, face_gray);
 //人脸识别并用圆框
 face_cascade.detectMultiScale(face_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(1, 1));
 for (int i = 0; i < faces.size(); i++) {
  Point center(faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5);
  ellipse(face, center, Size(faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar(255, 0, 0), 2, 7, 0);
 }
 //识别图片显示
 imshow("out_image", face);
}

摄像头测试:

#include <opencv2/core/core.hpp>
#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;
//定义分类器
CascadeClassifier face_cascade;
//xml文件存在于opencv/source/data下,尽可能使用绝对路径,相对路径会出错
string facexml = "D:\\opencv3.4.1\\opencv\\sources\\data\\haarcascades_cuda\\haarcascade_frontalface_alt.xml";
//预处理及识别函数
void detectAndDisplay(Mat frame);
//图片的识别
int main(int argc, char** argv) {
 VideoCapture cap(0);
 Mat frame;
 //加载分类器并判断
 if (!face_cascade.load(facexml)) {
  printf("can not load cascade \n");
  return -1;
 }
 while (cap.read(frame)) {
  //调用人脸检测函数 
  detectAndDisplay(frame);
  char c = waitKey(15);
  if (c == 27)
  {
   break;
  }
 }
 waitKey(0);
 return 0;
}
void detectAndDisplay(Mat face) {
 std::vector<Rect> faces;
 Mat face_gray;
 //灰度
 cvtColor(face, face_gray, CV_BGR2GRAY);
 //直方图 
 equalizeHist(face_gray, face_gray);
 //人脸识别并用圆框
 face_cascade.detectMultiScale(face_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(1, 1));
 for (int i = 0; i < faces.size(); i++) {
  Point center(faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5);
  ellipse(face, center, Size(faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar(255, 0, 0), 2, 7, 0);
 }
 //识别图片显示
 imshow("out_image", face);
}

在这里插入图片描述

过程中的问题

过程中调试了好半天的问题就是,一定要用绝对路径,不知道什么个情况,把分类器放进项目下,把检测图片放到项目下,都不能用相对路径打开,检测时一闪而过,调试了半天,最后用绝对路径才能打开。
而且调用分类器不成功,它还不报错,谨记谨记。

发布了7 篇原创文章 · 获赞 15 · 访问量 1595

猜你喜欢

转载自blog.csdn.net/weixin_44747240/article/details/104118790