OpenCV中的背景扣除(C++)

use*_*576 8 c++ opencv image-processing background-subtraction

我想实现一个背景平均方法.我在一秒钟内拍摄了50帧图像,其中一些帧包含闪电,我想将其提取为前景.框架采用固定式摄像机拍摄,框架采用灰度级.我想做的是:

  1. 获取背景模型
  2. 然后,将每个帧与背景模型进行比较,以确定该帧中是否有光照.

我阅读了一些关于如何通过使用cvAcc()实现这一目标的文档,但我很难理解如何做到这一点.我将非常感谢一段代码,它引导我和文档链接,可以帮助我理解如何实现这一点.

提前感谢你.

pin*_*ing 19

我们在其中一个项目中完成了同样的任务.

为了获得背景模型,我们只需创建一个类BackgroundModel,捕获第一个(比方说)50帧并计算平均帧以避免背景模型中的像素错误.

例如,如果从相机获得8位灰度图像(CV_8UC1),则使用CV_16UC1初始化模型以避免剪切.

cv::Mat model = cv::Mat(HEIGHT, WIDTH, CV_16UC1, cv::Scalar(0));
Run Code Online (Sandbox Code Playgroud)

现在,等待第一帧计算模型,只需将每个帧添加到模型中并计算接收的帧数.

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

void createMask() {
    cv::convertScaleAbs(model, mask, 1.0 / learnedFrames);
    mask.convertTo(mask, CV_8UC1);
}
Run Code Online (Sandbox Code Playgroud)

现在,您只需将所有帧通过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;
}
Run Code Online (Sandbox Code Playgroud)

最后但并非最不重要的是,您可以使用标量和(const Mat&mtx)来计算像素总和并确定它是否是带有灯光的帧.

  • @ user854576如果这是一个正确的答案,你应该很好并接受它.请参阅常见问题解答中的[本页](http://stackoverflow.com/faq#howtoask)如何接受答案. (3认同)