OpenCV人脸检测程序以及cx0000000d错误的解决

以下转载,仅供学习交流!

CvHaarFeature, CvHaarClassifier, CvHaarStageClassifier, CvHaarClassifierCascade Boosted Haar 分类器结构的几个结构体是树型结构。

Cascade:

Stage1:
Classifier11:
Feature11
Classifier12:
Feature12
...
Stage2:
Classifier21:
Feature21 整个等级可以手工构建,也可以利用函数cvLoadHaarClassifierCasc ade从已有的磁盘文件或嵌入式基中导入。

 

1.CvHaarClassifierCascade* cvLoadHaarClassifierCascade( const char* directory训练好的级联分类器的路径,cvSize orig_window_size级联分类器训练中采用的检测目标的尺寸。因为这个信息没有在级联分类器中存储,所以要单独指出 );

函数 cvLoadHaarClassifierCascade 用于从文件中装载训练好的利用哈尔特征的级联分类器,或者从OpenCV中嵌入的分类器数据库中导入。分类器的训练可以应用函数haartraining(详细察看opencv/apps/haartraining) 这个数值是在训练分类器时就确定好的,修改它并不能改变检测的范围或精度。

需要注意的是,这个函数已经过时了。现在的目标检测分类器通常存储在 XML 或 YAML 文件中,而不是通过路径导入。从文件中导入分类器,可以使用函数 cvLoad 。

2.void cvReleaseHaarClassifierCascade( CvHaarClassifierCascade** cascade );

cascade
双指针类型指针指向要释放的cascade. 指针由函数声明。

 

函数 cvReleaseHaarClassifierCascade 释放cascade的动态内存,其中cascade的动态内存或者是手工创建,或者通过函数 cvLoadHaarClassifierCascade 或 cvLoad分配。

3.CvSeq* cvHaarDetectObjects( const CvArr* image, CvHaarClassifierCascade* cascade,

                            CvMemStorage* storage, double scale_factor=1.1,

                            int min_neighbors=3, int flags=0,

                            CvSize min_size=cvSize(0,0) );

typedef struct CvAvgComp

{

    CvRect rect;

    int neighbors;

}

 

image
被检图像
cascade
harr 分类器级联的内部标识形式
storage 用来存储检测到的一序列候选目标矩形框的内存区域。 scale_factor
在前后两次相继的扫描中,搜索窗口的比例系数。例如1.1指将搜索窗口依次扩大10%。
min_neighbors
构成检测目标的相邻矩形的最小个数(缺省-1)。如果组成检测目标的小矩形的个数和小于min_neighbors-1 都会被排除。如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户自定义对检测结果的组合程序上。
flags
操作方式。当前唯一可以定义的操作方式是 CV_HAAR_DO_CANNY_PRUNING。如果被设定,函数利用Canny边缘检测器来排除一些边缘很少或者很多的图像区域,因为这样的区域一般不含被检目标。人脸检测中通过设定阈值使用了这种方法,并因此提高了检测速度。
min_size
检测窗口的最小尺寸。缺省的情况下被设为分类器训练时采用的样本尺寸(人脸检测中缺省大小是~20×20)。

 

函数 cvHaarDetectObjects 使用针对某目标物体训练的级联分类器在图像中找到包含目标物体的矩形区域,并且将这些区域作为一序列的矩形框返回。函数以不同比例大小的扫描窗口对图像进行几次搜索(察看cvSetImagesForHaarClassifierCascade)。每次都要对图像中的这些重叠区域利用cvRunHaarClassifierCascade进行检测。有时候也会利用某些继承(heuristics)技术以减少分析的候选区域,例如利用 Canny 裁减 (prunning)方法。函数在处理和收集到候选的方框(全部通过级联分类器各层的区域)之后,接着对这些区域进行组合并且返回一系列各个足够大的组合中的平均矩形。调节程序中的缺省参数(scale_factor=1.1, min_neighbors=3, flags=0)用于对目标进行更精确同时也是耗时较长的进一步检测。为了能对视频图像进行更快的实时检测,参数设置通常是:scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING, min_size=<minimum possible face size> (例如, 对于视频会议的图像区域).

4.void cvSetImagesForHaarClassifierCascade( CvHaarClassifierCascade* cascade,

                                          const CvArr* sum, const CvArr* sqsum,

                                          const CvArr* tilted_sum, double scale );为

为隐藏的cascade(hidden cascade)指定图像

cascade
隐藏 Harr 分类器级联 (Hidden Haar classifier cascade), 由函数 cvCreateHidHaarClassifie rCascade生成
sum
32-比特,单通道图像的积分图像(Integral (sum) 单通道 image of 32-比特 integer format). 这幅图像以及随后的两幅用于对快速特征的评价和亮度/对比度的归一化。 它们都可以利用函数 cvIntegral从8-比特或浮点数 单通道的输入图像中得到。
sqsum
单通道64比特图像的平方和图像
tilted_sum
单通道32比特整数格式的图像的倾斜和(Tilted sum)
scale
cascade的窗口比例. 如果 scale=1, 就只用原始窗口尺寸检测 (只检测同样尺寸大小的目标物体) - 原始窗口尺寸在函数cvLoadHaarClassifierCasc ade中定义 (在 "<default_face_cascade>"中缺省为24x24), 如果scale=2, 使用的窗口是上面的两倍 (在face cascade中缺省值是48x48 )。这样尽管可以将检测速度提高四倍,但同时尺寸小于48x48的人脸将不能被检测到。

 

函数 cvSetImagesForHaarClassifierCascade 为hidden classifier cascade 指定图像 and/or 窗口比例系数。如果图像指针为空,会继续使用原来的图像(i.e. NULLs 意味这"不改变图像")。比例系数没有 "protection" 值,但是原来的值可以通过函数 cvGetHaarClassifierCascadeScale 重新得到并使用。这个函数用于对特定图像中检测特定目标尺寸的cascade分类器的设定。函数通过cvHaarDetectObjects进行内部调用,但当需要在更低一层的函数cvRunHaarClassifierCascade中使用的时候,用户也可以自行调用

5.int cvRunHaarClassifierCascade( CvHaarClassifierCascade* cascade, CvPoint pt, int start_stage=0 );

在给定位置的图像中运行 cascade of boosted classifier

cascade
Haar 级联分类器
pt
待检测区域的左上角坐标。待检测区域大小为原始窗口尺寸乘以当前设定的比例系数。当前窗口尺寸可以通过cvGetHaarClassifierCasca deWindowSize重新得到。
start_stage
级联层的初始下标值(从0开始计数)。函数假定前面所有每层的分类器都已通过。这个特征通过函数cvHaarDetectObjects内部调用,用于更好的处理器高速缓冲存储器。

 

函数 cvRunHaarClassifierCascade 用于对单幅图片的检测。在函数调用前首先利用 cvSetImagesForHaarClassifierCascade设定积分图和合适的比例系数 (=> 窗口尺寸)。当分析的矩形框全部通过级联分类器每一层的时返回正值(这是一个候选目标),否则返回0或负值


程序源代码:

#include "stdafx.h"

#include "cv.h" 
#include "highgui.h" 
#include <iostream>
//读取训练好的分类器。 
void ErrorHandler(char* message)
{
cout<<message<<endl;
exit(0);
}


CvHaarClassifierCascade* load_object_detector( const char* cascade_path ) 

return (CvHaarClassifierCascade*)cvLoad( cascade_path ); 
}


void detect_and_draw_objects( char* imgname, 
CvHaarClassifierCascade* cascade, 
int do_pyramids ) 


CvMemStorage* storage = cvCreateMemStorage(0); //创建动态内存 
CvSeq* faces; 
int i, scale = 1; 
IplImage* image=cvLoadImage(imgname); 
IplImage* small_image = image; 
/* if the flag is specified, down-scale the 输入图像 to get a 
performance boost w/o loosing quality (perhaps) */ 
if( do_pyramids ) 



small_image = cvCreateImage( cvSize(image->width/2,image->height/2), IPL_DEPTH_8U, 3 ); 
//函数 cvPyrDown 使用 Gaussian 金字塔分解对输入图像向下采样。
//首先它对输入图像用指定滤波器进行卷积,然后通过拒绝偶数的行与列来下采样图像。 
cvPyrDown( image, small_image, CV_GAUSSIAN_5x5 );
scale = 2; 

/* use the fastest variant */ 
faces = cvHaarDetectObjects( small_image, cascade, storage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING ); 
/* draw all the rectangles */ 
for( i = 0; i < faces->total; i++ ) 

/* extract the rectanlges only */ 
CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i ); 
cvRectangle( image, cvPoint(face_rect.x*scale,face_rect.y*scale), 
cvPoint((face_rect.x+face_rect.width)*scale, 
(face_rect.y+face_rect.height)*scale), 
CV_RGB(255,0,0), 3 ); 

cvNamedWindow( "test", 1 ); 
cvShowImage( "test", image ); 
if( small_image != image ) 
cvReleaseImage( &small_image ); 
cvReleaseImage( &image ); 
cvReleaseMemStorage( &storage ); //释放动态内存 


/* takes image filename and cascade path from the command line */ 
int main( int argc, char** argv ) 
{
WIN32_FIND_DATA FileData; 
HANDLE hSearch; 
BOOL fFinished = FALSE; 
if(!SetCurrentDirectory("images")){
std::cout<<"failed to change work directory"<<endl;
exit(0);
}
CvHaarClassifierCascade* cascade = load_object_detector("D:\\OpenCV2.2\\data\\haarcascades\\haarcascade_frontalface_alt.xml"); 
hSearch = FindFirstFile("*.jpg", &FileData); 
if (hSearch == INVALID_HANDLE_VALUE){ 
ErrorHandler("No .bmp files found."); 

while (!fFinished){ 
//fingerTip(FileData.cFileName);
detect_and_draw_objects( FileData.cFileName, cascade, 1 ); 
if (!FindNextFile(hSearch, &FileData))
{
if (GetLastError() == ERROR_NO_MORE_FILES)
{
fFinished = TRUE; 

else

ErrorHandler("Couldn't find next file."); 

}
cvWaitKey(0);

//IplImage* image=cvLoadImage("E:\\photo\\Lena.jpg"); 
//if( argc==3 && (image = cvLoadImage( argv[1], 1 )) != 0 ) 
//{ 
//cvWaitKey(0); 
cvReleaseHaarClassifierCascade( &cascade );
//} 
return 0; 
}


源程序下载地址:http://download.csdn.net/detail/wode0239/4881850


对于cx0000000d错误的解决是 :使用opencv2.2。我最开始使用的是opencv2.3总是提示cx0000000d错误。改用opencv2.2然后配置一下库和链接就可以运行了。希望对你有帮助。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值