OpenCV dynamische Zielerkennung


Vorwort

Ich habe den Artikel schon lange nicht mehr aktualisiert. Dieses Mal werde ich ihn hier aufzeichnen, da das Arbeitsszenario die Erkennung dynamischer Ziele erfordert.


1. Effektanzeige

Fügen Sie hier eine Bildbeschreibung ein

2. Implementierungsmethode

Ein Beispiel für die Erkennung sich bewegender Objekte in Videos, implementiert mit der Hintergrundsubtraktionsmethode der OpenCV-Bibliothek. Durch Extrahieren von Vordergrundobjekten aus dem Eingabevideo und anschließendes Zeichnen von Begrenzungsrahmen erkannter sich bewegender Objekte innerhalb eines bestimmten Bereichs. Die Hauptfunktionsmethoden sind wie folgt:

Konstruieren Sie die für morphologische Operationen erforderlichen Kernel:

cv2.getStructuringElement: Erstellen Sie die für morphologische Operationen erforderlichen Strukturelemente. Hier wird ein elliptisches Strukturelement verwendet.

Erstellen Sie ein Hintergrundsubtraktionsmodell:

cv2.createBackgroundSubtractorMOG2(): Erstellen Sie einen Hintergrundsubtrahierer für ein Gaußsches Mischungsmodell, um den Vordergrund im Video zu extrahieren.

Morphologische Operationen:

cv2.morphologyEx(fgmk, cv2.MORPH_OPEN, kernel): Führen Sie eine morphologische Öffnungsoperation für das Vordergrundbild durch, um Rauschen zu entfernen und das Vordergrundziel zu glätten.

Konturerkennung:

cv2.findContours(fgmk.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE): Konturen im Vordergrundbild finden.

3. Code

Sie müssen die Parameter entsprechend Ihrem Video entsprechend anpassen

Python-Code

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++-Code

#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;
}

Zusammenfassen

Dieser Code demonstriert die Anwendung der Hintergrundsubtraktionsmethode bei der Erkennung bewegter Ziele. Durch die Erkennung von Vordergrundzielen und das Zeichnen von Begrenzungsrahmen innerhalb eines bestimmten Bereichs kann er für einige einfache Bewegungsanalyse- und Zielverfolgungsanwendungen verwendet werden.

Referenzdokumentation

https://blog.csdn.net/Gavinmiaoc/article/details/96474368
https://blog.csdn.net/drippingstone/article/details/116186462Wenn
die Lektüre dieses Artikels für Sie nützlich ist, können Sie ihn gerne mit einem verknüpfen klicken! ! !
9. August 2023 17:15:40
Fügen Sie hier eine Bildbeschreibung ein

Supongo que te gusta

Origin blog.csdn.net/JulyLi2019/article/details/132188076
Recomendado
Clasificación