微信圣诞帽:OpenCV 库Linux下c++实现
所需依赖
- 编译opencv2
- g++编译器
- 前置摄像头完好
Opencv haarcascades文件简介
在搜索人脸检测的资料时,直接调用haarcascade_frontalface_alt.xml之类的文件,这个.xml是Opencv内训练好的人脸检测分类器,所在位置为OpenCV安装位置\sources\data\haarcascades\。
haar feather-based cascade classifier for object detection 是由paul viola提出,由rainer lienhart改进。首先,分类器是由数千个一致尺寸的特定物体我们称为正例和反例训练出来。在分类器训练以后,可以用来对一幅图像的区域作出检测。分类器如果检测到该物体跟训练物体类似就输出1,否则输出0。
在一幅图像中搜索目标,可以在图像上移动整个搜索窗口。分类器设计成很容易改变尺寸,这比改变图像的尺寸效率更高。所以要在一幅图像中找到未知尺寸的物体,需要对不同的比例作多次扫描。
编译链接运行
root@master:/home/hanss# g++ -I/usr/local/opencv2/include/ -o giveCap giveCap.cpp -L/usr/local/opencv2/lib -lopencv_objdetect -lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_imgproc -lopencv_flann -lopencv_core -lopencv_nonfree
root@master:/home/hanss# ./giveCap
源代码
giveCap.cpp注意改变自己opencv库的位置,我自己电脑上是/usr/local/opencv2
#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;
//g++ -I/usr/local/opencv2/include/ -o giveCap giveCap.cpp -L/usr/local/opencv2/lib -lopencv_objdetect -lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_imgproc -lopencv_flann -lopencv_core -lopencv_nonfree
#pragma comment(lib,"opencv_core2410d.lib")
#pragma comment(lib,"opencv_highgui2410d.lib")
#pragma comment(lib,"opencv_objdetect2410d.lib")
#pragma comment(lib,"opencv_imgproc2410d.lib")
/** Function Headers */
void detectAndDisplay( Mat frame );
/** Global variables */
//-- Note, either copy these two files from opencv/data/haarscascades to your current folder, or change these locations
String face_cascade_name = "/usr/local/opencv2/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "/usr/local/opencv2/share/OpenCV/haarcascades/haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
string window_name = "Capture - Face detection";
RNG rng(12345);
const int FRAME_WIDTH = 1280;
const int FRAME_HEIGHT = 240;
/**
* @function main
*/
int main(int argc, char const *argv[])
{
CvCapture* capture;
Mat frame;
//-- 1. Load the cascades
if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
VideoCapture cap(0);
if(!cap.isOpened())
return -1;
Mat edges;
for(;;)
{
Mat frame;
cap >> frame;
detectAndDisplay( frame );
//imshow("edges", frame);
if(waitKey(30) >= 0) break;
}
waitKey(0);
return 0;
}
void mapToMat(const cv::Mat &srcAlpha, cv::Mat &dest, int x, int y)
{
int nc = 3;
int alpha = 0;
for (int j = 0; j < srcAlpha.rows; j++)
{
for (int i = 0; i < srcAlpha.cols*3; i += 3)
{
alpha = srcAlpha.ptr<uchar>(j)[i / 3*4 + 3];
if(alpha != 0)
{
for (int k = 0; k < 3; k++)
{
// if (src1.ptr<uchar>(j)[i / nc*nc + k] != 0)
if( (j+y < dest.rows) && (j+y>=0) &&
((i+x*3) / 3*3 + k < dest.cols*3) && ((i+x*3) / 3*3 + k >= 0) &&
(i/nc*4 + k < srcAlpha.cols*4) && (i/nc*4 + k >=0) )
{
dest.ptr<uchar>(j+y)[(i+x*nc) / nc*nc + k] = srcAlpha.ptr<uchar>(j)[(i) / nc*4 + k];
}
}
}
}
}
}
/**
* @function detectAndDisplay
*/
void detectAndDisplay( Mat frame )
{
std::vector<Rect> faces;
Mat frame_gray;
Mat hatAlpha;
hatAlpha = imread("2.png",-1);
cvtColor( frame, frame_gray, COLOR_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
//-- Detect faces
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_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 );
Mat faceROI = frame_gray( faces[i] );
std::vector<Rect> eyes;
//-- In each face, detect eyes
eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_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 ), 3, 8, 0 );
}
resize(hatAlpha,hatAlpha,Size(faces[i].width, faces[i].height),0,0,INTER_LANCZOS4);
mapToMat(hatAlpha,frame,faces[i].x,faces[i].y-0.8*faces[i].height);
}
//-- Show what you got
imshow( window_name, frame );
imwrite("merry christmas.jpg",frame);
}