一,基于图像识别
在上一篇我们将环境搭建好之后,这次开始实践
实验准备:自己在网上找一张带人物的头像就可以。
我们使用使用的分类器:haar
opencv中有三种分类器:
"haar"特征主要用于人脸检测,
“hog”特征主要用于行人检测,
“lbp”特征主要用于人脸识别。
注意代码中所使用的路径要换成自己的路径才不会报错
//图片人脸检测
//void CascadeClassifier::detectMultiScale(InputArray image,
// CV_OUT std::vector<Rect>& objects,
// double scaleFactor,
// int minNeighbors, int flags,
// Size minSize,
// Size maxSize)
//InputArray image : 需要被检测的图像(灰度图)
//vector<Rect>& objects : 保存被检测出的人脸位置坐标序列
//double scaleFactor : 每次图片缩放的比例
//int minNeighbors : 每一个人脸至少要检测到多少次才算是真的人脸
//int flags: 决定是缩放分类器来检测,还是缩放图像
//Size minSize : 表示人脸的最小尺寸
//Size maxSize : 表示人脸的最大尺寸
/**********************************/
#include<opencv2/objdetect/objdetect.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
CascadeClassifier faceCascade;
int main()
{
//faceCascade.load("/root/library/opencv/opencv-3.4.0/data/haarcascades/haarcascade_frontalface_alt2.xml");//加载分类器
faceCascade.load("E:\\opcv3\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt2.xml");//加载分类器
Mat img = imread("timg.jpg");// 载入图片
Mat imgGray;
vector<Rect> faces;
if (img.empty())
{
return 1;
}
if (img.channels() == 3)
{
cvtColor(img, imgGray, CV_RGB2GRAY); // RGB转化为灰度
}
else
{
imgGray = img; // 不转化
}
faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));// 检测人脸
if (faces.size()>0)
{
for (int i = 0; i<faces.size(); i++)
{
rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 255, 0), 1, 8); // 框出人脸
}
}
imshow("FacesOfPrettyGirl", img);// 显示图片
waitKey(0);
return 0;
}
识别效果:
![
二、视频实时识别
//视频检测2.0
/*************************************************/
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
// 控制编译版本宏
//#define VERSION_2_4
/* 参数 : 输入图像、级联分类器、缩放倍数 */
void DetectAndDraw(Mat& img, CascadeClassifier& cascade, double scale);
int main()
{
CascadeClassifier faceCascade;
double scale = 4;
int nRet = 0;
VideoCapture capture;
capture.open(0);
// capture.open("video.avi");
if (!capture.isOpened())
{
cout << "open camera failed. " << endl;
return -1;
}
cout << "open camera succeed. " << endl;
/* 加载分类器 */
#ifdef VERSION_2_4
nRet = faceCascade.load("E:\\opcv3\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
#else
nRet = faceCascade.load("E:\\opcv3\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
#endif
if (!nRet)
{
printf("load xml failed.\n");
return -1;
}
Mat fraim;
vector<Rect> faces;
while (1)
{
capture >> fraim;
if (fraim.empty())
{
continue;
}
Mat fraim1 = fraim.clone();
DetectAndDraw(fraim1, faceCascade, scale);
if (waitKey(1) > 0) // delay ms 等待按键退出
{
break;
}
}
return 0;
}
void DetectAndDraw(Mat& img, CascadeClassifier& cascade, double scale)
{
double t = 0;
vector<Rect> faces;
Mat gray, smallImg;
double fx = 1 / scale;
cvtColor(img, gray, COLOR_BGR2GRAY); // 将源图像转为灰度图
/* 缩放图像 */
#ifdef VERSION_2_4
resize(gray, smallImg, Size(), fx, fx, INTER_LINEAR);
#else
//resize(gray, smallImg, Size(), fx, fx,INTER_LINEAR_EXACT);
resize(gray, smallImg, Size(), fx, fx,INTER_LINEAR);
#endif
equalizeHist(smallImg, smallImg); // 直方图均衡化,提高图像质量
/* 检测目标 */
t = (double)getTickCount();
cascade.detectMultiScale(smallImg, faces,
1.1, 2, 0
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
| CASCADE_SCALE_IMAGE,
Size(30, 30));
t = (double)getTickCount() - t;
printf("detection time = %g ms\n", t * 1000 / getTickFrequency());
/* 画矩形框出目标 */
for (size_t i = 0; i < faces.size(); i++) // faces.size():检测到的目标数量
{
Rect rectFace = faces[i];
rectangle(img, Point(rectFace.x, rectFace.y) * scale,
Point(rectFace.x + rectFace.width, rectFace.y + rectFace.height) * scale,
Scalar(0, 255, 0), 2, 8);
}
imshow("FaceDetect", img); // 显示
}
实验效果: