2011-10-14 170 views
7

我想要实现背景平均法。我在一秒钟内拍摄了50帧图像,其中一些帧包含我想要提取为前景的闪电。使用固定摄像机拍摄框架,并将框架视为灰度。我想要做的是:OpenCV中的背景减法(C++)

  1. 获取背景模型
  2. 后,比较每一帧的背景模型,以确定是否有在该框架或不点亮。

我读了一些关于如何通过使用cvAcc()来完成这项工作的文档,但我很难理解如何做到这一点。我将不胜感激指导我的一段代码,并链接到可帮助我理解如何实现这一点的文档。

感谢您提前。

回答

18

我们在其中一个项目中完成了相同的任务。为了得到背景模型,我们只需创建一个BackgroundModel类,捕获第一个(可以说)50帧并计算平均帧,以避免背景模型中的像素错误。例如,如果您从相机获取8位灰度图像(CV_8UC1),则使用CV_16UC1初始化模型以避免裁剪。现在

cv::Mat model = cv::Mat(HEIGHT, WIDTH, CV_16UC1, cv::Scalar(0)); 

,等待第一个帧,计算模型,只是每帧添加到模型并计算接收帧的数量。

void addFrame(cv::Mat frame) { 
    cv::Mat convertedFrame; 
    frame.convertTo(convertedFrame, CV_16UC1); 
    cv::add(convertedFrame, model, model); 
    if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50 
     createMask(); 
    } 
} 

createMask()函数计算我们用于模型的平均帧。

void createMask() { 
    cv::convertScaleAbs(model, mask, 1.0/learnedFrames); 
    mask.convertTo(mask, CV_8UC1); 
} 

现在,您只需将所有帧通过BackgroundModel类发送到函数subtract()即可。如果结果是一个空的cv :: Mat,则仍然计算掩码。否则,你会得到一个相减的帧。

cv::Mat subtract(cv::Mat frame) { 
    cv::Mat result; 
    if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50 
     cv::subtract(frame, mask, result); 
    } 
    else { 
     addFrame(frame); 
    } 
    return result; 
} 

最后但并非最不重要的,你可以使用 标量和(常量垫& MTX) 用于计算像素之和决定它是否与它的灯光的框架。

+0

非常感谢你ping(“,) – user854576

+3

@ user854576如果这是一个正确的答案,你应该很好,并接受它。见[本页](http://stackoverflow.com/faq#howtoask)在常见问题如何接受答案。 –