opencv动态目标检测

news/2024/7/10 3:01:15 标签: opencv, 目标检测, 人工智能

文章目录

  • 前言
  • 一、效果展示
  • 二、实现方法
      • 构造形态学操作所需的核:
      • 创建背景减除模型:
      • 形态学操作:
      • 轮廓检测:
  • 三、代码
    • 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.niftyadmin.cn/n/4925264.html

相关文章

互联网摸鱼日报(2023-08-04)

互联网摸鱼日报(2023-08-04) 36氪新闻 当爱尝「鲜」的年轻人&#xff0c;遇到「常」鲜的个性化家电 36氪项目报道&#xff5c;「高烯科技」&#xff0c;以正在“走向现实”的石墨烯技术发力新材料产业化 刚刚&#xff0c;韩国学会称“LK-99常温超导证据不足”&#xff0c;此…

用python实现xmind用例转换为excel/csv用例

from xmindparser import xmind_to_dict from openpyxl import Workbook# 解析XMind文件 xmind_file path/to/xmind/file.xmind xmind_data xmind_to_dict(xmind_file)# 创建Excel文件 excel_file path/to/excel/file.xlsx wb Workbook() ws wb.active# 定义用例表格的列名…

C语言重点考试选择题及答案解析C语言期末考试专升本

C语言重点考试选择题及答案解析 介绍&#xff1a; 在本篇博客中&#xff0c;我们将为大家整理了20道C语言重点考试选择题&#xff0c;每道题下面都附有正确答案和解析。这些选择题涵盖了C语言的基础知识点&#xff0c;希望能够帮助你复习和巩固你的C语言编程技能。 1. 在C语言…

遍历集合List的五种方法以及如何在遍历集合过程中安全移除元素

一、遍历集合List的五种方法 测试数据 List<String> list new ArrayList<>(); list.add("A");list.add("B");list.add("C");1. 普通for循环 普通for循环&#xff0c;通过索引遍历 for (int i 0; i < list.size(); i) {Syst…

Json简述(C++)

目录 1.介绍 2.格式 3.底层 3.1数据对象表示 3.2序列化接口 3.3反序列化接口 4.使用 1.介绍 Json&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;其最早是为JavaScript编程语言设计的格式。不过发发展至今&#xff0c;Jso…

【数学】CF1796 C

Problem - 1796C - Codeforces 题意&#xff1a; 思路&#xff1a; 模拟一下样例可以发现一些规律 Code&#xff1a; #include <bits/stdc.h>#define int long longusing i64 long long;constexpr int N 1e6 10; constexpr int mod 998244353;void solve() {int l…

深入理解Go语言中的并发编程【30】【多路复用】

文章目录 多路复用 多路复用 操作系统级的I/O模型有&#xff1a; 阻塞I/O非阻塞I/O信号驱动I/O异步I/O多路复用I/O   Linux下&#xff0c;一切皆文件。包括普通文件、目录文件、字符设备文件&#xff08;键盘、鼠标&#xff09;、块设备文件&#xff08;硬盘、光驱&#xff…