1. 程式人生 > >從視頻中提取圖片,對圖片做人臉檢測並截取人臉區域

從視頻中提取圖片,對圖片做人臉檢測並截取人臉區域

rep pan details 一個 ons sprintf imread href multipl

環境配置:VS2013+opencv2.4.10+libface.lib

參考博客: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;
}

從視頻中提取圖片,對圖片做人臉檢測並截取人臉區域