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++深复制和浅复制讲解

    C++中的复制操作包含深复制和浅复制两种方式。简单来说,浅复制只复制指针而不复制指针指向的内存空间,而深复制会复制指针和指针指向的内存空间。 一般情况下,我们需要使用深复制,以避免浅复制造成指针指向错误的情况。 深复制的实现方式 在C++中,可以通过使用拷贝构造函数和赋值操作符实现深复制。 拷贝构造函数 拷贝构造函数是一种特殊的构造函数,用于在创建对象时,用…

    C 2023年5月23日
    00
  • C语言详细分析讲解流程控制语句用法

    C语言详细分析讲解流程控制语句用法 在C语言中,流程控制语句可以控制程序的执行顺序,根据不同的条件分支执行不同的语句,还可以循环执行语句。本文将详细分析C语言中常用的流程控制语句的用法,包括条件语句和循环语句。 条件语句 if语句 if语句用于判断一个条件是否成立,如果条件成立则执行指定的代码块。if语句的一般结构如下: if(条件) { 满足条件时执行的语…

    C 2023年5月30日
    00
  • C语言实现简单的图书管理系统

    C语言实现简单的图书管理系统攻略 一、前期准备 在实现图书管理系统之前,需要先了解以下基础知识: 结构体的定义和使用 文件的读写操作 指针的使用 掌握以上基础知识,才能顺利实现图书管理系统。 二、功能需求 我们要实现的图书管理系统需要以下功能模块: 添加图书信息(包括图书名称、作者、价格等信息) 删除图书信息 修改图书信息 查找图书信息 显示所有图书信息 三…

    C 2023年5月22日
    00
  • C语言示例讲解do while循环语句的用法

    C语言示例讲解do while循环语句的用法 什么是do while循环语句 do while循环语句是一种循环结构,它先执行一次循环体,再根据判断条件是否成立来决定是否继续执行循环体。与while循环语句不同的是,do while循环语句至少会执行一次循环体。 do while循环语句的基本格式如下: do { 循环体语句; } while (判断条件);…

    C 2023年5月22日
    00
  • C语言实现模拟银行系统

    C语言实现模拟银行系统攻略 概述 本文将介绍如何采用C语言实现简单的模拟银行系统。该系统主要包含账户管理、存款、取款、转账、查询余额等功能。 系统设计 账户结构体 一个账户包含三个属性:账户号、账户余额和持有者姓名。定义一个结构体表示账户: typedef struct account_t { int account_no; //账户号 float bala…

    C 2023年5月23日
    00
  • Cs全面介绍与问题解答

    Cs全面介绍与问题解答 什么是Cs? Cs是Counter-Strike的缩写,是一款经典的多人游戏。游戏的核心玩法包括恐怖分子与反恐精英之间的对抗。两支队伍都会获得特定的任务,如拆弹、营救人质等。游戏时间较短,每局游戏通常为1分钟到3分钟。 Cs的游戏模式 团队对抗:恐怖分子与反恐精英之间的经典对抗。 成人礼:一名护送者护送一名新兵从一个地点到另一个地点,…

    C 2023年5月22日
    00
  • Java实现生成JSON字符串的三种方式分享

    以下是 “Java实现生成JSON字符串的三种方式分享” 的完整攻略: 一、使用Java的JSONObject实现 在Java中,可以使用JSONObject类来生成JSON字符串,该类定义了用于创建和操作JSON对象的方法。下面是一个示例: import org.json.*; public class JSONDemo { public static v…

    C 2023年5月23日
    00
  • 02-VS调试以及Qt基本使用

    VS调试以及Qt基本使用 1.汇编语言 1.1 VS中C语言嵌套汇编代码(了解) #include <stdio.h> int main() { //定义整型变量a, b, c int a; int b; int c; __asm { mov a, 3 //3的值放在a对应内存的位置 mov b, 4 //4的值放在b对应内存的位置 mov ea…

    C语言 2023年4月18日
    00
合作推广
合作推广
分享本页
返回顶部