4

我几乎必须用 OpenCV 进行高效背景减法中所说的(背景减法,前景有颜色,除了相机而不是视频文件)。问题是在那个主题中没有关于背景减法阶段本身的解释。

我查看了官方的 openCV 书和互联网,简单的帧差异不足以满足我的需要。我试图理解更复杂的平均背景方法,但在帧的cvAcc获得平均值后我迷路了:/

如果有人可以帮助我一点,我将不胜感激..

谢谢!

使用我现在拥有的代码进行编辑:

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

平均

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

适应背景(#define 中的 alpha 为 0.05)

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

现在有问题!

现在最大的问题是,当我在图片的某个地方有一个灯泡时,当我将手“放在”它上面几秒钟后,当我把它拿走时,灯光会在前景中停留很长时间。 . 对此有什么帮助吗?

4

2 回答 2

4

简单的背景减法(前景提取)方法。

1.假设您的视频具有静态背景(即背景的微小变化几乎恒定的背景),然后考虑N一些帧并对其进行平均。然后您可以获得背景图像,即Img_BG

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

2.如果您的视频有任何光照变化,那么您的背景图像会更新如下,称为running avg。

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

alpha 是赋予当前帧的权重,通常在 0.05 到 0.1 左右。与 1 方法相比,此方法使用更少的内存。

3.您可以计算背景图像作为计算median of N frames.

于 2012-05-29T05:43:58.123 回答
3

您可以尝试使用Mixture of Gaussians来实现背景减法。wiki 解释了每个步骤中使用的 OpenCV 函数。

这是一种强大的背景减法方法,可以处理光线变化和场景中进出的物体。

我希望这有帮助。

于 2012-05-29T07:16:54.583 回答