赞
踩
目录
背景减除算法的目标是将视频帧中的背景与前景(通常是移动的对象)分离。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。
BackgroundSubtractorMOG2
是基于高斯混合模型(Gaussian Mixture Model, GMM)的背景减除算法。它适用于处理具有动态背景的场景,如对于缓慢变化的光照条件和动态背景(如摇曳的树叶或水面波纹)也具有一定的鲁棒性。
apply()
函数是BackgroundSubtractorMOG2
类的一个重写父类BackgroundSubtractor的成员函数,它接受一个输入帧(frame
),并输出一个前景掩模(fgMaskMOG2
)。前景掩模是一个灰度图像,其中背景像素接近黑色(值接近0),而前景(移动的对象)像素则更亮(值接近255)。
BackgroundSubtractorKNN
是基于K近邻(K-Nearest Neighbors, KNN)算法的背景减除器。这种算法对于处理突然的光照变化或复杂的动态背景可能更为有效。
与BackgroundSubtractorMOG2
的示例类似。apply()
函数是BackgroundSubtractorKNN
类的一个重写父类BackgroundSubtractor的成员函数,它接受一个输入帧(frame
),并输出一个前景掩模(fgMaskKNN
)。前景掩模是一个灰度图像,其中背景像素接近黑色(值接近0),而前景(移动的对象)像素则更亮(值接近255)。
BackgroundSubtractorKNN
类有几个可以调整的参数,如nframes
(用于算法训练的初始帧数)、dist2Threshold
(前景检测中的距离阈值)等。这些参数可以通过setNFrames()
、setDist2Threshold()
等成员函数进行设置。
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;
- }
本文是采用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方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。