我正在做一个关于监控摄像头的人脸检测项目。现在我正处于人脸检测的阶段,我可以检测到每个帧的脸部。检测到脸部后,我需要将脸部存储到本地文件夹。现在我可以保存指定文件夹中的每个面。
问题现在它正在保存每个面孔,但我只需要保存一次相同的面孔。这意味着如果将一个面部保存为jpeg图像,并且当面部检测再次进展时,同一面部即将到来,所以这次我不想保存那张特别的脸。
这是我的代码:
#include <cv.h>
#include <highgui.h>
#include <time.h>
#include <stdio.h>
using namespace std;
int ct=1;
int ct1=0;
IplImage *frame;
int frames;
void facedetect(IplImage* image);
void saveImage(IplImage *img,char *ex);
IplImage* resizeImage(const IplImage *origImg, int newWidth,int newHeight, bool keepAspectRatio);
const char* cascade_name="haarcascade_frontalface_default.xml";
int k=1;
int main(int argc, char** argv)
{
CvCapture *capture=cvCaptureFromFile("Arnab Goswami on Pepper spary rajagopal Complete NewsHour Debate (Mobile).3gp");
int count=1;
while(1)
{
frame = cvQueryFrame(capture);
if(count%30==0)
{
facedetect(frame);
}
count++;
}
cvReleaseCapture(&capture);
return 0;
}
void facedetect(IplImage* image)
{
ct1++;
cvNamedWindow("output");
int j=0,i,count=0,l=0,strsize;
char numstr[50];
int arr[100],arr1[100];
CvPoint ul,lr,w,h,ul1,lr1;
CvRect *r;
//int i=0;
IplImage* image1;IplImage* tmpsize;IplImage* reimg;
CvHaarClassifierCascade* cascade=(CvHaarClassifierCascade*) cvLoad(cascade_name);
CvMemStorage* storage=cvCreateMemStorage(0);
const char *extract;
if(!cascade)
{
cout<<"Coulid not load classifier cascade"<<endl;
}
if(cascade)
{
CvSeq*faces=cvHaarDetectObjects(image,cascade,storage,1.1,1,CV_HAAR_DO_CANNY_PRUNING,cvSize(10,10));
//function used for detecting faces.o/p is list of detected faces.
for(int i=0;i<(faces ? faces->total : 0);i++)
{
string s1="im",re,rename,ex=".jpeg";
sprintf(numstr, "%d", k);
re = s1 + numstr;
rename=re+ex;
char *extract1=new char[rename.size()+1];
extract1[rename.size()]=0;
memcpy(extract1,rename.c_str(),rename.size());
//Copies the values of rename.size from the location pointed by source //(rename.c_str)directly to the memory block pointed by destination(extract).
strsize=rename.size();
r=(CvRect*) cvGetSeqElem(faces,i);//draw rectangle outline around each image.
ul.x=r->x;
ul.y=r->y;
w.x=r->width;
h.y=r->height;
lr.x=(r->x + r->width);
lr.y=(r->y + r->height);
cvSetImageROI(image,cvRect(ul.x,ul.y,w.x,h.y));
image1=cvCreateImage(cvGetSize(image),image->depth,image->nChannels);
cvCopy(image, image1, NULL);
reimg=resizeImage(image1, 40, 40, true);
saveImage(reimg,extract1);
cvResetImageROI(image);
cvRectangle(image,ul,lr,CV_RGB(1,255,0),3,8,0);
j++,count++;
k++;
cout<<"frame"<<ct1<<" "<<"face"<<ct<<":"<<"x: "<<ul.x<<endl;
cout<<"frame"<<ct1<<" "<<"face"<<ct<<":"<<"y: "<<ul.y<<endl;
cout<<""<<endl;
ct++;
//cvShowImage("output",image);
}
//return image;
//cvNamedWindow("output");//creating a window.
cvShowImage("output",image);//showing resized image.
cvWaitKey(0);
}
}
void saveImage(IplImage *img,char *ex)
{
int i=0;
char path[255]="/home/athira/Image/OutputImage";
char *ext[200];
char buff[1000];
ext[i]=ex;
sprintf(buff,"%s/%s",path,ext[i]);//copy ext[i] to buff
strcat(path,buff);//concat path & buff
cvSaveImage(buff,img);
i++;
}
答案 0 :(得分:0)
您正在使用基于haar功能的级联分类器进行对象检测。据我所知,这些xml文件只接受过基于数百张评估图片检测特定对象的培训(参见cascade classifier training)。
因此,为了比较保存的图像,您需要另一种“检测”模式,因为您必须比较两个面是否与视角相同等等(关键字:生物识别数据)。 您正在寻找的关键字是“face recognition”我认为。只需根据检测到的面部建立一个数据库,然后将其用于人脸识别。
修改强> 另一个可能有用的链接:www.shervinemami.info/faceRecognition.html
答案 1 :(得分:0)
如果我理解正确,你想要的是检测一帧中的脸部,保存这张脸的缩略图。然后,在下一帧中,您希望再次检测面部,但只保存第一帧中不存在的缩略图。
这个问题很难,因为视频中捕获的面孔总是从一帧变为另一帧。这是由于图像中的噪音,人们可能正在移动等等。因此,在监控录像中没有两张面孔相同。
因此,为了实现您的要求,您需要确定您在考虑的面部是否已在之前的帧中观察过。在一般形式中,这个问题并不明显,并且仍然是许多与生物识别,行人跟踪和重新识别等相关的研究的主题。因此,你将很难在检测到已经观察到给定面部时达到100%有效。
但是,如果可以接受不是100%有效的方法,您可以尝试以下方法:
检测第0帧中的面F 0 i ,并关联图像位置(x 0 i ,y 0 i ),并存储缩略图
计算位置上的稀疏光流(例如使用KLT,见this link)(x n-1 i ,y n-1 i )前一帧n-1中的面,以估计它们的位置(xx n i ,yy n i )当前帧n。
检测当前帧n中的面F 0 i ,并关联图像位置(x n i < / sub>,y n i ),并且只保存那些不接近预测位置之一的缩略图(xx n i ,yy n i )。
增加n并使用下一帧重复步骤2-3。
这是一种使用跟踪来确定先前是否已经观察过给定面部的简单算法。它应该比基于生物识别的方法更容易实现,并且在视频监控的背景下可能更合适。然而,由于光流估计和面部检测器的有效性有限,不 100%准确,。