您的位置:首页 > 其它

从视频中提取图片,对图片做人脸检测并截取人脸区域

2017-08-10 10:55 567 查看
环境配置:VS2013+opencv2.4.10+libfacedetect.lib

libfacedetect.libxi下载: https://github.com/ShiqiYu/libfacedetection/blob/master/example/libfacedetect-example.cpp

安装参考博客日志:DAY1 :http://www.cnblogs.com/yamin/p/7115501.html

参考博客:http://blog.csdn.net/augusdi/article/details/11042329

http://www.1024do.com/?p=1296
首先给出视频处理的函数video_process.hpp

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "facedetect-dll.h"
#include<opencv2/highgui/highgui.hpp>

#pragma comment(lib,"libfacedetect.lib")
//#pragma comment(lib,"libfacedetect-x64.lib")
using namespace cv;

#define DETECT_BUFFER_SIZE 0x20000 //facedetect
#define UNKNOWN_FLOW_THRESH 1e9  //facedetect

#define NUM_FRAME 100  //Video_to_imag中控制截取帧数

//函数声明
void Video_to_image(char* filename, char* Savepath);
/*
函数功能:读取视频的每一帧,并将其按帧数命名保存
例如:Video_to_image("F:\\tp\\1.mp4", "F:\\image");
*/
void video_to_image(char* Filename, char* Savepath);
/*
函数功能:截取视频前三帧图片并将其保存,帧数间隔默认5
可用count_tmp和jiangge控制读取帧数和帧数间隔
用法示例:video_to_image(videopath, "F:\\截图\\1_")
保存文件名为\\后字符和输入序号的拼接
*/
int image_cut(char* Filename, char* Savepath);
/*
函数功能:对图片进行人脸检测吧,并截取保存人脸及周边区域
其中用到了libfacedetect.lib
用法示例:image_cut("F:\\截图\\1_1.jpg","F:\\截图\\CUT1_1.jpg" );
*/


给出视频处理的函数video_process.cpp ,对应上面三个函数

#include<video_process.h>

void Video_to_image(char* filename, char* Savepath)
{
printf("------------- video to image ... ----------------\n");

CvCapture* capture = cvCaptureFromAVI(filename);//初始化一个视频文件捕捉器
cvQueryFrame(capture);//获取视频信息
int frameH = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
int frameW = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
int fps = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
int numFrames = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
printf("video height : %dntvideo width : %dntfps : %dntframe numbers : %dn", frameH, frameW, fps, numFrames);//打印视频信息
//定义和初始化变量
int i = 0;
IplImage* img = 0;
char image_name[18];

cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);

//读取和显示
while (1)
{
img = cvQueryFrame(capture); //获取一帧图片
cvShowImage("mainWin", img); //将其显示
char key = cvWaitKey(20);
sprintf(image_name, "%s%d%s", Savepath, ++i, ".jpg");//保存的图片名
cvSaveImage(image_name, img);
//cvSaveImage( image_name, img);   //保存一帧图片
if (i == 0)
{
sprintf(image_name, "%s//%d%s", Savepath, i, ".jpg");
cvSaveImage(image_name, img);   //保存一帧图片
}
if (i == numFrames) break;
//if (i == NUM_FRAME) break;
i++;
}
cvReleaseCapture(&capture);
cvDestroyWindow("mainWin");
cvWaitKey();

}

void video_to_image(char* Filename, char* Savepath)
{
printf("------------- video to image ... ----------------n");
//初始化一个视频文件捕捉器
CvCapture *capture = NULL;
IplImage *frame = NULL;
char *AviFileName = Filename;// "F:\\tp\\1.mp4";//视频的目录
char *AviSavePath = Savepath;//"F:\\截图\\";//图片保存的位置
const int jiange = 5;//间隔5帧保存一次图片
capture = cvCaptureFromAVI(AviFileName);
cvNamedWindow("AVI player", 1);
int count_tmp = 0;//计数总帧数
int i = 1;
char tmpfile[100] = { '\0' };
while (count_tmp<15)  //每段视频保留3帧
{
if (cvGrabFrame(capture))
{
if (count_tmp % jiange == 0)
{
frame = cvRetrieveFrame(capture);
cvShowImage("AVI player", frame);//显示当前帧
sprintf(tmpfile, "%s%d.jpg", AviSavePath, i);//使用帧号作为图片名
cvSaveImage(tmpfile, frame);
i++;
}
if (cvWaitKey(10) >= 0) //延时
break;
++count_tmp;
}
else
{
break;
}
}
cvReleaseCapture(&capture);
cvDestroyWindow("AVI player");
std::cout << "总帧数" << count_tmp << std::endl;
cvWaitKey();
return;
}

int image_cut(char* Filename, char* Savepath)
{
Mat image = imread(Filename);
if (image.empty())
{
fprintf(stderr, "Can not load the image file %s.\n");
return -1;
}
Mat gray;
cvtColor(image, gray, CV_BGR2GRAY);
int * pResults = NULL;
//pBuffer is used in the detection functions.
//If you call functions in multiple threads, please create one buffer for each thread!
unsigned char * pBuffer = (unsigned char *)malloc(DETECT_BUFFER_SIZE);
if (!pBuffer)
{
fprintf(stderr, "Can not alloc buffer.\n");
return -1;
}

int doLandmark = 1;
///////////////////////////////////////////
// reinforced multiview face detection / 68 landmark detection
// it can detect side view faces, better but slower than facedetect_multiview().
//////////////////////////////////////////
//!!! The input image must be a gray one (single-channel)
//!!! DO NOT RELEASE pResults !!!
pResults = facedetect_multiview_reinforce(pBuffer, (unsigned char*)(gray.ptr(0)), gray.cols, gray.rows, (int)gray.step,
1.2f, 3, 48, 0, doLandmark);

printf("%d faces detected.\n", (pResults ? *pResults : 0));
int j = 0;
Mat result_multiview_reinforce = image.clone();
Mat image_cut = image.clone();
//print the detection results

for (int i = 0; i < (pResults ? *pResults : 0); i++)
{
short * p = ((short*)(pResults + 1)) + 142 * i;
int x = p[0];
int y = p[1];
int w = p[2];
int h = p[3];
int neighbors = p[4];
int angle = p[5];

printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);//(x,y)为检测到人脸左上角像素位置,w为宽,h为高
rectangle(result_multiview_reinforce, Rect(x, y, w, h), Scalar(0, 255, 0), 0.5);
int y1 = y - 100;
int x1 = x - 90;
int x2 = x + 285;
int y2 = y + 345;
if (y1 < 0) //超出边界判断
y1 = 0;
if (x1 < 0)
x1 = 0;
if (y2 >479)
y2 = 479;
if (x2>679)
x1 = 679;
image_cut = image_cut(Range(y1, y2), Range(x1, x2));
//imshow("image_cut", image_cut);
imwrite(Savepath, image_cut);

}

//release the buffer
free(pBuffer);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: