First, and foremost, a warning: I am a c# developer, so c++ is a whole different beast for me...
I am using OpenCV to grab images from a webcam, and I am trying to keep a running history in an array. I can't find a reason for this stepping though, but pretty quickly my history array craps out and the only symptom I can find is the pointers are all the same value.
My idea is first to fill the array, and once it is full to throw away the 0 index image, and shift them all down one, filling the last element with the current image.
IplImage* _imgHistory[MAX_HISTORY];
bool Background::setHistory(IplImage* inputImg) {
//Add to the history array
if (!_imgHistory[MAX_HISTORY-1]) {
// History is not yet full, so find the first empty spot
for (int i=0;i<MAX_HISTORY;i++) {
if (!_imgHistory[i]) {
_imgHistory[i] = cvCloneImage(inputImg);
printf("Frame: %d\n", i);
returnfalse; // no point in continuing since history is still filling
}
}
}
//Make room for the next frame
cvReleaseImage(&_imgHistory[0]);
for (int i=0;i<MAX_HISTORY-2;i++)
_imgHistory[i] = _imgHistory[i+1];
_imgHistory[MAX_HISTORY-1] = cvCloneImage(inputImg);
returntrue;
}
First thing is to replace that array with a deque or boost::circular_array.
Raw arrays are rarely used in C++ and it would be madness to implement basic functionality like removal of an element manually when there is no need.
Edit: cvReleaseImage(&_imgHistory[0]); doesn't look correct either. Surely you want to pass the pointer to the image and not a pointer to the pointer to the image?
As far as cvReleaseImage, There is certainly a problem somewhere, because I am quickly filling my memory, and something is not being released. I believe what I have is right, as the declaration is:
1 2
/* Releases IPL image header and data */
CVAPI(void) cvReleaseImage( IplImage** image );
The MAX_HISTORY - 2 is used since the loop references i+1
I converted to deque, but now I am getting errors from opencv, I think because the type inside the deque is showing as IplImage*&
UpdateImage(IplImage*) adds the image to history (via setHistory), then uses the history to try to determine what is static background and what is foreground...
The MAX_HISTORY - 2 is used since the loop references i+1
Yes, but it still should have been MAX_HISTORY-1. With the condition i<MAX_HISTORY-2, i will go up to MAX_HISTORY-3, so history[MAX_HISTORY-2] would be assigned to history[MAX_HISTORY-3] in the last iteration. The last element remains untouched and therefore the second to last element is being replicated all over the array which results in newer frames not being freed, as they never get to wander to the front of the array.
The line cvAbsDiff(_imgHistory.front(), _imgHistory.back(), diff); should be fine, though (it should compile, at least). IplImage*& is a reference to a pointer and since references are aliases, you can use it everywhere where a pointer to IplImage is expected. If this line still produces an error, you should post the exact error messages.