0

我正在尝试制作一个简单的程序,该程序将使用 OpenCV 和 C++ 从背景中减去一个对象。

这个想法是使用 VideoCapture 来:

  • 捕捉静态背景(没有对象)
  • 然后连续捕捉当前帧并从背景中减去

但是,将捕获的数据发送到我的 BackgroundSubtraction() 函数时出现问题。它给了我一个错误:

OpenCV_BackgroundSubtraction.exe 中 0x77d815 处未处理的异常:0xC000005:访问关于位置 0x04e30050 的违规

但是,有时它似乎有效,有时则无效(在 Windows 7 64 位上使用 Visual Studio 2010 C++)。

我有一种感觉,它与内存分配和函数的优先级有关。似乎 VideoCapture 抓取器在我将其发送到 BackgroundSubtraction() 之前抓取/写入帧的速度可能不够快。

我笔记本电脑中的内置网络摄像头工作正常(即显示图片),但我的代码中有问题。我试过玩一些延迟,但它似乎没有影响。

这是我的代码:

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;
}

提前致谢!

附言。尽管可能有一些内置函数可以完成这项工作,但我宁愿自己制作算法。

4

1 回答 1

1

您可以尝试更改几件事来确定您的问题。但我的猜测是,您传递给减法器函数的图像之一是无效的。请在处理它们之前验证两者是否确实有效

  1. 您应该确保正确创建和发布您的捕获。我不记得 capture.release() 是否正在等待,但我会验证捕获是否正常工作。实际上我可能只使用一次捕获,因为您只使用一个相机。
  2. 您没有验证您的 currentImage 是否实际创建,因此是有效的。
  3. 我还记得前一段时间无法修改由捕获对象创建的图像,但必须在处理之前制作帧的副本。你也可以试试这个
  4. 此外,我注意到您正在为前景和背景图像传递相同的图像。这本身不是问题,但可能不是您想要做的。

最后,您应该尝试调试您的程序,以确定代码中引发异常的确切位置。

于 2012-10-06T15:39:03.137 回答