使用 OpenCV 的 YOLOv4 目标检测

YOLO(You Only Look Once)是一种对象检测算法,可以近乎实时地检测图像中的对象。YOLOv4 是 YOLO 的第 4 版,于 2020 年 4 月推出。

本教程举例说明如何使用预训练的 YOLOv4 模型使用 OpenCV 检测图像中的对象。

准备环境

在开始之前,从AlexeyAB/darknet资源库的发布页面下载 YOLOv4 网络配置 ( yolov4.cfg) 和权重 ( yolov4.weights) 。

模型是在COCO数据集上训练的,该数据集由80个物体类别组成。下载coco.names包含类名的文件。

代码

我们先读取图像和类名。接下来,我们读取网络配置和预训练的权重。初始化检测模型并设置输入参数。1/255 比例因子定义了像素值从 0 到 1 进行缩放。给定的图像将被调整为 416×416 的大小而不裁剪。该swapRB参数定义第一个和最后一个通道将被交换,因为 OpenCV 使用 BGR。

我们检测图像中的物体。信心分数阈值(在我们的例子中是0.6)用于通过信心分数来过滤盒子。通过使用非最大压制(NMS)来选择最合适的盒子。NMS由阈值控制(在我们的例子中是0.4)。

最后,我们在图像上绘制边界框以及类标签和分数。

package app;

import org.opencv.core.*;
import org.opencv.dnn.DetectionModel;
import org.opencv.dnn.Dnn;
import org.opencv.dnn.Net;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class Main
{
    static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }

    public static void main(String[] args) throws IOException
    {
        Mat img = Imgcodecs.imread("test.jpg");

        List<String> classes = Files.readAllLines(Paths.get("coco.names"));

        Net net = Dnn.readNetFromDarknet("yolov4.cfg", "yolov4.weights");

        DetectionModel model = new DetectionModel(net);
        model.setInputParams(1 / 255.0, new Size(416, 416), new Scalar(0), true);

        MatOfInt classIds = new MatOfInt();
        MatOfFloat scores = new MatOfFloat();
        MatOfRect boxes = new MatOfRect();
        model.detect(img, classIds, scores, boxes, 0.6f, 0.4f);

        for (int i = 0; i < classIds.rows(); i++) {
            Rect box = new Rect(boxes.get(i, 0));
            Imgproc.rectangle(img, box, new Scalar(0, 255, 0), 2);

            int classId = (int) classIds.get(i, 0)[0];
            double score = scores.get(i, 0)[0];
            String text = String.format("%s: %.2f", classes.get(classId), score);
            Imgproc.putText(img, text, new Point(box.x, box.y - 5),
                    Imgproc.FONT_HERSHEY_SIMPLEX, 1, new Scalar(0, 255, 0), 2);
        }

        HighGui.imshow("Image", img);
        HighGui.waitKey(0);
        HighGui.destroyAllWindows();

        System.exit(0);
    }
}
import cv2

img = cv2.imread('test.jpg')

with open('coco.names', 'r') as f:
    classes = f.read().splitlines()

net = cv2.dnn.readNetFromDarknet('yolov4.cfg', 'yolov4.weights')

model = cv2.dnn_DetectionModel(net)
model.setInputParams(scale=1 / 255, size=(416, 416), swapRB=True)

classIds, scores, boxes = model.detect(img, confThreshold=0.6, nmsThreshold=0.4)

for (classId, score, box) in zip(classIds, scores, boxes):
    cv2.rectangle(img, (box[0], box[1]), (box[0] + box[2], box[1] + box[3]),
                  color=(0, 255, 0), thickness=2)

    text = '%s: %.2f' % (classes[classId[0]], score)
    cv2.putText(img, text, (box[0], box[1] - 5), cv2.FONT_HERSHEY_SIMPLEX, 1,
                color=(0, 255, 0), thickness=2)

cv2.imshow('Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace dnn;

int main()
{
    Mat img = imread("test.jpg");

    std::vector<std::string> classes;
    std::ifstream file("coco.names");
    std::string line;
    while (std::getline(file, line)) {
        classes.push_back(line);
    }

    Net net = readNetFromDarknet("yolov4.cfg", "yolov4.weights");

    DetectionModel model = DetectionModel(net);
    model.setInputParams(1 / 255.0, Size(416, 416), Scalar(), true);

    std::vector<int> classIds;
    std::vector<float> scores;
    std::vector<Rect> boxes;
    model.detect(img, classIds, scores, boxes, 0.6, 0.4);

    for (int i = 0; i < classIds.size(); i++) {
        rectangle(img, boxes[i], Scalar(0, 255, 0), 2);

        char text[100];
        snprintf(text, sizeof(text), "%s: %.2f", classes[classIds[i]].c_str(), scores[i]);
        putText(img, text, Point(boxes[i].x, boxes[i].y - 5), cv::FONT_HERSHEY_SIMPLEX, 1,
                Scalar(0, 255, 0), 2);
    }

    imshow("Image", img);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

效果图:

使用 OpenCV 的 YOLOv4 目标检测

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论