by mish4 in Coding Tricks / Tips

It started with casual debugging as I noticed my output was not what I expected. Then more signs showed that there was something DEFINITELY wrong. In particular I kept getting 0.0 when computing the difference of histograms using opencv’s compareHist, which operates on histograms computed by calcHist. Why would two different histograms (checked by creating images for them) yield a difference (using chi squared) that was 0. This shouldn’t be the case. After tracing my code from the final output to nearly the beginning of my system, I found the culprit.

I will recreate the bug scenario here by writing some ROUGH code to illustrate the idea. This is obviously not COMPLETE code, so do keep that in mind. See code comments

//Suppose we have a Shape class

class Shape {

public:

vector<Mat> histograms_; //should store many histograms

void computeHistograms(); //should compute histograms

}

//now let’s look at what void computeHistograms(); was doing (the part that contains the bug)

void Shape::computeHistograms()

{

Mat hist; //declare Mat which will store a single histogram

for(int i=0; i< num_histograms_to_compute; i++)

{

//assume that calcHist called below is used correctly and that as

//the variable i changes it should be computing a different

// histogram and storing it in the output variable hist

calcHist(i,param2,param3,param4,hist,param5,param6); //again arguments are approximate to illustrate the idea

histograms_.push_back(hist); //now I save this histogram computed in THIS iteration

}

}

So WHAT ends up happening with the code above is that the SAME histogram keeps getting pushed back into histograms_. Its as though the loop is not computing a NEW histogram on each iteration. So this is what resulted in all my histogram comparisons yielding a distance of 0.0, all the histograms were the same.

To FIX this BUG I put Mat hist; INSIDE of the for loop (at the top). That way, on every iteration of the loop I am re-declaring hist as a Mat. This of course causes the old hist to be freed and a new instance to be created. Once this change is in place the loop correctly computes a different histogram on each iteration and stores them in histograms_.

My guess is that calcHist has problems writing to a Mat that has already been written to. I don’t understand why it wouldn’t just overwrite the existing value, like you would expect in the following loop.

int x;

vector<int> save_x;

for (int i = 0; i< 10; i++)

{

x = i;

save_x.push_back(x);

}

//the output should be save_x == {0,1,2,3,4,5,6,7,8,9}; and I shouldn’t have to put int x inside the loop.

Moral of the story be careful with OpenCV, in particular calcHist!