【opencv】教程代码 —video(3) 视频背景剔除

bg_sub.cpp

这段代码的功能是把视频中的背景和前景分离,提取出前景的运动物体 。根据用户选择的不同的模式,可以选择基于MOG2或者基于KNN的方法 来进行背景减除。在处理每一帧图像的过程中,首先使用背景减除模型对图像帧进行处理,得到一个前景掩码,该掩码中包含了所有被认为是前景的像素。然后将处理后的掩码图像和原始帧同时显示出来 。通过这种方式,用户能够清楚看到前景移动物体被成功地从背景中分离出来,这个过程是实时的。

cpp 复制代码
/**
 * @file bg_sub.cpp
 * @brief 背景减除教程样例代码
 * @author Domenico D. Bloisi
 */


#include <iostream>  // 引入 C++ 的输入输出流库
#include <sstream>  // 引入字符串流,它是 iostream 的一部分,提供了方便的字符串输入和输出功能
#include <opencv2/imgcodecs.hpp>  // 引入 OpenCV 的图像编解码模块,用于图像的读取和保存
#include <opencv2/imgproc.hpp>  // 引入 OpenCV 的图像处理模块,包含很多图像处理的功能
#include <opencv2/videoio.hpp>  // 引入 OpenCV 的视频 IO 模块,用于视频保存和读取、以及本机摄像头的访问
#include <opencv2/highgui.hpp>  // 引入 OpenCV 的高级 GUI 模块,用于创建界面显示图像
#include <opencv2/video.hpp>  // 引入 OpenCV 的视频分析模块,包含了许多常见的视频分析算法,比如对象跟踪、运动估计等


using namespace cv;  // 使用 OpenCV 命名空间
using namespace std;


const char* params
    = "{ help h         |           | Print usage }"
      "{ input          | vtest.avi | Path to a video or a sequence of image }"
      "{ algo           | MOG2      | Background subtraction method (KNN, MOG2) }";


int main(int argc, char* argv[])  
{
    // 命令行参数解析
    CommandLineParser parser(argc, argv, params);
    string about_message = "This program shows how to use background subtraction methods provided by "
                  " OpenCV. You can process both videos and images.\n";
    parser.about(about_message);


    if (parser.has("help"))   // 如果有帮助信息
    {
        parser.printMessage();  // 打印使用帮助信息
    }


    // 创建背景减除对象
    Ptr<BackgroundSubtractor> pBackSub;
     //根据输入确定使用 KNN 还是 MOG2 
    if (parser.get<String>("algo") == "MOG2")
        pBackSub = createBackgroundSubtractorMOG2();
    else
        pBackSub = createBackgroundSubtractorKNN();


    // 输入视频
    VideoCapture capture( samples::findFile(parser.get<String>("input")) );
    if (!capture.isOpened()){  
        cerr << "Unable to open: " << parser.get<String>("input") << endl;
        return 0;
    }
    Mat frame, fgMask;  // 定义图像矩阵,用于读取视频帧以及存储背景减除图像
    while (true) {
        capture >> frame;  // 读取一帧
        if (frame.empty())
            break;


        // 更新背景模型
        pBackSub->apply(frame, fgMask);
        
        // 在当前帧上显示帧编号
        rectangle(frame, cv::Point(10, 2), cv::Point(100,20), cv::Scalar(255,255,255), -1);
        // 在 frame 上画一个白色矩形,左上角坐标为(10, 2),右下角坐标为(100, 20),颜色为白色(即 (255,255,255))。
        
        stringstream ss;
        ss << capture.get(CAP_PROP_POS_FRAMES);
        // 用 stringstream 将视频的当前帧数转换为字符串。
        
        string frameNumberString = ss.str();
        // 将帧数从 stringstream 转换为 string。
        
        putText(frame, frameNumberString.c_str(), cv::Point(15, 15), FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
        // 在 frame 上的(15, 15)位置用黑色字体输出当前的帧数。
        // 显示当前帧和背景掩码
        imshow("Frame", frame);
        imshow("FG Mask", fgMask);
       
        int keyboard = waitKey(30);  // 获取键盘输入
        if (keyboard == 'q' || keyboard == 27)
            break;
    }
    return 0;
}
相关推荐
sight-ai1 分钟前
超越基础:SightAI 智能路由与多模型选择实战
人工智能·开源·大模型·api
OpenVINO 中文社区2 分钟前
端侧AI创新挑战赛正式启动
人工智能
取酒鱼食--【余九】9 分钟前
深度学习经典网络解析:ResNet
网络·人工智能·深度学习·神经网络·resnet·卷积神经网络·残差神经网络
搞科研的小刘选手13 分钟前
【通信&网络安全主题】第六届计算机通信与网络安全国际学术会议(CCNS 2025)
大数据·人工智能·网络安全·vr·通信工程·网络技术·计算机工程
qq_314810811 小时前
三重变革:数字革命、地缘重构与生态危机
人工智能
武子康1 小时前
AI-调查研究-104-具身智能 从模型训练到机器人部署:ONNX、TensorRT、Triton全流程推理优化详解
人工智能·gpt·ai·性能优化·机器人·tensorflow·具身智能
灵犀物润1 小时前
机器宠物建模的第一步:基础形体搭建(Blocking)
人工智能·机器人·宠物
人机与认知实验室1 小时前
触摸大语言模型的边界
人工智能·深度学习·机器学习·语言模型·自然语言处理
神的孩子都在歌唱2 小时前
PostgreSQL 向量检索方式(pgvector)
数据库·人工智能·postgresql
ARM+FPGA+AI工业主板定制专家2 小时前
基于Jetson+GMSL AI相机的工业高动态视觉感知方案
人工智能·机器学习·fpga开发·自动驾驶