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

yizhihongxing

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语言实现字符串匹配KMP算法

    C语言实现字符串匹配KMP算法 什么是KMP算法 字符串匹配是计算机科学中的一个基本问题,给定两个文本串A和B,其中A称为主串,B称为模式串,现在要查找B在A中第一次出现的位置,这就是字符串匹配的问题。 KMP算法(Knuth-Morris-Pratt算法)是一种字符串匹配算法,它利用了字符串的局部匹配特性来提升匹配效率。与暴力匹配算法相比,KMP算法的时间…

    C 2023年5月22日
    00
  • 创建安全的个人Web服务器(winserver2003、sql2000)

    创建安全的个人Web服务器(winserver2003、sql2000)需要遵循以下几个步骤: 1. 购买并设置服务器 首先需要购买一台Windows Server 2003的服务器,建议使用具有防火墙和其他安全功能的云服务器。安装操作系统后,需要进行基本设置并保证防火墙开启并设置正确的端口规则。 2. 安装IIS Web服务器和ASP.NET 在安装完操作…

    C 2023年5月23日
    00
  • 详解C++程序中定义struct结构体的方法

    下面我将详细讲解如何在C++程序中定义struct结构体。 1. 概述 在C++中,struct是一种用户自定义的数据类型,它可以将多个不同类型的数据成员组合在一起,形成一个数据结构。在C++中,我们可以使用struct关键字来定义一个结构体,然后在程序中实例化一个结构体对象,可以使用结构体对象来访问结构体中的数据成员,从而完成对数据的处理。 2. 定义结构…

    C 2023年5月30日
    00
  • php格式化json函数示例代码

    PHP格式化JSON函数示例代码 在PHP中,有一个很方便的函数可以帮助我们格式化JSON字符串。这个函数就是json_encode()。它使用非常简单,只需要将我们要格式化的JSON对象传入函数中即可。 例如,我们有一个如下所示的JSON字符串: { "name": "Tom", "age": 3…

    C 2023年5月23日
    00
  • C语言实现学生管理系统的源码分享

    C语言实现学生管理系统的源码分享攻略 1. 确定需求及功能设计 首先要确定学生管理系统的需求和功能,例如添加学生信息、删除学生信息、查询学生信息、更新学生信息等功能,然后进行功能及界面的设计。 2. 编写代码 在得到需求及功能设计后,就可以开始编写代码了。可以用C语言或C++语言编写学生管理系统的源码,编程编辑器一般可以选择gcc或VS Code等。 代码示…

    C 2023年5月23日
    00
  • 全面了解Java中对于异常的捕捉方法

    全面了解Java中对于异常的捕捉方法 在Java中,异常处理是一个非常重要的概念,因为在编写代码时总会遇到一些意外情况,如文件不存在、网络连接断开等等,这些异常的出现会导致程序运行崩溃,无法完成预定任务,影响程序的可靠性和稳定性。Java提供了一套完善的异常处理机制来处理这些异常,可以使程序在出现异常的情况下依然保持正常运行,从而更好地保证程序的正确性。 J…

    C 2023年5月23日
    00
  • C语言中如何进行代码优化?

    代码优化是提高程序性能和运行效率的必要手段,也是编程中一个重要的环节。C语言中进行代码优化可以采取如下措施: 1. 优化算法 在编程中,算法的选择对程序性能影响较大,常见的提高算法效率的方法有: 1.1 使用空间换时间的算法 如果内存空间充足的情况下,可以采用空间复杂度高但时间复杂度低的算法,避免使用时间复杂度高但空间复杂度低的算法,从而提高程序性能。 例如…

    C 2023年4月27日
    00
  • C/C++的文件IO函数你知道吗

    C/C++的文件IO函数攻略 什么是文件IO? 文件IO(Input/Output)指的是使用程序对文件进行读写的操作。对于C/C++语言而言,文件IO是一个非常基础和常用的操作。 文件IO函数 fopen函数 用于打开一个文件,并返回一个文件指针(FILE*)。如果打开成功,则返回指向文件指针的地址,否则返回NULL。 FILE *fopen(const …

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