C/C++开发,opencv内置背景减除算法与运动检测

目录

一、c++ opencv 背景减除算法内置算法

1.1 MOG2算法

1.2 KNN算法

二、完整案例实现

2.1 程序代码

2.2 程序编译及输出


一、c++ opencv 背景减除算法内置算法

        背景减除算法的目标是将视频帧中的背景与前景(通常是移动的对象)分离。OpenCV提供MOG2(Gaussian Mixture-based Background/Foreground Segmentation)和KNN(K-Nearest Neighbors)等背景减除算法,他们都派生于BackgroundSubtractor,各派生类需要重写父类的apply函数。

CV_WRAP virtual void apply(InputArray image, OutputArray fgmask, double learningRate=-1) = 0;

这些内置算法,来自video模块的modules\video\include\opencv2\video\background_segm.hpp。

1.1 MOG2算法

        BackgroundSubtractorMOG2是基于高斯混合模型(Gaussian Mixture Model, GMM)的背景减除算法。它适用于处理具有动态背景的场景,如对于缓慢变化的光照条件和动态背景(如摇曳的树叶或水面波纹)也具有一定的鲁棒性。

        apply()函数是BackgroundSubtractorMOG2类的一个重写父类BackgroundSubtractor的成员函数,它接受一个输入帧(frame),并输出一个前景掩模(fgMaskMOG2)。前景掩模是一个灰度图像,其中背景像素接近黑色(值接近0),而前景(移动的对象)像素则更亮(值接近255)。

1.2 KNN算法

        BackgroundSubtractorKNN是基于K近邻(K-Nearest Neighbors, KNN)算法的背景减除器。这种算法对于处理突然的光照变化或复杂的动态背景可能更为有效。

        与BackgroundSubtractorMOG2的示例类似。apply()函数是BackgroundSubtractorKNN类的一个重写父类BackgroundSubtractor的成员函数,它接受一个输入帧(frame),并输出一个前景掩模(fgMaskKNN)。前景掩模是一个灰度图像,其中背景像素接近黑色(值接近0),而前景(移动的对象)像素则更亮(值接近255)。

   BackgroundSubtractorKNN类有几个可以调整的参数,如nframes(用于算法训练的初始帧数)、dist2Threshold(前景检测中的距离阈值)等。这些参数可以通过setNFrames()setDist2Threshold()等成员函数进行设置。

二、完整案例实现

2.1 程序代码

        main.cpp代码,先读取一段视频或打开摄像头,并创建一个BackgroundSubtractorMOG2实例或BackgroundSubtractorKNN实例。然后,在读取视频帧的循环中,使用apply()方法将当前帧与背景模型进行比较,并生成一个前景掩模(fgMask)。这个掩模是一个与输入帧相同大小的灰度图像,其中背景像素接近黑色(值接近0),而前景像素则更亮(值接近255)。

#include <opencv2/opencv.hpp>  
#include <vector>
#include <iostream>

int main(int argc, char* argv[]) 
{  
    cv::VideoCapture capture; // 视频捕获对象 
    if(argc< 2){ 
        capture.open(0);        //0是摄像头的索引
	}else{        
        // 加载视频 
        capture.open(argv[1]);  //如果是视频文件,则传入文件路径  
    }
    // cv::VideoCapture capture(0); // 0是摄像头的索引,如果是视频文件,则传入文件路径  
    if (!capture.isOpened()) {  
        std::cerr << "Error opening video stream or file" << std::endl;  
        return -1;  
    }  
	
    // 创建背景减除器对象  
    cv::Ptr<cv::BackgroundSubtractorMOG2> pBackSub = cv::createBackgroundSubtractorMOG2(); 
    // cv::Ptr<cv::BackgroundSubtractorKNN> pBackSub = cv::createBackgroundSubtractorKNN();
  
    cv::Mat frame, fgMask;  
  
    while (capture.read(frame)) {  
        if (frame.empty())  
            break;  
  
        // 应用背景减除  
        pBackSub->apply(frame, fgMask);  
  
        // 可选:进行一些形态学操作来去除噪声  
        cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3));  
        morphologyEx(fgMask, fgMask, cv::MORPH_OPEN, kernel);  
  
        // 显示结果  
        imshow("Frame", frame);  
        imshow("FG Mask", fgMask);  
        // 对检测图像进行判断
  
        char c = (char) cv::waitKey(30);  
        if (c == 27) break; // 按ESC退出  
    }  
  
    capture.release();  
    cv::destroyAllWindows();  
    return 0;  
}
2.2 程序编译及输出

        本文是采用win系统下,opencv采用MinGW编译的静态库(C/C++开发,win下OpenCV+MinGW编译环境搭建_opencv mingw-CSDN博客),建立makefile:

#/bin/sh
#win32
CX= g++ -DWIN32 
#linux
#CX= g++ -Dlinux 

BIN 		:= ./
TARGET      := Motion_detection.exe
FLAGS		:= -std=c++11 -static
SRCDIR 		:= ./
#INCLUDES
INCLUDEDIR 	:= -I"../../opencv_MinGW/include" -I"./"
#-I"$(SRCDIR)"
staticDir   := ../../opencv_MinGW/x64/mingw/staticlib/
#LIBDIR		:= $(staticDir)/libopencv_world460.a\
#			   $(staticDir)/libade.a \
#			   $(staticDir)/libIlmImf.a \
#			   $(staticDir)/libquirc.a \
#			   $(staticDir)/libzlib.a \
#			   $(wildcard $(staticDir)/liblib*.a) \
#			   -lgdi32 -lComDlg32 -lOleAut32 -lOle32 -luuid 
#opencv_world放弃前,然后是opencv依赖的第三方库,后面的库是MinGW编译工具的库

LIBDIR 	    := -L $(staticDir) -lopencv_world460 -lade -lIlmImf -lquirc -lzlib \
				-llibjpeg-turbo -llibopenjp2 -llibpng -llibprotobuf -llibtiff -llibwebp \
				-lgdi32 -lComDlg32 -lOleAut32 -lOle32 -luuid 
source		:= $(wildcard $(SRCDIR)/*.cpp) 

$(TARGET) :
	$(CX) $(FLAGS) $(INCLUDEDIR) $(source)  -o $(BIN)/$(TARGET) $(LIBDIR)

clean:
	rm  $(BIN)/$(TARGET)

编译如下:

程序运行输出如下,本测试没有指定视频图像,采用笔记本的摄像头抓取视频:    

PS:读者可以调整参数、图像光影效果等验证测试BackgroundSubtractorKNN方法。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

py_free-物联智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值