我使用OpenCV 2.4.9,Visual Studio 2013
我开发了一个从后台提取对象的程序。背景显示为黑色,对象显示为原始颜色
我通过笔记本电脑摄像头收到输入。
这是我的程序
#include <iostream>
#include <cstdlib>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
namedWindow("Background Subtraction");
VideoCapture capture(0); // Open the default camera
if (!capture.isOpened()) // Check if we succeeded
return -1;
Mat bg_frame; // Capture 1st frame
capture >> bg_frame;
Mat cur_frame; // Capture current frame
double threshold = (double)50;
while (1) {
// Capture current frame
capture >> cur_frame;
// Loop all pixel in image
for (int i = 0; i < cur_frame.rows; ++i) {
for (int j = 0; j < cur_frame.cols; ++j) {
Vec3b bg_RGB_pixel = bg_frame.at<Vec3b>(i, j);
Vec3b cur_RGB_pixel = cur_frame.at<Vec3b>(i, j);
double pixel_different = sqrt( pow(bg_RGB_pixel[0], cur_RGB_pixel[0]) +
pow(bg_RGB_pixel[1], cur_RGB_pixel[1]) +
pow(bg_RGB_pixel[2], cur_RGB_pixel[2]) );
if (pixel_different > threshold) {
cur_RGB_pixel[0] = 0;
cur_RGB_pixel[1] = 0;
cur_RGB_pixel[2] = 0;
cur_frame.at<Vec3b>(i, j) = cur_RGB_pixel;
}
}
}
imshow("Background Subtraction", cur_frame);
char c = cvWaitKey(10);
if (c == 27)
break;
}
return 0;
}
当我运行代码时,我收到此错误。 错误出现在此行
Vec3b bg_RGB_pixel = bg_frame.at<Vec3b>(i, j);
我该如何解决这个问题?
感谢您的所有建议和解决方案。
[编辑]
使用Mat.at(i,j)时异常:std :: bad_alloc; - 已解决
我刚刚发现问题出在我安装在计算机上的AntiVirus软件上。
我必须确认该应用程序可以使用我的网络摄像头,但程序仍然执行,它会收到以下错误,因为它什么也没有捕获。
但现在,我发现我的算法出现了新问题。它不会删除背景。输出只是一个黑屏。
我现在该怎么办?
答案 0 :(得分:0)
我看到两个问题:
我很确定你没有正确使用pow()。我假设你正在寻找2的幂(bg_RGB_pixel [0] - cur_RGB_pixel [0])等等。在你看来,bg_RGB_pixel的功能是cur_RGB_pixel的功能。
我用更长的形式写了它,因为我认为它更清晰(首先计算差异,然后是权力;见下面的代码)。
另外,我认为你想要pixel_different比阈值更少 - 而不是更多 - 以便将相对于第一个捕获的参考帧不改变的背景归零(除非你想要分割出新的东西)在图像上)。
无论如何 - 这对我有效(仅显示内部,每个图像,循环):
for (int i = 0; i < cur_frame.rows; ++i) {
for (int j = 0; j < cur_frame.cols; ++j) {
Vec3b bg_RGB_pixel = bg_frame.at<Vec3b>(i, j);
Vec3b cur_RGB_pixel = cur_frame.at<Vec3b>(i, j);
int diff0 = bg_RGB_pixel[0] - cur_RGB_pixel[0];
int diff1 = bg_RGB_pixel[1] - cur_RGB_pixel[1];
int diff2 = bg_RGB_pixel[2] - cur_RGB_pixel[2];
double pixel_different = sqrt(pow(diff0, 2) + pow(diff1, 2) + pow(diff2, 2));
if (pixel_different < threshold) {
cur_RGB_pixel[0] = 0;
cur_RGB_pixel[1] = 0;
cur_RGB_pixel[2] = 0;
cur_frame.at<Vec3b>(i, j) = cur_RGB_pixel;
}
}
}
我将大部分背景分割出来,并且在我开始后出现在相机视野中的项目不会被分割出来(不会变黑)并以原始颜色显示。 在合理范围内...即使是新项目也有一些部分被涂黑了。但是你使用的是非常简单的分割算法,所以这是预期的,结果实际上非常好。
迈克尔