利用OpenCV的人脸检测给头像带上圣诞帽

标签: 利用 opencv 人脸检测 | 发表时间:2015-12-25 05:47 | 作者:wangyaninglm
出处:http://blog.csdn.net

原图:

 

效果:

 

 

 

    原理其实很简单:

采用一张圣诞帽的png图像作为素材,

 

   

    利用png图像背景是透明的,贴在背景图片上就是戴帽子的效果了。

人脸检测的目的主要是为了确定贴帽子的位置,类似ps中自由变换的功能,检测到人脸中间的位置,resize圣诞帽子和人脸大小匹配,确定位置,贴上去,ok!

 

 

 

代码:非常简洁,根据参考博客给出的代码,由OpenCV自带的人脸检测代码经过简单修改即可。

// getheader.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#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;


#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 = "D:\\Program Files\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "D:\\Program Files\\opencv\\sources\\data\\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( void )
{
	CvCapture* capture;
	//VideoCapture 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; };

			frame = imread("19.jpg");//背景图片

			//-- 3. Apply the classifier to the frame
			if( !frame.empty() )
			{ detectAndDisplay( frame ); }
			
			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];
			//alpha = 255-alpha;
			if(alpha != 0) //4通道图像的alpha判断
			{
				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 );
		// ellipse( frame, center, Size( faces[i].width/2, faces[i].height/2), 0, 0, 360, Scalar( 255, 0, 255 ), 2, 8, 0 );

		// line(frame,Point(faces[i].x,faces[i].y),center,Scalar(255,0,0),5);

		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 );
		}

		// if(eyes.size())
		{
			resize(hatAlpha,hatAlpha,Size(faces[i].width, faces[i].height),0,0,INTER_LANCZOS4);
			// mapToMat(hatAlpha,frame,center.x+2.5*faces[i].width,center.y-1.3*faces[i].height);
			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);
}


 

 

 

 

 

 

参考文献:

http://blog.csdn.net/lonelyrains/article/details/50388999

http://docs.opencv.org/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html

作者:wangyaninglm 发表于2015/12/24 21:47:00 原文链接
阅读:164 评论:0 查看评论

相关 [利用 opencv 人脸检测] 推荐:

利用OpenCV的人脸检测给头像带上圣诞帽

- - CSDN博客综合推荐文章
采用一张圣诞帽的png图像作为素材,.     利用png图像背景是透明的,贴在背景图片上就是戴帽子的效果了. 人脸检测的目的主要是为了确定贴帽子的位置,类似ps中自由变换的功能,检测到人脸中间的位置,resize圣诞帽子和人脸大小匹配,确定位置,贴上去,ok. 代码:非常简洁,根据参考博客给出的代码,由OpenCV自带的人脸检测代码经过简单修改即可.

[译] OpenCV vs Dlib 人脸检测比较分析

- - IT瘾-dev
点击我爱计算机视觉标星,更快获取CVML新技术. 人脸检测是计算机视觉最典型的应用之一,早期OpenCV的logo就是Haar人脸检测的示意图. 很多人的第一个OpenCV学习目标就是跑通Haar级联人脸检测,Dlib库在业内开始流行很大程度上是因为其HOG-SVM人脸检测比OpenCV Haar的好,而近年来OpenCV和Dlib均已包含基于深度学习的人脸检测算法实现.

PyQt+OpenCV 录制保存、播放视频

- - 编程语言 - ITeye博客
准备这一两个月看看以前的书,另外学习下视频方面的东西(CV方面). 之前学过几天QT/PyQt,于是用PyQt结合OpenCV,做了一个小程序. 具有播放并保存摄像头捕获组成的视频,以及播放本地视频文件两个小功能. 界面很简单,没图没真相. 代码就100多行,很容易看懂. 最后感叹下OpenCV和python的强大,噢,还有QT/PyQt.

Android和iOS自带的人脸检测API

- friedvan - 增强视觉 | 计算机视觉 增强现实
说说Android和iOS里面自带的人脸检测API. Android提供了一个人脸检测类 android.media.FaceDetector,调用findFaces函数,它可以返回图片中的找到的人脸. 人脸的属性封装在Face类,包括x, y, z三轴的人脸pose,还有两眼距离eyesDistance().

人脸检测与识别的趋势与再分析

- - IT瘾-dev
最近因为种种原因,这方面的知识有得到大家的认可和对其有很大的兴趣,所以今天想再一次分享这知识,让已明白的人更加深入理解,让初学者有一个好的开端与认知,谢谢大家的支持. 现在打开谷*公司的搜索器,输入 “face detect”,估计大家都能够想到,都是五花八门的大牛文章,我是羡慕啊. (因为里面没有我的一篇,我们实验室的原因,至今没有让我发一篇有点权威的文章,我接下来会写4张4A纸的检讨,去自我检讨下为什么.

人脸检测、人脸对齐(MTCNN方法) - 花泽 - CSDN博客

- -
众所众知,严格定义上的人脸识别分为四个步骤:. ①人脸检测:从图片中准确定位到人脸. ②人脸矫正(对齐): 检测到的人脸,可能角度不是很正,需要使其对齐. ④对两张人脸图像的特征向量进行对比,计算相似度. 这里,我们主要是推荐步骤1和步骤2用到的一个方法,论文是. 《2016 Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks》.  这篇论文具体的思想大家可以自己阅读.

Windows平台上编译OpenCV的Android版本

- Pei - C++博客-首页原创精华区
Android NDK(r5b或更高版本). 在opencv\android\scripts\目录下,新建wincfg.cmd文件. 关于wincfg.cmd文件的配置,可以参考opencv\android\scripts\wincmd.cfg.tmpl文件. 编译完成即可在opencv\android\build目录下得到所有的静态库文件.

记录下用OpenCV做Demo时候用到的小代码

- Fenix - 丕子
Demo做完了,但是鲁棒性和泛化能力很差,是关于视频中人体检测跟踪以及计数的,对我这个没有接触过视频以及跟踪的人来说,10天搞定还真是困难很大. 主要就是先进行图像差将运动的前景减出来,然后只要在前景当中运行HOG的MultiScale方法检测行人,这样可以提高一部分效率,毕竟前景图都是原始图的子图.

在 Mac OS X 10.6 下编译安装高性能 OpenCV 库

- Wolf - Chun Tian (binghe)
最初由 Intel 开发的 OpenCV 库已经逐渐成为目前计算机视觉和图像识别领域的事实标准了,教科书里几乎所有的主流图形算法都在 OpenCV 里可以找到高效的实现. 为了完成公司安排给我的工作,这个库是我的必经之路,道理很简单:我不可能花费一个相关专业的硕士研究生的在校时间去把所有底层算法从头学习并实现一遍,我的时间顶多只有一两个月,因此重要的是如何用尽可能少的时间把整个工作中我最不擅长的部分用现成的开源软件来完成.

[OpenCV实战]5 基于深度学习的文本检测

- - IT瘾-geek
在这篇文章中,我们将逐字逐句地尝试找到图片中的单词. 基于最近的一篇论文进行文字检测. 应该注意,文本检测不同于文本识别. 在文本检测中,我们只检测文本周围的边界框. 但是,在文本识别中,我们实际上找到了框中所写的内容. 例如,在下面给出的图像中,文本检测将为您提供单词周围的边界框,文本识别将告诉您该框包含单词STOP.