openFrameworks下实现OpenCV MOG/MOG2背景减除器及报错解决问询
openFrameworks 实现MOG/MOG2背景减除的解决方案
问题根源
抽象类实例化报错的核心原因是老旧的第三方库适配的是OpenCV 2/3的旧API,openFrameworks 0.11.2内置的OpenCV版本为4.x,OpenCV 3+版本中背景减除器已改为抽象类,必须通过静态工厂方法create()创建实例,旧库直接调用构造函数实例化的写法不再兼容。
推荐实现方法(无需第三方库,基于OF内置ofxCv)
openFrameworks 0.11+版本自带的核心附加库ofxCv已完整封装OpenCV接口,可直接调用官方的背景减除能力,无需依赖第三方废弃库。
核心实现步骤
- 第一步:在项目属性中添加内置附加库
ofxCv - 第二步:在
ofApp.h头文件中声明相关变量
#include "ofxCv.h" class ofApp : public ofBaseApp{ // 其他原有声明 private: ofVideoGrabber grabber; // 可替换为ofVideoPlayer读取本地视频 cv::Ptr<cv::BackgroundSubtractorMOG2> mog2; cv::Mat fgMask; // 存储前景掩码结果 };
- 第三步:在
setup()方法中初始化实例
void ofApp::setup(){ grabber.setup(640, 480); // 参数说明:历史帧数量、像素方差阈值、是否检测阴影 mog2 = cv::createBackgroundSubtractorMOG2(500, 16, true); // 如需使用MOG,替换为下面的代码即可 // mog2 = cv::createBackgroundSubtractorMOG(); }
- 第四步:在
update()方法中逐帧处理画面
void ofApp::update(){ grabber.update(); if(grabber.isFrameNew()){ cv::Mat frame = ofxCv::toCv(grabber.getPixels()); // 第三个参数为学习率:0为固定背景不更新,1为每帧完全重置背景,常规使用取值0.001-0.01即可 mog2->apply(frame, fgMask, 0.001); } }
- 第五步:在
draw()方法中渲染结果
void ofApp::draw(){ grabber.draw(0, 0); ofImage fgImg; ofxCv::toOf(fgMask, fgImg); fgImg.draw(640, 0); }
第三方库适配方案
如果必须使用原有第三方库,仅需修改库源码的不兼容部分即可:
- 找到库头文件中
cv::BackgroundSubtractorMOG2类型的成员变量声明,将类型修改为cv::Ptr<cv::BackgroundSubtractorMOG2> - 找到库中初始化实例的代码,将直接调用构造函数的写法替换为
cv::createBackgroundSubtractorMOG2()工厂方法 - 将所有原有调用该变量成员方法的
.操作符替换为->操作符,修改完成后即可正常编译运行
内容的提问来源于stack exchange,提问作者rojele
相关产品推荐
相关产品推荐

