opencv动态目标检测

news2024/12/25 2:16:57

文章目录

  • 前言
  • 一、效果展示
  • 二、实现方法
      • 构造形态学操作所需的核:
      • 创建背景减除模型:
      • 形态学操作:
      • 轮廓检测:
  • 三、代码
    • python代码
    • C++代码
  • 总结
  • 参考文档


前言

很久没更新文章了,这次因为工作场景需要检测动态目标,特此记录一下。


一、效果展示

在这里插入图片描述

二、实现方法

基于OpenCV库的背景减除方法实现的视频中的移动目标检测示例。通过从输入视频中提取前景目标,然后在特定区域内绘制检测到的移动物体的边界框。主要函数方法如下:

构造形态学操作所需的核:

cv2.getStructuringElement: 创建形态学操作所需的结构元素,这里使用椭圆形的结构元素。

创建背景减除模型:

cv2.createBackgroundSubtractorMOG2(): 创建一个高斯混合模型背景减除器,用于提取视频中的前景。

形态学操作:

cv2.morphologyEx(fgmk, cv2.MORPH_OPEN, kernel): 对前景图像进行形态学开运算,用于去除噪声并平滑前景目标。

轮廓检测:

cv2.findContours(fgmk.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE): 寻找前景图像中的轮廓。

三、代码

需要根据自己的视频适当微调参数

python代码

import cv2
import numpy as np

def main(path):
    # 第一步:使用cv2.VideoCapture读取视频
    camera = cv2.VideoCapture(path)

    width = int(camera.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT))

    per_width = int(width / 4)
    per_height = int(height / 2)

    # 第二步:cv2.getStructuringElement构造形态学使用的kernel
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
    # 第三步:构造高斯混合模型
    model = cv2.createBackgroundSubtractorMOG2()
    # model = cv2.createBackgroundSubtractorKNN()

    # 设定区域,后面可以用于判断是否在区域内(可以设置为多边形)
    contour = np.array([[0, 0], [3 * per_width, per_height], [3 * per_width, height], [0, height]])

    while True:
        # 第四步:读取视频中的图片,并使用高斯模型进行拟合
        ret, frame = camera.read()
        # 运用高斯模型进行拟合,在两个标准差内设置为0,在两个标准差外设置为255
        fgmk = model.apply(frame)
        # 第五步:使用形态学的开运算做背景的去除
        fgmk = cv2.morphologyEx(fgmk, cv2.MORPH_OPEN, kernel)
        # 第六步:cv2.findContours计算fgmk的轮廓
        contours, hierarchy = cv2.findContours(fgmk.copy(), cv2.RETR_EXTERNAL,
                                               cv2.CHAIN_APPROX_SIMPLE)  # 该函数计算一幅图像中目标的轮廓

        for c in contours:
            # 过滤面积较小的扰动
            if cv2.contourArea(c) < 80:
                continue

            else:
                x, y, w, h = cv2.boundingRect(c)  # 该函数计算矩形的边界框
                center = (int(x + w / 2), int(y + h / 2))

                # 判断点是否在多边形区域内
                result = cv2.pointPolygonTest(contour, center, False)

                if result > 0:
                    cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)

        # 第八步:进行图片的展示
        cv2.imshow('fgmk', fgmk)
        cv2.imshow('frame', frame)

        if cv2.waitKey(1) & 0xff == 27:
            break

    camera.release()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    path = "./video/test.mp4"
    main(path)

C++代码

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int argc, char** argv) {
    string path = "../test2.mp4";
    // 第一步:使用VideoCapture读取视频
    VideoCapture camera(path);

    int width = static_cast<int>(camera.get(CAP_PROP_FRAME_WIDTH));
    int height = static_cast<int>(camera.get(CAP_PROP_FRAME_HEIGHT));

    int per_width = width / 4;
    int per_height = height / 2;

    // 第二步:getStructuringElement构造形态学使用的kernel
    Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3));
    // 第三步:构造高斯混合模型
    Ptr<BackgroundSubtractorMOG2> model = createBackgroundSubtractorMOG2();
    // Ptr<BackgroundSubtractorKNN> model = createBackgroundSubtractorKNN();

    // 设定区域,后面可以用于判断是否在区域内(可以设置为多边形)
    vector<Point> contour = {Point(0, 0), Point(3 * per_width, per_height), Point(3 * per_width, height), Point(0, height)};

    while (true) {
        // 第四步:读取视频中的图片,并使用高斯模型进行拟合
        Mat frame;
        bool ret = camera.read(frame);
        if (!ret) break;

        // 运用高斯模型进行拟合,在两个标准差内设置为0,在两个标准差外设置为255
        Mat fgmk;
        model->apply(frame, fgmk);
        // 第五步:使用形态学的开运算做背景的去除
        morphologyEx(fgmk, fgmk, MORPH_OPEN, kernel);
        // 第六步:findContours计算fgmk的轮廓
        vector<vector<Point>> contours;
        vector<Vec4i> hierarchy;
        findContours(fgmk.clone(), contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

        for (const auto& c : contours) {
            if (contourArea(c) < 80)
                continue;
            else {
                Rect rect = boundingRect(c);
                Point center(rect.x + rect.width / 2, rect.y + rect.height / 2);

                // 判断点是否在多边形区域内
                double result = pointPolygonTest(contour, center, false);

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

        // 第八步:进行图片的展示
        imshow("fgmk", fgmk);
        imshow("frame", frame);

        if (waitKey(1) == 27) // 按下ESC键退出
            break;
    }

    camera.release();
    destroyAllWindows();

    return 0;
}

总结

这段代码演示了背景减除方法在移动目标检测中的应用,通过检测前景目标并在特定区域内绘制边界框,可以用于一些简单的运动分析和目标跟踪应用。

参考文档

https://blog.csdn.net/Gavinmiaoc/article/details/96474368
https://blog.csdn.net/drippingstone/article/details/116186462
如果阅读本文对你有用,欢迎一键三连呀!!!
2023年8月9日17:15:40
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/853522.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简化AD管理减少IT工作负担

管理和保护混合 AD 环境 IT 管理员几乎每天都要创建和管理多个 AD 对象&#xff0c;利用本机AD工具&#xff08;如Active Directory用户和计算机控制台以及PowerShell脚本&#xff09;来执行这些任务并不理想&#xff0c;因为它们必须在多个控制台之间切换才能执行这些任务&am…

【UE4 RTS】02-Camera Movement

前言 本篇实现了CameraPawn的基本移动功能 步骤 1. 打开项目设置&#xff0c;在 引擎——输入 一栏中删除模板自带的操作映射 在轴映射中&#xff0c;删除“TurnRate” 添加如下键值 2. 打开“RTS_PlayerController_BP”&#xff0c;在事件图表中添加如下节点 此时运行游戏就…

MySQL和钉钉单据接口对接

MySQL和钉钉单据接口对接 数据源系统:钉钉 钉钉&#xff08;DingTalk&#xff09;是阿里巴巴集团打造的企业级智能移动办公平台&#xff0c;是数字经济时代的企业组织协同办公和应用开发平台。钉钉将IM即时沟通、钉钉文档、钉闪会、钉盘、Teambition、OA审批、智能人事、钉工牌…

Java后台生成ECharts图片

前言 通过echarts的jar包&#xff0c;Java后台生成一张图片&#xff0c;并把图片插入到word中。关于word插图片的代码在下一章。 需要用到的工具PhantomJS,Echarts-convert.js,jquery.js,echarts.js。 1.PhantomJS 介绍 PhantomJS是一个不需要浏览器的富客户端。 官方介绍&…

PS的一些智能对象是怎么用的?用于包装设计该怎么使用?

大家都对一些效果图不太理解&#xff0c;我现在就献丑给大家讲一下&#xff0c;教程都是网友盛传的&#xff0c;我自己学习并且有所体会。 一般做的非常好的PS效果图都是外国人自己做的&#xff0c;所以大多数效果图都是英文&#xff0c;细心的网友会发现&#xff0c;中文的是一…

IOS上架流程

IOS上架流程 准备 开发者账号完工的项目 上架步骤 一、创建App ID二、创建证书请求文件 &#xff08;CSR文件&#xff09;三、创建发布证书 &#xff08;CER&#xff09;四、创建Provisioning Profiles配置文件 &#xff08;PP文件&#xff09;五、在App Store创建应用六、…

MPLAB X IDE v6.1.0 使用MCC代码配置器

安装教程应该很好搜到&#xff0c;如果没有 代码配置器&#xff08;MPLAB Code Configurator&#xff0c;MCC&#xff09;说明IDE版本太低了&#xff0c;建议更新下版本&#xff1b; 刚安装完成之后第一次启动会很卡&#xff0c;属于正常现象&#xff1b; 我这好像是离线模式…

博客网站添加复制转载提醒弹窗Html代码

网站如果是完全禁止右键&#xff08;复制、另存为等&#xff09;操作&#xff0c;对用户来说体验感会降低&#xff0c;但是又不希望自己的原创内容直接被copy&#xff0c;今天飞飞和你们分享几行复制转载提醒弹窗Html代码。 效果展示&#xff1a; 复制以下代码&#xff0c;将其…

11_Vue3中的新的组件

1. Fragment 在Vue2中&#xff1a;组件必须要有一个跟标签在Vue3中&#xff1a;组件可以没有根标签&#xff0c;内部会将多个标签包含在一个Fragment虚拟元素中好处&#xff1a;减少标签层级&#xff0c;减少内存占用 2. Teleport 什么是Teleport?——Teleport 是一种能够将…

ubuntu22.04源码编译opencv4.6

第一次编译之后&#xff0c;测试opencv_example不成功&#xff0c;又重新卸载了再装了一次&#xff0c;成功了&#xff0c;简单记录一下。 下载opencv4.6以及opencv_contrib-4.6.0 opencv下载地址 opencv-contrib下载地址解压以后&#xff0c;把contrib放到opencv4.6文件夹下 第…

无涯教程-Perl - getnetent函数

描述 此函数从/etc/networks文件获取下一个条目,返回-($name,$aliases,$addrtype,$net) 如果/etc/networks文件为空,则它将不返回任何内容,并且调用将失败。 语法 以下是此函数的简单语法- getnetent返回值 此函数在错误时返回undef,否则在标量context中返回网络地址,在错…

Qt应用开发(基础篇)——框架类 QFrame

一、前言 QFrame继承于QWidget&#xff0c;被QLCDNumber、QToolBox、QLabel、QListView等部件继承&#xff0c;是一个拥有矩形框架的基类。 QFrame可以直接创建成一个没有内容的的矩形框架&#xff0c;框架的样式由边框厚度(lineWidth)、框架形状(QFrame::Shape)和阴影样式(QFr…

药物临床试验项目风险管理︱科济生物医药临床运营部总监张立峰

科济生物医药&#xff08;上海&#xff09;有限公司临床运营部总监张立峰先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;药物临床试验项目风险管理---回顾疫情考验下的风险管理应对。大会将于8月12-13日在北京举办&#xff0c;敬请…

小程序外包开发框架

小程序是一种轻量级的移动应用程序&#xff0c;通常用于在微信和其他平台上提供简单的交互和功能。以下是一些常见的小程序开发框架以及它们的特点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.微…

冯诺依曼体系结构与进程概念理解

目录 1. 先谈硬件 1、初步理解冯诺依曼体系结构 2、理解各个模块之间的协作 2. 再谈软件 1、为什么要有操作系统 2、操作系统如何管理软硬件资源 3. 再谈进程 1、什么是进程 2、如何理解进程 3、Linux 是如何管理进程的 写在最后&#xff1a; 1. 先谈硬件 1、初步理…

亚马逊对AIGC的定义

大家好&#xff0c;这里是Doker,最近AIGC非常火&#xff0c;这里我们聊一下什么是AIGC. 一、 AIGC 介绍与典型行业应用场景 ​AIGC 又称生成式 AI (Generative AI)&#xff0c;是继专业生产内容&#xff08;PGC&#xff0c; Professional-generated Content&#xff09;、用户…

谁知道,多项目管理的进度管理应该如何进行?

大家好&#xff0c;我是老原。多项目管理的进度管理应该如何进行&#xff1f; 我们应该拆分开来看&#xff1a;一手应对多项目管理&#xff0c;一手把握进度管控。 这个和一个人同时需要处理/负责多个项目线程&#xff0c;道理上是通用的。 今天还是会一如即往的在文章里给大…

7.5 批量规范化详解

BatchNorm(归一化/标准化) 归一化/标准化实质是一种线性变换&#xff0c;线性变换有很多良好的性质&#xff0c;这些性质决定了对数据改变后不会造成“失效”&#xff0c;反而能提高数据的表现&#xff0c;这些性质是归一化/标准化的前提。比如有一个很重要的性质&#xff1a;…

webshell免杀项目-webshell(七)

免杀webshell生成工具 项目地址&#xff1a; https://github.com/pureqh/webshell 快速使用 下载该项目后直接用python3运行相关py脚本即可生成免杀代码

如何剪裁操作系统源码——移植FreeRTOS的内存管理模块到ARMV8裸片

如何剪裁操作系统源码 本文面向的需求场景是&#xff0c;为缺乏标准库实现的处理器IP移植内存管理模块&#xff0c;即为裸片部署C标准库中的 malloc() 和 free() 函数。 具体做法是——从操作系统的内存管理组件中剪裁出必要的源码&#xff0c;适配到目标处理器的开发环境&am…