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完成运动目标捕捉的详细攻略,希望对您有所帮助。

阅读剩余 79%

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

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

相关文章

  • 深入理解c++常成员函数和常对象

    以下是深入理解C++常成员函数和常对象的完整攻略: 1. 常成员函数 1.1 常成员函数的定义和声明 C++ 中的类成员函数,如果不加修饰,都可以被修改其所属对象的数据成员和调用其它成员函数。但是有时候我们希望某个成员函数只能被调用,但不能修改对象的数据成员,这个时候就需要使用常成员函数。常成员函数在函数声明的后面加上 const 关键字。 常成员函数的声明…

    C 2023年5月22日
    00
  • C语言随机数生成教程(rand和srand用法)

    C语言中的rand()函数用于生成随机数,下面详细讲解C语言随机数生成教程并介绍rand()和srand()的用法。 一、rand()函数 rand()函数用于生成随机数,该函数在头文件stdlib.h中定义,它没有参数,返回值为一个整数,该整数为随机生成的伪随机数,取值范围为0到RAND_MAX(通常为32767)。 下面的例子将生成1到100之间的随机整…

    C 2023年5月23日
    00
  • 汇编语言超浓缩教程

    汇编语言超浓缩教程攻略 什么是汇编语言 汇编语言是一种低级程序语言,它使用助记符来代替机器指令,通过CPU的解释和执行,最终实现计算机指令的功能。汇编语言通常用于嵌入式系统、游戏开发、操作系统等领域,对计算机底层原理有深入的了解和研究能力。 学习汇编语言的必备条件 学习汇编语言需要具备一些必备的条件: 计算机基础知识,包括计算机组成原理、操作系统基础和计算机…

    C 2023年5月23日
    00
  • Java日常练习题,每天进步一点点(62)

    介绍“Java日常练习题,每天进步一点点(62)”题目攻略。 题目描述 题目链接:https://mp.weixin.qq.com/s/Ls8_zCvCkCWOD0j1K4Zp_g 攻略 题目要求在给定整数列表中,找到最大的偶数。以下是解题思路。 步骤 1: 创建整数列表 我们将使用以下代码创建一个包含整数的列表。 List<Integer> n…

    C 2023年5月22日
    00
  • C语言实现四窗口聊天

    C语言实现四窗口聊天攻略 简介 在本文中,我们将使用C语言实现一个四窗口聊天程序。该程序可以启动四个窗口,每个窗口都可以像聊天室一样发送和接收消息。 准备工作 1. 确认操作系统 在开始编写程序之前,我们需要确认使用的操作系统是否支持多窗口。大多数现代操作系统,如Windows, Mac OS, 和Linux,都支持多窗口,因此在这些操作系统上实现四窗口程序…

    C 2023年5月24日
    00
  • C 程序 八进制转换为二进制

    让我来为您详细介绍C程序如何将八进制转换为二进制。 1. 简介 如何将八进制转换为二进制这个问题,实际上是一个将任意进制的数转换为另一种进制的问题,只不过这里以八进制和二进制转换为例子来说明。要将八进制数转换为二进制,我们需要将八进制数的每一位先转换为二进制,再将每个二进制数位连接起来,最终得到二进制数。 2. 具体步骤 具体的转换步骤如下: 将每个八进制位…

    C 2023年5月9日
    00
  • c语言实现输入一组数自动从大到小排列的实例代码

    下面我会为您详细讲解C语言实现输入一组数自动从大到小排列的实例代码,步骤如下: 步骤一:定义数组 定义一个整型数组,这里我们定义为arr,并定义数组大小为10。 int arr[10]; 步骤二:输入数据 通过循环语句输入10个数字,这里我们使用for循环,如下所示: for(int i = 0; i < 10; i++){ printf("…

    C 2023年5月24日
    00
  • C语言实现简单的推箱子游戏

    C语言实现简单的推箱子游戏攻略 游戏规则 推箱子游戏是一款智力类游戏,玩家需要通过推动木箱到指定的位置来完成游戏,游戏难度逐渐增加。 游戏规则如下: 玩家可以通过键盘上的 ↑、↓、←、→ 控制人物(P)的移动,人物可以向四个方向行走; 如果人物面对着一个箱子(O),玩家按下操作键,木箱就会朝着人物所面对的方向移动一个格子; 箱子在游戏界面移动的过程中,必须始…

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