【问题标题】:Easy, but not elementar background subtraction in opencv?在opencv中简单但不是基本的背景减法?
【发布时间】:2012-05-29 03:05:58
【问题描述】:

我必须做出几乎在Efficient Background subtraction with OpenCV 中所说的内容(背景减法与前景的颜色,除了相机而不是视频文件)。问题是在那个主题中没有关于背景减法阶段本身的解释。

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

如果有人能帮我一点忙,我将不胜感激..

谢谢!

EDIT 使用我现在拥有的代码:

总和

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

现在有问题!

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

【问题讨论】:

    标签: opencv average background-subtraction


    【解决方案1】:

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

    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 左右。 与第一种方法相比,此方法使用的内存更少。

    3.你可以像计算median of N frames.一样计算背景图片

    【讨论】:

    • thks @surya,我会在今天下午试一试,然后我会回复我的结果。
    • 好的,所以我尝试了这种方式。 sum 的代码是: cvCvtScale( currentFrame, currentFloat, 1, 0 ); if(totalFrames == 0) cvCopy(currentFloat, sum); else cvAcc(currentFloat, sum); |求平均值的代码是:cvConvertScale( sum, imgBG, (double)(1.0/totalFrames) ); | adapted background 的代码是 cvRunningAvg(currentFrame, imgBG, alpha);(alpha 在#define 中为 0.05 到 0.1。results 是:如果我一开始出现在镜头前,我不会出现,过了一会儿我是个鬼。我认为现在背景很好。
    • 我现在想要的是作为前景的最终图像(我走在镜头前),颜色为彩色,其余为黑色。你说什么?我尝试了 cvAbsDiff(currentFloat, imgBG, finalFloat); 但它不如我预期的那么好...... thks :) 它正在滚动项目eheh **编辑:**使用面具怎么样?我在网上阅读可以帮助我,但我不知道如何使用它..
    • 所以我继续这个项目,尽管没有使用面具。我关注了这个网站link,程序运行良好,但远非完美。现在最大的问题是,当我在图片的某个地方有一个灯泡时,当我将手“放在”它上面几秒钟后,当我把它拿走时,灯光会在前景中停留很长时间。 . 有什么帮助吗?
    【解决方案2】:

    您可以尝试使用高斯混合进行背景减法implementation。 wiki 解释了每个步骤中使用的 OpenCV 函数。

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

    我希望这会有所帮助。

    【讨论】:

    • thks @Jav_Rock,在 surya 的方法之后,如果我没有满意的结果,我会求助于你的 :)
    猜你喜欢
    • 2011-12-07
    • 2011-12-19
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    相关资源
    最近更新 更多