放假期间接着了解opencv里面的东西,之前就有过想调用看看opencv库里面的想法,花了一点点时间了解了一下。笔记较为粗略,读者看得懂就行。
我的想法是通过opencv库里面自带的人脸检测包来给识别出来的人脸做一个类似于市面上的特效软件一样。
opencv自带了17人脸个人脸特征检测包。路径一般都在
/home/sms/opencv4.1.0/data/haarcascades
这个路径下。读者可以自行上网了解一下opencv的各种检测包,包括但不限于人脸检测库。
ok,话不多说。直接开始
1. 要准备的材料:自己做的特效图,待加特效的图片或者视频。完整的opencv库
2然后开始编写我们的程序:
1最开始就是读取所需要的图像:灰度图的效果图及其原图,要加特效的人脸图片
src_img = imread("/home/sms/tu/1.jpg");//要加特效的图片
src2_img = imread("/home/sms/tu/2.png");//特效图
2然后灰度图片
cvtColor(src_img,gray_img,COLOR_RGBA2GRAY);
equalizeHist(gray_img,gray_img);
3首先是读取人脸人脸识别检测器:下面就是人脸检测包的位置
string facades_path = "/home/sms/opencv4.1.0/data/haarcascades/haarcascade_frontalface_alt.xml";//opencv人脸检测xml文件,检测器
下面
4然后常规操作的检查路径
if(!face_cascade.load(facades_path)){
cout<<"打开xml文件路径错误"<<endl;
}
5定义一个人脸检测类的一个对象
CascadeClassifier face_cascade;
6 定义个人Rect的容器来储存识别出来的人脸并进行识别
vector<Rect> faces;
face_cascade.detectMultiScale(gray_img,faces,2.2,3,0,Size(1,1));
7 将识别出来的图片结果和特效图合并在一起:
divi_img是识别出来人脸的部分分出来打ROI区域。
divi_img = src_img(Rect(faces[i].x,faces[i].y,faces[i].size().width,faces[i].size().height));//分离的人脸
然后将图片合并展示,下面打DIVIWINDOW是宏定义的窗口名称,可以自行更改
resize(src2_img,src2_img,Size(divi_img.cols,divi_img.rows*0.5));
cvtColor(src2_img,src2_dst_img,COLOR_RGBA2GRAY);
Mat roi = divi_img(Rect(0,src2_img.rows*0.3,src2_img.cols,src2_img.rows));
src2_img.copyTo(roi,src2_dst_img);
imshow(DIVIWINDOW,divi_img);
最后将原图显示图来就大功告成
然后献上我的fish lese代码
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include<opencv2/objdetect/objdetect.hpp>
#include<control.h>
using namespace std;
using namespace cv;
string facades_path = "/home/sms/opencv4.1.0/data/haarcascades/haarcascade_frontalface_alt.xml";//opencv人脸检测xml文件,检测器
CascadeClassifier face_cascade;
#define img_cap 0 //0打开图片,1打开视频(摄像头)
#define DIVIWINDOW "divi_img"
int main()
{
Mat src_img,src2_img,src2_dst_img,gray_img,divi_img
namedWindow(DIVIWINDOW,WINDOW_AUTOSIZE);
if(!face_cascade.load(facades_path)){
cout<<"打开xml文件路径错误"<<endl;
}
#if img_cap == 0
bool flag = false;
src_img = imread("/home/sms/tu/3.jpg");
// resize(src_img,src_img,Size(660,480));
if(src_img.empty())
{
cout<<"未找到图片位置"<<endl;
}
imshow("srcImage",src_img);
src2_img = imread("/home/sms/tu/2.png");
if(src2_img.empty())
{
cout<<"图片路径错误"<<endl;
}
cvtColor(src_img,gray_img,COLOR_RGBA2GRAY);
equalizeHist(gray_img,gray_img);
face_cascade.detectMultiScale(gray_img,faces,2.2,3,0,Size(1,1));
if(faces.size()!=0)
{
for (size_t i = 0; i < faces.size(); ++i)
{
Scalar color(rand()%255,rand()%255,rand()%255);
rectangle(src_img,faces[i],color,3,8);
divi_img = src_img(Rect(faces[i].x,faces[i].y,faces[i].size().width,faces[i].size().height));//分离的人脸
flag = true;
}
}
if(flag == true)
{
resize(src2_img,src2_img,Size(divi_img.cols,divi_img.rows*0.5));
cvtColor(src2_img,src2_dst_img,COLOR_RGBA2GRAY);
Mat roi = divi_img(Rect(0,src2_img.rows*0.3,src2_img.cols,src2_img.rows));
src2_img.copyTo(roi,src2_dst_img);
imshow(DIVIWINDOW,divi_img);
}
if(flag == true &&faces.size()<=0)
{
flag =false;
destroyWindow(DIVIWINDOW);
}
imshow("src_img",src_img);
cout<<"检测到的人脸个数是"<<faces.size()<<endl;
waitKey(0);
#endif
#if img_cap == 1
Videocapture capture;
bool flag = false;
capture.open(0);
for (;;)
{
src2_img = imread("/home/sms/tu/2.png");
if(src2_img.empty())
{
cout<<"图片路径错误"<<endl;
}
capture>>src_img;
cvtColor(src_img,gray_img,COLOR_RGBA2GRAY);
equalizeHist(gray_img,gray_img);
face_cascade.detectMultiScale(gray_img,faces,1.1,2,0,Size(1,1));
if(faces.size()>0)
{
for (size_t i = 0; i < faces.size(); ++i)
{
rectangle(src_img,faces[i],Scalar(255,255,255),3,8);
divi_img = src_img(Rect(faces[i].x,faces[i].y,faces[i].size().width,faces[i].size().height));//分离的人脸
resize(src2_img,src2_img,Size(divi_img.cols,divi_img.rows*0.5));
cvtColor(src2_img,src2_dst_img,COLOR_RGB2GRAY);
Mat roi = divi_img(Rect(0,src2_img.rows*0.3,src2_img.cols,src2_img.rows));
src2_img.copyTo(roi,src2_dst_img);
flag = true;
}
}
if(flag == true)
{
// addWeighted(small_roi,1,src2_img,1,0.0,small_roi);
imshow(DIVIWINDOW,divi_img);
}
if(faces.size()<=0&&flag == true)
{
flag = false;
destroyWindow(DIVIWINDOW);
}
// char key = waitKey(1);//按键事件
// if(key == 'q')
// {
// destroyWindow(DIVIWINDOW);
// }
imshow("src_img",src_img);
cout<<"检测到的人脸个数是"<<faces.size()<<endl;
waitKey(15);
}
#endif
}