我正在尝试制作一个简单的程序,该程序将使用 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;
}
提前致谢!
附言。尽管可能有一些内置函数可以完成这项工作,但我宁愿自己制作算法。