C++如何调用opencv完成运动目标捕捉详解

C++如何调用OpenCV完成运动目标捕捉,以下是详细攻略。

准备工作

在使用OpenCV前,需要安装OpenCV库。可以从OpenCV的官方网站(https://opencv.org/)下载,安装后需要在编译时链接到相关的库文件。

加载视频文件

首先需要加载视频文件,使用OpenCV中的cv::VideoCapture类。该类的构造函数接受视频文件路径作为参数,用于打开视频文件。

#include <opencv2/opencv.hpp>

using namespace cv;

int main()
{
    // 打开视频文件
    VideoCapture cap("video.mp4"); 

    return 0;
}

读取每一帧图像

使用cv::VideoCapture类的read方法,可以读取视频文件的每一帧图像,并用cv::Mat类型对象保存。

// 打开视频文件
VideoCapture cap("video.mp4");

Mat frame; // 保存读取到的每一帧图像
while (cap.read(frame)) // 循环读取每一帧图像
{
    // 处理每一帧图像
    ...
}

提取运动目标

首先将第一帧图像作为背景帧,然后用当前帧图像与背景帧进行比较,计算差分图像,并对差分图像进行阈值处理,得到二值图像。最后使用cv::findContours函数查找二值图像中的轮廓。

Mat frame, foreground, background;
bool firstFrame = true;
while (cap.read(frame)) 
{
    if (firstFrame)
    {
        // 第一帧作为背景
        frame.copyTo(background);
        firstFrame = false;
        continue;
    }

    // 计算差分图像
    absdiff(frame, background, foreground);

    // 应用阈值,得到二值图像
    threshold(foreground, foreground, 25, 255, THRESH_BINARY);

    // 查找轮廓
    vector<vector<Point> > contours;
    findContours(foreground, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    ...
}

绘制边框

在找到轮廓后,可以绘制边框,将运动目标框住。

Mat frame, foreground, background;
bool firstFrame = true;
while (cap.read(frame)) 
{
    if (firstFrame)
    {
        // 第一帧作为背景
        frame.copyTo(background);
        firstFrame = false;
        continue;
    }

    // 计算差分图像
    absdiff(frame, background, foreground);

    // 应用阈值,得到二值图像
    threshold(foreground, foreground, 25, 255, THRESH_BINARY);

    // 查找轮廓
    vector<vector<Point> > contours;
    findContours(foreground, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    // 绘制边框
    for (int i = 0; i < contours.size(); i++)
    {
        Rect rect = boundingRect(contours[i]);
        rectangle(frame, rect, Scalar(0, 255, 0), 2);
    }

    ...
}

示例1:检测运动目标并保存图像

以下代码演示如何检测运动目标,并在运动目标框住时保存图像。

#include <opencv2/opencv.hpp>

using namespace cv;

int main()
{
    // 打开视频文件
    VideoCapture cap("video.mp4");

    Mat frame, foreground, background;
    bool firstFrame = true;
    int count = 0; // 计数器,用于生成文件名
    while (cap.read(frame)) 
    {
        if (firstFrame)
        {
            // 第一帧作为背景
            frame.copyTo(background);
            firstFrame = false;
            continue;
        }

        // 计算差分图像
        absdiff(frame, background, foreground);

        // 应用阈值,得到二值图像
        threshold(foreground, foreground, 25, 255, THRESH_BINARY);

        // 查找轮廓
        vector<vector<Point> > contours;
        findContours(foreground, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

        // 绘制边框,保存图像
        for (int i = 0; i < contours.size(); i++)
        {
            Rect rect = boundingRect(contours[i]);

            // 保存运动目标图像
            if (rect.area() > 1000)
            {
                Mat roi = frame(rect);
                char filename[50];
                sprintf(filename, "frame%d.jpg", count++);
                imwrite(filename, roi);
            }

            rectangle(frame, rect, Scalar(0, 255, 0), 2);
        }

        imshow("Motion Detection", frame);
        waitKey(30);
    }

    return 0;
}

示例2:检测运动目标并发出警报

以下代码演示如何检测运动目标,并在运动目标框住时发出警报。

#include <opencv2/opencv.hpp>

using namespace cv;

int main()
{
    // 打开视频文件
    VideoCapture cap("video.mp4");

    Mat frame, foreground, background;
    bool firstFrame = true;
    while (cap.read(frame)) 
    {
        if (firstFrame)
        {
            // 第一帧作为背景
            frame.copyTo(background);
            firstFrame = false;
            continue;
        }

        // 计算差分图像
        absdiff(frame, background, foreground);

        // 应用阈值,得到二值图像
        threshold(foreground, foreground, 25, 255, THRESH_BINARY);

        // 查找轮廓
        vector<vector<Point> > contours;
        findContours(foreground, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

        // 绘制边框,发出警报
        bool motionDetected = false;
        for (int i = 0; i < contours.size(); i++)
        {
            Rect rect = boundingRect(contours[i]);

            if (rect.area() > 1000)
            {
                motionDetected = true;
            }

            rectangle(frame, rect, Scalar(0, 255, 0), 2);
        }

        if (motionDetected)
        {
            // 发出警报
            putText(frame, "Motion Detected!", Point(10, 30), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2);
        }

        imshow("Motion Detection", frame);
        waitKey(30);
    }

    return 0;
}

以上是C++如何调用OpenCV完成运动目标捕捉的详细攻略,希望对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++如何调用opencv完成运动目标捕捉详解 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C 和 Dart 的区别

    C 和 Dart 是两种不同的编程语言,它们各自有着不同的特点和用途。在这里,我将详细讲解 C 和 Dart 的区别及其使用攻略。 C 和 Dart 的基本介绍 C 语言 C 语言是一种广泛使用的高级程序设计语言,具有高效、简洁、快速和可移植等特点。C 语言可以用来开发操作系统、编写驱动程序、实现嵌入式系统和游戏引擎等需求。 Dart 语言 Dart 语言是…

    C 2023年5月10日
    00
  • 分页类,异常类

    下面是详细讲解“分页类,异常类”的完整攻略: 分页类 分页类通常用于对大量数据进行分页展示,其中包含以下属性: 当前页码(current_page) 总页数(total_page) 数据总数(total_count) 每页数据量(per_page) 分页类中的核心方法为 paginate() 方法,该方法会接收两个参数: $query:查询数据所用的 Que…

    C 2023年5月23日
    00
  • 如何理解C++指针常量和常量指针

    下面给你详细讲解如何理解C++指针常量和常量指针。 1. 指针常量 1.1 概念介绍 指针常量是指一个指针被定义为常量(值不能被改变),而指针所指向的变量的值可以变化。在定义指针常量时,必须把指针初始化为某个地址。 1.2 示例说明 以下是一个指针常量的示例: #include <iostream> using namespace std; in…

    C 2023年5月23日
    00
  • vs2019+win10配置boost库的详细教程

    下面我将为你详细讲解如何在vs2019+win10上配置boost库。 环境准备 在开始配置boost库之前,需要先准备好以下环境: windows10操作系统 Visual Studio 2019 IDE boost库源代码 建议下载完整版的boost库源代码,并解压到一个方便访问的目录下。 配置boost库 1. 编译Boost库 首先需要使用CMD进入…

    C 2023年5月22日
    00
  • log4j2 项目日志组件的实例代码

    以下是详细讲解“log4j2 项目日志组件的实例代码”的完整攻略。 什么是log4j2 log4j2是一个Java日志框架,可以提供高效灵活的日志记录服务,供各种Java应用程序使用。它是Apache软件基金会下的一个开源项目,其具备下列特点: 多种输出方式:文件、控制台、数据库等 丰富的API:易于使用、易于扩展 完善的日志级别:支持丰富的日志级别,能够控…

    C 2023年5月22日
    00
  • vue中如何实现复制内容到剪切板详解

    让我们来详细讲解一下“vue中如何实现复制内容到剪贴板”的完整攻略。 第一步:安装依赖 在使用vue实现复制内容到剪贴板之前,需要安装一个剪贴板操作插件clipboard(也可以使用其他类似插件)。 使用npm在项目中安装clipboard插件: npm i clipboard –save 第二步:创建一个指令 在Vue中实现复制内容到剪贴板需要创建一个指…

    C 2023年5月23日
    00
  • C++中string类的常用方法实例总结

    C++中string类的常用方法实例总结 1. 概述 在C++中,字符串类型数据可以使用char数组和string类来实现。虽然char数组是C语言中常用的字符串表示方式,但是由于其操作起来非常麻烦,因此C++中更推荐使用string类。 C++中的string类提供了多种方法来处理字符串数据。本文将从常用方法的角度,总结并讲解C++中string类的一些常…

    C 2023年5月23日
    00
  • QT基于TCP实现网络聊天室程序

    首先我们需要准备QT的开发环境,并且熟悉QT的基本开发流程。在此不再赘述。 创建QT项目 首先需要创建一个QT项目,选择一个QT GUI Application即可。在创建过程中,选择需要包含网络模块。 添加TCP服务器 我们需要添加一个TCP服务器来实现网络聊天室。在创建TCP服务器时,需要指定服务器绑定的IP地址和端口号。以下是示例代码: QTcpSer…

    C 2023年5月30日
    00
合作推广
合作推广
分享本页
返回顶部