Легкое, но не элементарное вычитание фона в opencv?

Мне нужно сделать почти то, что сказано в Эффективное вычитание фона с помощью OpenCV (вычитание фона с помощью передний план с цветом, за исключением камеры, а не видеофайла). Проблема в том, что в той теме нет объяснения самой фазы вычитания фона.

Я просмотрел официальную книгу openCV и в Интернете, и простого Frame Differenceing недостаточно для того, что мне нужно. Я пытался понять более сложный Метод усреднения фона, но я теряюсь после cvAcc кадров, чтобы получить среднее значение:/

Если бы кто-нибудь мог мне немного помочь, я был бы очень признателен.

Спасибо!

EDIT с кодом, который у меня уже есть:

Сумма

cvCvtScale( currentFrame, currentFloat, 1, 0 ); 
if(totalFrames == 0) 
 cvCopy(currentFloat, sum); 
else 
 cvAcc(currentFloat, sum);

средний

cvConvertScale( sum, imgBG, (double)(1.0/totalFrames) );

адаптированный фон (альфа равна 0,05 в #define)

cvRunningAvg(currentFrame, imgBG, alpha); 

Создание конечного изображения только с передним планом (далеко от совершенства!)

void createForeground(IplImage* imgDif,IplImage * currentFrame)
{
cvCvtColor(imgDif, grayFinal, CV_RGB2GRAY);
cvSmooth(grayFinal, grayFinal);
cvThreshold(grayFinal, grayFinal, 40, 255, CV_THRESH_BINARY);

unsigned char *greyData= reinterpret_cast<unsigned char *>(grayFinal->imageData);
unsigned char *currentData= reinterpret_cast<unsigned char *>(currentFrame->imageData);
unsigned char *fgData= reinterpret_cast<unsigned char *>(currentFrame->imageData);

int i=0;
for(int j=0 ; j<(grayFinal->width*grayFinal->height) ; j++)
{
        if(greyData[j]==0) 
        {
            fgData[i]=0;
            fgData[i+1]=0;
            fgData[i+2]=0;
            i=i+3;
        }
        else 
        {
            fgData[i]= currentData[i];
            fgData[i+1]= currentData[i+1];
            fgData[i+2]= currentData[i+2];
            i=i+3;
        }
}
cvSetData( imgFG , fgData , imgFG->width*imgFG->nChannels);
}

ПРОБЛЕМА ПРЯМО СЕЙЧАС!

Самая большая проблема сейчас заключается в том, что когда у меня есть лампочка где-то на картинке, после того, как я держу руку «поверх» ее в течение нескольких секунд, когда я убираю ее, свет остается на переднем плане в течение длительного времени. , любая помощь в этом?


person StinkyCat    schedule 29.05.2012    source источник


Ответы (2)


Простые методы вычитания фона (извлечение переднего плана).

1. Скажем, если ваше видео имеет статический фон (т. Е. Небольшие вариации фона почти постоянный фон), то рассмотрите N количество кадров и усредните его. Затем U может получить фоновое изображение, т. е. Img_BG.

    Img_BG = (1/N)*sum(framesFrom1 to N);

2. Если ваше видео с каким-либо освещением время от времени меняется, ваше фоновое изображение обновляется следующим образом, оно называется работающим avg.

    Img_ApdatedBG =(1- alpha)*Img_BG+(alpha)*CurrentFrame;
    Img_BG =  Img_ApdatedBG;

альфа — это вес, придаваемый текущему кадру, обычно он составляет от 0,05 до 0,1. Этот метод использует меньше памяти по сравнению с 1 методом.

3. Вы можете рассчитать фоновое изображение как вычисление median of N frames.

person surya    schedule 29.05.2012
comment
спасибо @surya, я попробую сегодня днем, а потом отпишусь о своих результатах. - person StinkyCat; 29.05.2012
comment
Хорошо, поэтому я попробовал этот способ. код для суммы: cvCvtScale(currentFrame, currentFloat, 1, 0); если (totalFrames == 0) cvCopy (currentFloat, сумма); иначе cvAcc(currentFloat, сумма); | Код для среднего: cvConvertScale(sum, imgBG, (double)(1.0/totalFrames)); | А код для адаптированного фонаcvRunningAvg(currentFrame, imgBG, alpha); (с альфа-значением от 0,05 до 0,1 в #define. результаты< /b> такие: если я оказываюсь перед камерой, сначала я не появляюсь, а через некоторое время я призрак. Я думаю, что фон теперь в порядке. - person StinkyCat; 29.05.2012
comment
Теперь я хочу, чтобы финальное изображение было на переднем плане (я иду перед камерой) в цвете, а остальное в черном. Что ты говоришь? Я попробовал cvAbsDiff(currentFloat, imgBG, finalFloat);, но это не так хорошо, как я ожидал... спасибо :) проект работает, эх **EDIT:** как насчет использования маски? Я читал в Интернете, что может мне помочь, но я не знаю, как его использовать. - person StinkyCat; 29.05.2012
comment
Так что я продолжил проект, хотя и не использовал маски. Я перешел на этот веб-сайт по ссылке, и программа работает хорошо, но далеко не идеально. Самая большая проблема сейчас заключается в том, что когда у меня есть лампочка где-то на картинке, после того, как я держу руку над ней в течение нескольких секунд, когда я убираю ее, свет остается на переднем плане в течение длительного времени. помочь в этом? - person StinkyCat; 30.05.2012

Вы можете попробовать с этой реализацией фонового вычитания, используя Mixture of Гауссианы. Вики объясняет функции OpenCV, используемые на каждом этапе.

Это надежный метод вычитания фона, который имеет дело с изменениями освещения и объектами, появляющимися и исчезающими из сцены.

Надеюсь, это поможет.

person Jav_Rock    schedule 29.05.2012
comment
спасибо @Jav_Rock, после подхода Сурьи, если у меня не будет удовлетворительных результатов, я обращусь к вам :) - person StinkyCat; 29.05.2012