Мой простой алгоритм вычитания фона не работает

0

Я использую OpenCV 2.4.9, Visual Studio 2013.

Я разрабатываю программу, которая извлекает объект из фона. Фон отображается как черный, а объект отображается как оригинальный цвет.
Я получаю вход через камеру Notebook.

Вот моя программа

#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);

Изображение 174551

Как я могу решить эту проблему?

Спасибо за все предложения и решения.

[Редактировать]
exception: std :: bad_alloc при использовании Mat.at(i, j); - Решено
Я только что обнаружил, что проблема в том, что мое программное обеспечение AntiVirus, которое я установил на своем компьютере. Я должен подтвердить, что приложение разрешено использовать мою веб-камеру, но программа все еще выполняется, и она получает следующую ошибку, потому что она ничего не фиксирует.

Но теперь я нашел новую проблему с моим алгоритмом. Он не удаляет фон. Выход - только черный экран.

Что мне теперь делать?

  • 0
    Добавьте if (bg_frame.cols == 0) return 0; перед вашим бесконечным циклом (или подобным тестом).
  • 1
    Попробуйте дважды 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])); если (pixel_different <порог) ...
Показать ещё 4 комментария
Теги:
opencv

1 ответ

0

Я вижу две проблемы:

Я уверен, что вы не используете pow() правильно. Я предполагаю, что вы ищете power of of of 2 (bg_RGB_pixel [0] - cur_RGB_pixel [0]) и т.д. То, что вам кажется, нужно сделать bg_RGB_pixel для мощности cur_RGB_pixel.

Я написал это в более длинной форме, так как я думаю, что он более ясен (сначала рассчитал diff, затем мощность, см. Код ниже).

Кроме того, я думаю, что вы хотите 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;
            }
        }
    }

Я получил большую часть фонового сегмента, и элементы, которые появляются в поле зрения камеры после того, как я начал, не сегментированы (не затемнены) и отображаются в исходном цвете. В пределах разумного... даже новые элементы имеют некоторые части, затемненные. Но вы используете очень упрощенный алгоритм сегментации, поэтому это ожидается, и результаты на самом деле довольно хороши.

Майкл

Ещё вопросы

Сообщество Overcoder
Наверх
Меню