我必须做几乎Efficient Background subtraction with 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);
}
现在有问题了!
现在最大的问题是,当我在图片中的某处有一个灯泡时,我将手“放在上面”几秒钟后,当我将它拿开时,光线会在前景中停留很长时间时间……对此有什么帮助吗?
最佳答案
简单的背景减法(前景提取)方法。
1.假设您的视频具有静态背景(即背景中的小变化几乎是恒定的背景),然后考虑 N
帧数并对其进行平均。然后您可以获得背景图片即 Img_BG
。
Img_BG = (1/N)*sum(framesFrom1 to N);
2.如果您的视频有任何照明不时变化,那么您的背景图像会更新如下,称为运行平均。
Img_ApdatedBG =(1- alpha)*Img_BG+(alpha)*CurrentFrame;
Img_BG = Img_ApdatedBG;
alpha 是赋予当前帧的权重,通常约为 0.05 到 0.1。 与方法 1 相比,此方法使用更少的内存。
3.您可以将背景图像计算为计算 N 帧的中位数。
关于opencv - 简单但不是 opencv 中的基本背景减法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10792616/