views:

334

answers:

2

I'm trying to iterator over some directories containing approximately 3000 images. I load the image. If the image is loaded I release it. That is the smallest program that I can write to reproduce the error.

After loading and releasing 124 images the program stops loading images. I think this a memory issue but I don't understand what exactly causes the program to stop loading images.

I'm using OpenCV on my Mac. I don't know how exactly I can figure out which version I'm using.

Here is the Code from my project.

bool FaceDetectionStrategy::detectFace(std::string imagePath) {

   IplImage *img = cvLoadImage(imagePath.c_str(), CV_LOAD_IMAGE_COLOR);
   if (img) {
      std::cout << "Image loaded " << imagePath << std::endl;
      cvReleaseImage(&img);
   } else {
      std::cout << "Image not loaded " << imagePath << std::endl;
   }
return true;

}

This method is called for every image in the directorys I'm iterating through. After 124 images the if(img) part evaluates to false and the else branch is executed. If I try to load images from other parts of the program later on they also won't load.

Edit it is not a memory issue. Mac Os standard max open files is 256 after changing it to 512 I can open 251 images. so it seems that OpenCV doesn't closes the image files after loading them.

+2  A: 

Behavior concerning memory rarely has to do with a consistent number, in my experience. The only way it could be that consistent is if there is some sort of internal limit in cvLoadImage that happens to be the not-very-common number 124. But your logic seems fine to me, that your images should be released.

More likely, since I assume your directories aren't changing between tests, that 125th image is bad.

Have you verified that the image you are trying to load actually exists? If it does (which it probably does), check that the image file format is supported by OpenCV. If that is also true, make sure the file is not corrupted by opening it with another editor.

You can have OpenCV help you out with errors. Use cvGetErrStatus() to check if there was an error, then use cvErrorStr() to get a textual description of it. You can do something like this:

// I would recommend putting this in a file, like CVUtility.h

#include <exception>

void check_CV_Error(void)
{
    int errorCode = cvGetErrStatus();
    if (errorCode) // I'm assuming 0 means no reportable error
    {
        throw std::runtime_error(cvErrorStr(errorCode));
        // std::cerr << cvErrorStr(errorCode);
        // ^ if you would rather not use exceptions
    }
}

Your code then becomes:

bool FaceDetectionStrategy::detectFace(std::string imagePath) {

   IplImage *img = cvLoadImage(imagePath.c_str(), CV_LOAD_IMAGE_COLOR);
   if (img) {
      std::cout << "Image loaded " << imagePath << std::endl;
      cvReleaseImage(&img);
   } else {
      std::cout << "Image not loaded " << imagePath << std::endl;
      check_CV_Error(); // find reason for error
   }
return true;

And that will throw an exception for you to catch and log, and possibly react on. (Or print the error to console if you use the std::cerr version)

GMan
The error code is zero. So either OpenCV doesn't causes the error or doesn't set an error code.I loaded all the images with OpenCV before but not that much inside one run so the images should be compatible to OpenCV.
Janusz
Try deleting or moving one of the first 100 and see if the problem moves itself to a new bitmap, to be sure. That will eliminate "it's a specific picture" ideas.
GMan
Beginning with another directory first produced the same error. The images are not all the same size something between 20 and 60 K but the number of images I can open stays the same. Maybe I need to do something else to force OpenCV releasing the file handle? That would be a reason for the numbers of images I can load staying the same.
Janusz
+3  A: 

Searching the bugtracker from OpenCv showed this answer to the problem: cvLoadImage with Mac ImageIO leaves file handles open.

It seems that this is a bug in the OpenCV mac implementation and the only way to solve it is to install a newer version of OpenCV.

EDIT installing the last version of OpenCV from the repository trunk solves the problem. Sometimes it helps checking the BugTracker of the frameworks you are using...

Janusz
Heh, that's too bad :( Good to know you weren't crazy though, huh?
GMan
Yes feels good to see that the error was not in my code :)
Janusz