有人能解释一下OpenCV中的detectMultiScale函数吗?

我一直在尝试使用OpenCV进行对象检测…

我按照以下几个步骤操作…

  1. 将图像调整为64×64的分辨率
  2. 将图像转换为灰度
  3. 获取用于对象检测的XML文件
  4. 在检测到的模式周围绘制矩形

然而,我还是没能成功…

这是我的代码:

#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;}

最后,这次成功了…!

附注:这个程序仅在输入为图像时有效,不适用于网络摄像头或视频输入。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注