这段代码展示了一个使用YOLOv9进行对象检测的简单测试框架。代码主体以及其功能分为以下几个关键部分:
创建测试图片数组
_testImages
,它包含了图片文件名和对应的标签。使用buildTests
方法来从给定的文件名中加载图片并调整尺寸,准备测试数据集。实现了
DisplayImageWithPredictions
方法,该方法接收一个System.Drawing.Image
对象和一组YOLO预测结果,使用OpenCvSharp的功能将图像和预测结果可视化。它首先将图像转换为字节数组,然后用Mat对象来绘制对象框和相应的标签。CheckResult
方法是一个辅助测试的方法,该方法验证预测结果的数量和标签是否符合预期。Main
方法是程序的入口点,它首先构建测试图片,然后实例化一个Yolov8
对象用于进行预测(这里可能是代码有误,实际上是YOLOv9模型),对每个测试图片进行预测,展示预测结果,并在控制台输出对象检测框的坐标。使用了xUnit的
Assert
方法进行断言验证,这部分通常用于自动化测试确认程序的正确性。但这里注释掉了这部分代码,可能是因为在实际的使用过程中不需要对结果进行断言。
代码展示了如何将YOLO对象检测模型集成到C#应用程序中,并使用OpenCvSharp在窗口中显示检测到的对象。整个程序流程包括加载和处理测试图像、执行模型推理、展示和验证检测结果。不过请注意,代码中有一些小的不一致之处,如 Yolov8
的实例化(YOLOv9 onnx模型)和注释掉的一些测试断言。此外,代码中的一些Yolo类和方法可能来源于特定的库或框架,但没有在代码段中直接给出,因此需要在相应上下文中查找相关的实现。
using System; // 使用System命名空间,包含基础类和基本输入输出
using System.Diagnostics; // 使用System.Diagnostics命名空间,提供调试输出和性能测试等功能
using System.Drawing; // 使用System.Drawing命名空间,支持图形界面绘制
using System.Drawing.Imaging; // 使用System.Drawing.Imaging,支持高级GDI+图形功能
using Xunit; // 使用Xunit命名空间,是单元测试的框架
using Yolov7net; // 使用Yolov7net命名空间,可能是YOLO的一个.NET实现(源代码中实际为Yolov8,可能存在误导)
using Yolov7net.Extentions; // 使用Yolov7net的扩展名空间,可能包含一些额外的方法
using OpenCvSharp; // 使用OpenCvSharp库,它是OpenCV的C#语言封装
// 定义yolov9_det_opencvsharp命名空间
namespace yolov9_det_opencvsharp
{
// 定义Program类
internal class Program
{
// 声明测试用的图片数组
public static (Image image, string label)[] _testImages;
// 定义buildTests方法,用以构建测试图片
public static void buildTests()
{
// 声明测试图片文件名及对应标签的数组
var testFiles = new (string fileName, string label)[]
{
("demo.jpg", "dog"),
("cat_224x224.jpg", "cat"),
("1.jpeg",""),
("2.png","")
};
// 基于提供的测试文件构建测试图片数组,包括图片和标签
var array = new (Image image, string label)[testFiles.Length];
// var array = new (Image image, string label)[testFiles.Length * 2];
int i = 0;
foreach (var tuple in testFiles)
{
// 从Assets文件夹加载图片
var image = Image.FromFile("Assets/" + tuple.fileName);
//array[i++] = (image, tuple.label);
// 调整图片大小为640x640
image = Utils.ResizeImage(image, 640, 640);
// 添加到数组中
array[i++] = (image, tuple.label);
}
// 将数组赋值给类的静态成员变量
_testImages = array;
}
// 定义DisplayImageWithPredictions方法,用于展示带预测框的图片
public static void DisplayImageWithPredictions(Image image, List<YoloPrediction> predictions)
{
// 将System.Drawing.Image转换为字节数组
byte[] imageBytes;
using (var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Bmp);
imageBytes = ms.ToArray();
}
// 使用OpenCVSharp从字节数组创建Mat对象
Mat mat = Mat.FromImageData(imageBytes, ImreadModes.Color);
// 遍历预测结果,在图像上绘制矩形框和标签
foreach (var prediction in predictions)
{
// 绘制预测框
Cv2.Rectangle(mat,
new OpenCvSharp.Point(prediction.Rectangle.Left, prediction.Rectangle.Top),
new OpenCvSharp.Point(prediction.Rectangle.Right, prediction.Rectangle.Bottom),
Scalar.Red, 2);
// 绘制标签和得分
string labelText = $"{prediction.Label.Name} ({prediction.Score:P})";
int baseLine;
// 获取标签文本的尺寸
var labelSize = Cv2.GetTextSize(labelText, HersheyFonts.HersheySimplex, 0.5, 1, out baseLine);
// 在图形上添加文本
Cv2.PutText(mat, labelText,
new OpenCvSharp.Point(prediction.Rectangle.Left, prediction.Rectangle.Top + labelSize.Height + baseLine),
HersheyFonts.HersheySimplex, 0.5, Scalar.Yellow, 1);
}
// 使用OpenCVSharp在新窗口显示带预测结果的图片
using (new Window("Image Display", mat, WindowFlags.AutoSize))
{
Cv2.WaitKey(2000); // 显示图像2000毫秒,然后继续执行
//Cv2.DestroyAllWindows(); // 关闭所有OpenCV窗口
}
}
// 定义CheckResult方法,用于断言预测结果的对错
public static void CheckResult(List<YoloPrediction> predictions, string label)
{
// 断言预测结果非空
Assert.NotNull(predictions);
// 断言只有一个预测结果
Assert.Equal(1, predictions.Count);
//Assert.Equal(label, predictions[0].Label.Name);
// 打印第一个预测结果的矩形坐标
Console.WriteLine(predictions[0].Rectangle);
}
// 定义程序的主入口点Main方法
static void Main(string[] args)
{
// 构建测试图片
buildTests();
// using var yolo = new Yolov7("./assets/yolov7-tiny.onnx", true); //yolov7 模型,不需要 nms 操作
// 使用yolov9-c.onnx创建YOLO模型实例,并启用nms操作
using var yolo = new Yolov8("./assets/yolov9-c.onnx", true);
// 设置YOLO模型的默认类别标签
yolo.SetupYoloDefaultLabels();
// 遍历测试图片
foreach (var tuple in _testImages)
{
// 对每张图片进行预测
List<YoloPrediction> ret = yolo.Predict(tuple.image);
//CheckResult(ret, tuple.label);
// 输出预测结果的矩形坐标
Console.WriteLine(ret[0].Rectangle);
// 显示带预测框的图片
DisplayImageWithPredictions(tuple.image,ret);
}
// 等待用户输入,程序暂停
Console.ReadLine();
}
}
}
这段代码定义了一个使用YOLOv9模型进行对象检测的控制台应用程序。它主要执行以下步骤:
buildTests
函数初始化了一个测试图片数组_testImages
,包含图片文件名和对应的标签。DisplayImageWithPredictions
函数接收一个Image
对象和一个YoloPrediction
列表,用OpenCVSharp将图片显示出来,并在图片上绘制检测到的对象的边界框和预测标签。CheckResult
函数对预测结果进行断言以确保正确性,这通常在测试环境下使用。Main
方法是程序的入口点,它构建测试数据,初始化YOLO模型,运行模型进行预测,并使用DisplayImageWithPredictions
方法来展示结果。
代码中使用了Yolov7net
库。程序的主要作用是进行图像处理和对象识别,并输出识别结果到控制台和图形界面展示。