Question

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.

Was it helpful?

Solution

There are several things that you could try to change to identify your problem. But my guess would be that one of the images that you pass to the subtracter function is not valid. Please verify that both are in fact valid before processing them

  1. You should make sure that your captures are created and released correctly. I cant remember whether the capture.release() is busy-waiting or not, but I would verify that the capture is working. Actually i would probably only use a single capture, since your using only one camera.
  2. Your not verifying that your currentImage is actually created, and thereby valid.
  3. Also I remember that sometime ago it was not possible to modify the image created by the capture object, but one had to make a copy of the frame before processing it. You could try this as well
  4. Additionally i noted that you are passing the same image for both the foreground and background image. It's not a problem per se, but probably not what you want to do.

And finally you should try to debug your program to identify the exact place in your code where an exception is thrown.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top