I am trying to make a simple program that will subtract an object from a background with OpenCV and C++.
The idea is to use the VideoCapture to:
- Capture a static background (without the object)
- Then continuously capture the current frame and subtract that from the background
However, I have a problem when sending the captured data to my BackgroundSubtraction() function. It gives me an error:
Unhandled exception at 0x77d815 in OpenCV_BackgroundSubtraction.exe: 0xC000005: Acces violation regarding location 0x04e30050
However, sometimes it seems to work, other times not (using Visual Studio 2010 C++ on Windows 7 64-bit).
I have a feeling that it has something to do with memory allocation and priority of the functions. It seems like the VideoCapture grabber maybe is not fast enough the grab/write the frames before I send it to BackgroundSubtraction().
The built-in webcam in my laptop works fine (i.e. it shows a picture), but something in my code is wrong. I have tried playing around with some delays, but it doesn't seem to have an influence.
Here is my code:
Mat BackgroundSubtraction(Mat background, Mat current);
int main()
{
Mat colorImage;
Mat gray;
// Background subtraction
Mat backgroundImage;
Mat currentImage;
Mat object; // the object to track
VideoCapture capture, capture2;
capture2.open(0);
// Initial frame
while (backgroundImage.empty())
{
capture2 >> backgroundImage;
cv::imshow("Background", backgroundImage);
waitKey(100);
capture2.release();
}
capture.open(0);
// Tracking the object
while (true)
{
capture >> currentImage;
if ((char)waitKey(300) == 'q') // Small delay
break;
// The problem happens when calling BackgroundSubtraction()
object = BackgroundSubtraction(backgroundImage, backgroundImage);
cv::imshow("Current frame", currentImage);
cv::imshow("Object", object);
}
Mat BackgroundSubtraction(Mat background, Mat current)
{
// Convert to black and white
Mat background_bw;
Mat current_bw;
cvtColor(background, background_bw, CV_RGB2GRAY);
cvtColor(current, current_bw, CV_RGB2GRAY);
Mat newObject(background_bw.rows, background_bw.cols, CV_8UC1);
for (int y = 0; y < newObject.rows; y++)
{
for (int x = 0; x < newObject.cols; x++)
{
// Subtract the two images
newObject.at<uchar>(y, x) = background_bw.at<uchar>(y, x)
- current_bw.at<uchar>(y, x);
}
}
return newObject;
}
Thanks in advance!
Ps. Even though there might be some built-in functions to do the work, I would rather make the algorithm myself.