基于opencv人脸检测,检测视频中的人脸如何减少发生的错误,漏检问题。

supreme321 2016-05-19 03:01:19


如上图存在的问题 求大神帮我改一改
代码如下

#include "cv.h"
#include "highgui.h"

#include "windows.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>


#ifdef _EiC
#define WIN32
#endif

static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade = 0;

void detect_and_draw( IplImage* image );

const char* cascade_name =
"haarcascade_frontalface_alt.xml";
/* "haarcascade_profileface.xml";*/

int main( int argc, char** argv )
{
// HWND MyWin;
cascade_name = "haarcascade_frontalface_alt2.xml";
cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

//CvCapture* pCap = cvCreateCameraCapture( 1 );//这里-1也可以,不过我的电脑装的有CyberLink YouCam软件,
// //OpenCV会默认调用该摄像头,而不调用系统的驱动
//IplImage *frame = NULL;

//if (cvCreateCameraCapture == NULL)
//{
// return(0);
//}

//cvNamedWindow("Camera",CV_WINDOW_FULLSCREEN);

//while ((frame = cvQueryFrame(pCap)) != 0 && cvWaitKey(20) != 27)
//{
// frame = cvQueryFrame(pCap);
// cvShowImage("Camera", frame);
//}

//cvReleaseCapture(&pCap);
//cvDestroyWindow("Camera");


if( !cascade )
{
fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
return -1;
}
storage = cvCreateMemStorage(0);
// cvNamedWindow( "result", 1 );

//const char* filename = "op.jpg";
//IplImage* image = cvLoadImage( filename, 1 );

//if( image )
//{
// detect_and_draw( image );
// cvWaitKey(0);
// cvReleaseImage( &image );
//}

//cvDestroyWindow("result");

//========================================================
// CvCapture 是一个结构体,用来保存图像捕获所需要的信息。
// opencv提供两种方式从外部捕获图像,一种是从摄像头中,一种
// 是通过解码视频得到图像。两种方式都必须从第一帧开始一帧一帧
// 的按顺序获取,因此每获取一帧后都要保存相应的状态和参数。
// 比如从视频文件中获取,需要保存视频文件的文件名,相应的******
// 类型,下一次如果要获取将需要解码哪一帧等。 这些信息都保存在
// CvCapture结构中,每获取一帧后,这些信息都将被更新,获取下一帧
// 需要将新信息传给获取的api接口
//=======================================================
CvCapture* capture = 0;
//===========================================================
// IplImage 是结构体类型,用来保存一帧图像的信息,也就是一帧
// 图像的所有像素值构成的一个矩阵
//===========================================================
IplImage *frame, *frame_copy = 0;

// 创建一个窗口,用“result”作为窗口的标识符
cvNamedWindow( "source", 1 );

// ==========================================
// 初始化一个视频捕获操作。
// 告诉底层的捕获api我想从 Capture1.avi中捕获图片,
// 底层api将检测并选择相应的******并做好准备工作
//==============================================
capture = cvCaptureFromFile("papi.avi");

// 如果 初始化失败,那么capture为空指针,程序停止,
// 否则进入捕获循环
if( capture )
{
// 捕获循环
for(;;)
{
// 调用cvGrabFrame,让底层api解码一帧图像
// 如果解码失败,就退出循环
// 如果成功,解码的图像保存在底层api的缓存中
if( !cvGrabFrame( capture ))
break;

// 将解码得到图像信息从缓存中转换成IplImage格式放在frame中
frame = cvRetrieveFrame( capture );

// 如果获取缓存或转换失败,则退出循环
if( !frame )
break;
detect_and_draw( frame );

// 将frame中的图像信息在窗口result中显示
// detect_and_draw( frame );
cvShowImage( "source", frame );

// 暂停一会儿,让你看一下图像
//Sleep(10);

// 如果你敲了键盘,就退出程序,否则继续捕获下一帧
if( cvWaitKey( 10 ) >= 0 )
break;
}

// 退出程序之前要清理一下堆栈中的内存,免得内存泄露
//cvReleaseImage( &frame );注意不需要这句,因为frame是从视频中捕获的,没有单独分配内存,无需释放,当capture 释放的时候frame自然就释放了。

// 退出之前结束底层api的捕获操作,免得它们占着茅坑不拉屎
// 比如会使得别的程序无法访问已经被它们打开的文件
cvReleaseCapture( &capture );

}
cvDestroyWindow("source");
//cvDestroyWindow("result");
return 0;
}


void detect_and_draw(IplImage* img )
{
double scale=1.2;
static CvScalar colors[] = {
{{0,0,255}},{{0,128,255}},{{0,255,255}},{{0,255,0}},
{{255,128,0}},{{255,255,0}},{{255,0,0}},{{255,0,255}}
};//Just some pretty colors to draw with

//Image Preparation
//
IplImage* gray = cvCreateImage(cvSize(img->width,img->height),8,1);
IplImage* small_img=cvCreateImage(cvSize(cvRound(img->width/scale),cvRound(img->height/scale)),8,1);
cvCvtColor(img,gray, CV_BGR2GRAY);
cvResize(gray, small_img, CV_INTER_LINEAR);

cvEqualizeHist(small_img,small_img); //直方图均衡

//Detect objects if any
//
cvClearMemStorage(storage);
double t = (double)cvGetTickCount();
CvSeq* objects = cvHaarDetectObjects(small_img,cascade,storage,1.1,2,0,cvSize(30,30));

t = (double)cvGetTickCount() - t;
printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );

//Loop through found objects and draw boxes around them
for(int i=0;i<(objects? objects->total:0);++i)
{
CvRect* r=(CvRect*)cvGetSeqElem(objects,i);
cvRectangle(img, cvPoint(r->x*scale,r->y*scale), cvPoint((r->x+r->width)*scale,(r->y+r->height)*scale), colors[i%8]);
}
for( int i = 0; i < (objects? objects->total : 0); i++ )
{
CvRect* r = (CvRect*)cvGetSeqElem( objects, i );
CvPoint center;
int radius;
center.x = cvRound((r->x + r->width*0.5)*scale);
center.y = cvRound((r->y + r->height*0.5)*scale);
radius = cvRound((r->width + r->height)*0.25*scale);
cvCircle( img, center, radius, colors[i%8], 3, 8, 0 );
}

//cvShowImage( "result", img );
cvReleaseImage(&gray);
cvReleaseImage(&small_img);
}
...全文
927 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2018-07-05
  • 打赏
  • 举报
回复
引用 6 楼 qq_36094296 的回复:
关于楼上有人说限制宽高大小,妈耶,也不想想,宽高不高于100px就不认为是人脸吗???假如离得远拍照脸就不是脸了吗,你要选好的数据去训练模型啊,改进一下函数参数设置,或者别的方法,你来个限制宽高 mmp什么垃圾方法

离多远?10000米?
赵4老师 2018-07-05
  • 打赏
  • 举报
回复
引用 6 楼 qq_36094296 的回复:
关于楼上有人说限制宽高大小,妈耶,也不想想,宽高不高于100px就不认为是人脸吗???假如离得远拍照脸就不是脸了吗,你要选好的数据去训练模型啊,改进一下函数参数设置,或者别的方法,你来个限制宽高 mmp什么垃圾方法

如图,后墙后面能站人吗?
king王一帅 2018-07-04
  • 打赏
  • 举报
回复
关于楼上有人说限制宽高大小,妈耶,也不想想,宽高不高于100px就不认为是人脸吗???假如离得远拍照脸就不是脸了吗,你要选好的数据去训练模型啊,改进一下函数参数设置,或者别的方法,你来个限制宽高 mmp什么垃圾方法
supreme321 2016-05-20
  • 打赏
  • 举报
回复
引用 3 楼 supreme321 的回复:
引用 1 楼 zhao4zhong1 的回复:
限制大小
什么意思?
赵老师,您的意思是不是对得到的人脸框进行判断,宽和高不超过100像素视为无效的人脸,是这个意思吗?
赵4老师 2016-05-20
  • 打赏
  • 举报
回复
引用 3 楼 supreme321 的回复:
引用 1 楼 zhao4zhong1 的回复:
限制大小
什么意思?
返回的人脸框的宽和高不超过比如100像素,不认为是有效的人脸。
supreme321 2016-05-20
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
限制大小
什么意思?
shiter 2016-05-19
  • 打赏
  • 举报
回复
CvSeq* objects = cvHaarDetectObjects(small_img,cascade,storage,1.1,2,0,cvSize(30,30)); 这句代码里面的参数调试一下就行了
赵4老师 2016-05-19
  • 打赏
  • 举报
回复
限制大小

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧