OpenCV заменяет IplImage на Mat

Я использую 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;
}

3 ответа

Решение

Хорошая идея, чтобы избавиться от иплимаций!

видите, это тоже становится намного проще:

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

Нижняя строка обрезает прямоугольник и копирует в тип циновки.

Mat cropped = captureframe(faces[i]);

нижняя строка сохраняет обрезанное изображение в каталоге вашего проекта с именем в виде числа, хранящегося в counter(тип int).

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

если вы делаете это для обучения распознавателя, не забудьте изменить размеры всех изображений до одинакового размера, прежде чем сохранить.

Другие вопросы по тегам