OpenCV 用 Mat 替换 IplImage

Posted

技术标签:

【中文标题】OpenCV 用 Mat 替换 IplImage【英文标题】:OpenCV replace IplImage by Mat 【发布时间】:2014-02-14 11:46:10 【问题描述】:

我正在使用 OpenCV 检测多张图像中的人脸,然后将人脸图像(矩形)保存为 jpg 文件。但由于我有很多图像,我得到了内存不足的 OpenCV 错误。我知道这是因为使用了IplImage,它不会自行释放,我应该改用cv::Mat,但我找不到使用cv::Mat 的解决方案。有人可以帮忙吗?

这是我的代码

int main (int argc, const char* argv[] )


    cv::CascadeClassifier face_cascade;

    face_cascade.load("haarcascade_frontalface_alt.xml");

    cv::Mat captureFrame;
    cv::Mat grayscaleFrame;

    DIR *dir;
    struct dirent *ent;
    if ((dir = opendir ("c:\\images\\")) != NULL) 
        int counter = 1;
        while ((ent = readdir (dir)) != NULL) 
            printf ("%s\n", ent->d_name);

            std::string fullPath = std::string("c:\\images\\") + ent->d_name;

            captureFrame = cv::imread(fullPath);

            cvtColor(captureFrame, grayscaleFrame, CV_BGR2GRAY);
            equalizeHist(grayscaleFrame, grayscaleFrame);

            std::vector<cv::Rect> faces;

            face_cascade.detectMultiScale(grayscaleFrame, faces, 1.2,2,CV_HAAR_DO_CANNY_PRUNING, cv::Size(60, 60)); 

            for(int i = 0; i < faces.size(); i++)
            
                IplImage* img = cvCloneImage(&(IplImage)captureFrame);
                cvSetImageROI(img, cvRect(faces.at(i).x, faces.at(i).y, faces.at(i).width, faces.at(i).height));

                IplImage *img2 = cvCreateImage(cvGetSize(img),
                    img->depth,
                    img->nChannels);

                cvCopy(img, img2, NULL);

                cvResetImageROI(img);

                std::stringstream sstm;
                sstm << "faces\\" <<counter << ".jpg";
                string result = sstm.str();

                cvSaveImage (result.c_str() , img2);

                counter++;
            
        
        closedir (dir);
    
    return 1;

【问题讨论】:

【参考方案1】:

下面的行裁剪矩形并复制到一个垫子类型。

Mat cropped = captureframe(faces[i]);

以下行将裁剪后的图像保存到您的项目目录中,名称为存储在计数器中的数字(int类型)。

imwrite( format("%d.jpg",  counter), cropped );

如果您这样做是为了训练识别器,请不要忘记在保存之前将所有图像调整为相同大小。

【讨论】:

【参考方案2】:

摆脱 iplimage 的好主意!

看,它也变得容易多了:

for(size_t i = 0; i < faces.size(); i++)


    Mat roi(captureFrame, faces[i]);

    std::stringstream sstm;
    sstm << "faces\\" <<counter << ".jpg";
    string result = sstm.str();

    imwrite(result.c_str() , roi);

    counter++;

【讨论】:

【参考方案3】:

你看到这个页面了吗?:How to convert a Mat variable typeOpenCV C++ interfaceOpenCV: IplImage versus Matconverting Mat to iplimage up url的也许有你的答案...

【讨论】:

以上是关于OpenCV 用 Mat 替换 IplImage的主要内容,如果未能解决你的问题,请参考以下文章

vector<Mat> opencv 问题

opencv::证件照背景替换

opencv怎么给mat赋值

opencv中Mat数据怎么保存为JPG格式的图片

OpenCV用另一个值替换特定像素值

OpenCV Mat类常用成员属性和成员方法