我一直在尝试使用OpenCV进行对象检测…
我按照以下几个步骤操作…
- 将图像调整为64×64的分辨率
- 将图像转换为灰度
- 获取用于对象检测的XML文件
- 在检测到的模式周围绘制矩形
然而,我还是没能成功…
这是我的代码:
#include<iostream>#include "cv.h"#include "highgui.h"#include<vector>using namespace cv;using namespace std;int main(){ IplImage* img; img = cvLoadImage( "hindi3.jpg" ); vector<cv::Rect> objects; // ***调整图像至64x64分辨率*** IplImage *resizeImage = cvCreateImage(cvSize(64,64),8,3); cvResize(img,resizeImage,CV_INTER_LINEAR); cvShowImage("Resize",resizeImage); cvWaitKey(0); // ***将图像转换为灰度*** IplImage *grayImage = cvCreateImage(cvGetSize(resizeImage),8,1); cvCvtColor(resizeImage,grayImage,CV_BGR2GRAY); cvShowImage("gray",grayImage); cvWaitKey(0); // ***获取通过Haar训练生成的XML文件*** CvMemStorage* storage = cvCreateMemStorage(0); cout<<"Memory created\n"; cv::CascadeClassifier cascade; cascade.load("cascade.xml"); //CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad( "cascade.xml" ); cout<<"cascade.xml loaded successfully\n"; double scale = 1.3; 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}} }; // ***检测对象*** cvClearMemStorage( storage ); objects.clear(); //CvSeq* objects = cvHaarDetectObjects( grayImage, cascade, storage, 1.1, 4, 0, cvSize( 40, 50 )); //cascade.detectMultiScale(grayImage, objects, 1.2, 4, CV_HAAR_DO_CANNY_PRUNING, cvSize(30, 30)); cascade.detectMultiScale(grayImage, objects, 1.2, 4, CV_HAAR_SCALE_IMAGE, cvSize(30, 30)); // ***在识别出的模式外绘制矩形*** cout<<"Object size : "<<objects.size(); for( vector<cv::Rect>::const_iterator r = objects.begin(); r != objects.end(); r++) { //rectangle(img, *r, Scalar(0,0,255), 2, 8, 0); cvRectangle( grayImage, cvPoint( r->x, r->y ), cvPoint( r->x + r->width, r->y + r->height ),Scalar(0,0,255)); cout<<"In the loop\n"; } cvNamedWindow( "Output" ); cvShowImage( "Output", grayImage ); cvWaitKey(0); cvReleaseImage(&resizeImage); cvReleaseImage(&grayImage); cvReleaseImage( &img ); return 0;}
遗憾的是,我打印的对象大小显示为0。因此,它没有进入for循环…谁能帮帮我吗?
附注:我在代码中注释了一些无用的行。如果可以使用这些行,请告诉我。
回答:
找到了答案…!我遗漏了detectMultiScale函数的指定参数。
现在运行正常…修正后的代码如下
#include<iostream>#include "cv.h"#include "highgui.h"#include<vector>using namespace cv;using namespace std;int main(){ IplImage* img; img = cvLoadImage( "test.jpg" ); vector<cv::Rect> objects; /*** 调整大小是可选的*** ***************************** IplImage *resizeImage = cvCreateImage(cvSize(64,64),8,3); cvResize(img,resizeImage,CV_INTER_LINEAR); cvShowImage("Resize",resizeImage); cvWaitKey(0);*/ /*** 将图像转换为灰度*** **********************************/ IplImage *grayImage = cvCreateImage(cvGetSize(img),8,1); cvCvtColor(img,grayImage,CV_BGR2GRAY); //cvEqualizeHist(grayImage,grayImage); 这是可选的 cvShowImage("gray",grayImage); cvWaitKey(0); CvMemStorage* storage = cvCreateMemStorage(0); cout<<"Memory created\n"; /*** 加载通过Haar训练生成的XML文件*** **************************************************/ cv::CascadeClassifier cascade; cascade.load("cascade.xml"); //CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad( "cascade.xml" ); cout<<"cascade.xml loaded successfully\n"; double scale = 1.3; 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}} }; /*** 检测对象*** **********************/ cvClearMemStorage( storage ); objects.clear(); //CvSeq* objects = cvHaarDetectObjects( grayImage, cascade, storage, 1.1, 4, 0, cvSize( 40, 50 )); //cascade.detectMultiScale(grayImage, objects, 1.2, 4, CV_HAAR_DO_CANNY_PRUNING, cvSize(30, 30)); 如果通过网络摄像头捕获 cascade.detectMultiScale(grayImage, objects, 1.1, 3, CV_HAAR_SCALE_IMAGE | CV_HAAR_DO_CANNY_PRUNING,cvSize(0,0), cvSize(100,100)); cout<<"Object size : "<<objects.size(); /***在识别出的模式外绘制矩形*** ***********************************************/ for( vector<cv::Rect>::const_iterator r = objects.begin(); r != objects.end(); r++) { //rectangle(img, *r, Scalar(0,0,255), 2, 8, 0); cvRectangle( grayImage, cvPoint( r->x, r->y ), cvPoint( r->x + r->width, r->y + r->height ),Scalar(0,0,255)); cout<<"In the loop\n"; } cvNamedWindow( "Output" ); cvShowImage( "Output", grayImage ); cvWaitKey(0); //cvReleaseImage(&resizeImage); 如果调整了大小 cvReleaseImage(&grayImage); cvReleaseImage( &img ); return 0;}
最后,这次成功了…!
附注:这个程序仅在输入为图像时有效,不适用于网络摄像头或视频输入。