【问题标题】:My Simple Background Subtraction Algorithm does not work我的简单背景减法算法不起作用
【发布时间】:2014-11-21 20:07:38
【问题描述】:

我使用 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; - 已解决
我刚刚发现问题出在我安装在计算机中的防病毒软件上。 我必须确认允许该应用程序使用我的网络摄像头,但该程序仍在执行,并且由于它没有捕获任何内容而出现以下错误。

但是现在,我发现我的算法有新问题。它不会删除背景。输出只是一个黑屏。

我现在该怎么办?

【问题讨论】:

  • 添加 if(bg_frame.cols == 0) return 0;在你的无限循环(或类似的测试)之前。
  • 尝试双 pixel_different = abs(bg_RGB_pixel[0]-cur_RGB_pixel[0]) + abs(bg_RGB_pixel[1] - cur_RGB_pixel[1]) + abs(bg_RGB_pixel[2]-cur_RGB_pixel[2]) ); if (pixel_different
  • 成功了!你能解释一下我的代码有什么问题吗? @米卡
  • 我好像啊...只是放错了参数。它应该是 pow(B1[0] - B2[0], 2)。无论如何,谢谢你的解决方案。 ;) @Micka
  • 您评论中的版本看起来更好,也应该可以工作! (如果您针对 进行测试)

标签: c++ opencv


【解决方案1】:

我看到两个问题:

我很确定您没有正确使用 pow()。我假设您正在寻找 (bg_RGB_pixel[0] - cur_RGB_pixel[0]) 等的 2 次幂。在我看来,您所拥有的 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;
            }
        }
    }

我将大部分背景分割出来,并且在我开始后出现在相机视野中的项目没有分割出来(不是涂黑)并以原始颜色显示。 在合理范围内……即使是新物品也有一些部分涂黑了。但是您使用的是非常简单的分割算法,所以这是意料之中的,结果实际上非常好。

迈克尔

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    相关资源
    最近更新 更多