C++ 如何只保存一次相同的面

C++ 如何只保存一次相同的面,c++,opencv,image-processing,C++,Opencv,Image Processing,我正在做一个关于监控摄像机人脸检测的项目。现在我正处于人脸检测阶段,我可以从每个帧检测人脸。检测完人脸后,我需要将该人脸存储到本地文件夹。现在我可以将每个人脸保存在指定的文件夹中 问题现在它正在保存所有人脸,但我只需要保存相同的人脸一次。这意味着如果将一张人脸保存为jpeg图像,并且当人脸检测再次进行时,会出现相同的人脸,因此这次我不想保存特定的人脸 这是我的代码: #include <cv.h> #include <highgui.h> #include <

我正在做一个关于监控摄像机人脸检测的项目。现在我正处于人脸检测阶段,我可以从每个帧检测人脸。检测完人脸后,我需要将该人脸存储到本地文件夹。现在我可以将每个人脸保存在指定的文件夹中

问题现在它正在保存所有人脸,但我只需要保存相同的人脸一次。这意味着如果将一张人脸保存为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++;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int-ct=1;
int ct1=0;
IplImage*框架;
int帧;
void facedetect(IplImage*图像);
void saveImage(IplImage*img,char*ex);
IplImage*大小图像(常量IplImage*初始值、int-newWidth、int-newHeight、布尔基普光谱比);
const char*cascade_name=“haarcascade_frontalface_default.xml”;
int k=1;
int main(int argc,字符**argv)
{
CvCapture*capture=cvCaptureFromFile(“Arnab Goswami on Pepper spary rajagopal Complete News Hour Conference(手机).3gp”);
整数计数=1;
而(1)
{
帧=cvQueryFrame(捕获);
如果(计数%30==0)
{   
人脸检测(帧);
}
计数++;
}   
cvReleaseCapture(&capture);
返回0;
}
void facedetect(IplImage*图像)
{
ct1++;
CVD(“输出”);
int j=0,i,count=0,l=0,strsize;
char numstr[50];
int-arr[100],arr1[100];
CVU点ul、lr、w、h、ul1、lr1;
CvRect*r;
//int i=0;
IplImage*image1;IplImage*tmpsize;IplImage*reimg;
CvHaarClassifierCascade*级联=(CvHaarClassifierCascade*)cvLoad(级联_名称);
CvMemStorage*storage=cvCreateMemStorage(0);
常量字符*提取;
如果(!级联)
{
库尔特;
lr.x=(r->x+r->宽度);
lr.y=(r->y+r->高度);
cvSetImageROI(图像,cvRect(ul.x,ul.y,w.x,h.y));
image1=cvCreateImage(cvGetSize(图像),图像->深度,图像->通道);
cvCopy(图像,图像1,空);
reimg=调整图像大小(图像1,40,40,真);
saveImage(reimg,extract1);
cvResetImageROI(图像);
CV矩形(图像、ul、lr、CV_RGB(1255,0)、3,8,0);
j++,count++;
k++;

cout您正在使用基于haar特征的级联分类器进行对象检测。据我所知,这些xml文件仅经过训练,可根据数百张评估图片检测特定对象(请参阅)

因此,要比较保存的图像,您需要另一种“检测”模式,因为您必须比较两个面在视角等方面是否相同(关键字:生物特征数据)。 我想你要找的关键词是“”。只要根据你检测到的人脸建立一个数据库,然后用它们进行人脸识别

编辑:
另一个可能有用的链接:www.shervinemami.info/faceRecognition.html

如果我理解正确,您需要在一帧中检测人脸,保存此人脸的缩略图。然后,在下一帧中,您需要再次检测人脸,但只保存第一帧中不存在的人脸的缩略图

这个问题很难解决,因为视频中捕获的人脸总是从一帧切换到下一帧。这是由于图像中的噪声、人员可能在移动等原因造成的。因此,监控视频中从来没有两张脸是相同的

因此,为了实现您的要求,您需要确定您正在考虑的人脸是否已经在以前的帧中被观察到。一般来说,这个问题并不明显,并且仍然是与生物特征识别、行人跟踪和重新识别等相关的许多研究的主题。因此,您将面临一个困难的time以实现100%的有效性,检测已观察到的给定人脸

但是,如果您可以接受一种不是100%有效的方法,您可以尝试以下方法:

  • 检测第0帧中具有相关图像位置(x0i、y0i)的面F0i,并存储缩略图

  • 计算前一帧n-1中面位置(xn-1i,yn-1i)上的稀疏光流(例如,使用KLT,参见),以估计它们在当前帧n中的位置(xxni,yyni)

  • 检测当前帧n中具有相关图像位置(xni,yni)的面F0i,并仅保存不接近其中一个预测位置(xxni,yyni)的面的缩略图

  • 增加n并使用下一帧重复步骤2-3


  • 这是一种简单的算法,使用跟踪来确定之前是否已经观察到给定的人脸。它应该比基于生物特征的方法更容易实现,并且可能更适合视频监控。但是,由于光流估计的有效性有限,它不是100%准确,人脸检测仪的ion和

    …openCV通常只检测人脸。默认情况下,没有生物特征数据来分离您的发现并将其保存为不同的人。(提示:您可以使用openCV教程中的数据将一些通用信息存储为眼睛之间的距离,以分离您的发现)您的标题和问题不一致。您的标题表示您希望“仅保存相同的图像一次”,而问题的正文似乎表示您希望“仅保存相同的人脸一次”你想要的是人脸识别,而不仅仅是人脸检测。请-停止使用过时的c-api!实际上我的意思是在标题和正文中都是一样的,那就是只保存相同的人脸一次,如果相同的人脸再次出现,我不想保存。抱歉,如果我的文字让你感到困惑…实际上我当前的问题em是为了避免多次保存同一张图像。我只想只保存一张特定的图像。有人能帮我克服这个问题吗..你能做的是:保存图像并进行人脸检测(使用casacade)和模板匹配()