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