tags:

views:

72

answers:

2

Hi,

I'm trying to add several images using opencv. I think that my source code should be correct and it compiles without any problems. But when I start the program an error occurs in the for-loop. The problem is that I don't understand why this is happening.

    #include <iostream>
    #include <sys/types.h>
    #include <dirent.h>
    #include <errno.h>
    #include <vector>
    #include <string>
    #include <fstream>

    #include <cv.h>
    #include <highgui.h>

using namespace std;


int get_files(string dir,
              vector<string> &files);



int main( int argc, char** argv ){

    //---------- Get the names of all *.png files in the directory 
    string directory = string(".");
    vector<string> files = vector<string>();

    get_files(directory,files);


    //---------- Erase all filenames that aren't *.png files 
    vector<string> files_format = vector<string>();

    for (unsigned int ii = 0; ii < files.size(); ii++) {

        files_format.push_back(files[ii]);

        string::iterator it;
        string format;
        files_format[ii].erase(0,files_format[ii].length()-3);

        if (files_format[ii] != "png") files.erase(files.begin() + ii);

     }

    files.erase(files.begin()); // in order to remove the ".." in the beginning

    int number_of_files = files.size();



    //---------- Create the necessary images 

    if (files.size() == 0)
        return -1;

    IplImage* img_firstimage = cvLoadImage(files[0].c_str());

    IplImage* img_totalsum = cvCreateImage(cvGetSize(img_firstimage), 8, 1 );
    cvCvtColor(img_firstimage, img_totalsum, CV_BGR2GRAY );


    //---------- Apply threshold 
    cvThreshold(img_totalsum, img_totalsum, 150, 1, 1);


    //---------- Add all the images 
    for (unsigned int ii=1; ii < files.size(); ii++){

        IplImage* img_load = cvLoadImage(files[ii].c_str());
        IplImage* img_add = cvCreateImage(cvGetSize(img_load), 8, 1 );

        cvCvtColor(img_load, img_add, CV_BGR2GRAY );

        cvThreshold(img_add, img_add, 150, 1, 1);

        //----- add the image to the total sum -----
        cvAdd(img_totalsum, img_add, img_totalsum);

        // ----- release images -----
        cvReleaseImage(&img_load);
        cvReleaseImage(&img_add);
    }


    //---------- Invert the total sum image 
    // -> dense regions are plotted in black
    //cvNot(img_totalsum, img_totalsum);

    cvNot(img_firstimage, img_firstimage);

    //---------- Show the images
    cvShowImage("Density Distribution", img_totalsum);
    cvShowImage("Negative", img_firstimage);

    cvWaitKey(0);


    // ----- release images -----
    cvReleaseImage(&img_firstimage);
    cvReleaseImage(&img_totalsum);

    return 0;
}

    int get_files(string dir,
           vector<string> &files){
DIR *dp;
struct dirent *dirp;
if((dp  = opendir(dir.c_str())) == NULL) {
       cout << "Error(" << errno << ") opening " << dir << endl;
         return errno;
     }

     while ((dirp = readdir(dp)) != NULL) {
         files.push_back(string(dirp->d_name));
     }
     closedir(dp);
     return 0;
+1  A: 

It seems, you release your img_add in every loop iteration, but it is created only once. Move the cvReleaseImage(&img_add); instruction outside (directly under) your for loop. That should fix it.

EDIT:

Okay, seems, you fixed that already. Does it work now?

Btw, creating and releasing the img_add inside of your for loop for every newly loaded image is not necessary and is possibly slower, because of the multiple memory allocation and deallocation. You should better allocate it befor entering the loop and release it after the loop.

Frank Bollack
I changed the source code as follows but it doesn't work either: I placed IplImage* img_add = cvCreateImage(cvGetSize(img_firstimage), 8, 1 ); before the loop and released the image directly after the loop.
supergranu
@supergranu: Does it crash at the same position? Can you please add the changed code to your question?
Frank Bollack
Yes, it crashes at the same position. - I tested the problem with another small program. It seems that there is a problem with memory allocation in general.
supergranu
The main problem is, that it's hard to find a way to have a for-loop that reads several images one after another (but uses only one variable for this) and does some image processing with them.
supergranu
@supergranu: Okay, one more important fact you need to make sure is, that all images must have the same format, that means same dimension and number of planes. Otherwise the `cvCvtColor()` will crash. Can you verify, all images are compatible?
Frank Bollack
A: 

I solved the problem. I had some other files in the working directory, that weren't *.png files and then the loop didn't work. Absolutely clear that the program couldn't load the other files and work with them... I just don't understand, why the part of the program isn't working that should take care of this problem... Somehow the if (files_format[ii] != "png") files.erase(files.begin() + ii); didn't work properly

supergranu