最近使用YOLO在做一些目标检测方面的工作,在此梳理和记录一下自己的整个过程。
目录在此
一、获取YOLOv5
二、标注图片
三、训练模型
四、转化模型
五、C#使用训练好的模型
一、获取YOLOv5
YOLO下载地址在此:YOLOv5
具体版本可以在左上角选择。
下面也有很多使用的方法:
二、标注图片
标注图片使用的是labelImg简单方便
1、安装
很简单,直接cmd里面输入
pip install labelImg
2、启动
同样的,在cmd里面直接输入
labelImg
程序打开就是这样
具体如何使用还是很简单的,随便找找就能学会。
三、训练模型
打开YOLO中train.py文件,大概400多行有一堆参数
具体想改啥,可以在命令行里写,不过可以直接改代码的默认数值。
官方文档里面也有实例
# Train YOLOv5s on COCO128 for 3 epochs
$ python train.py --img 640 --batch 16 --epochs 3 --data coco128.yaml --weights yolov5s.pt
当然,如果有一些细节不知道如何操作,这里有一个大佬做的手把手快速YOLO的实战视频,分享给各位参考。YOLO实战视频
四、转化模型
由于C#需要onnx模型,因此这里需要将训练好的模型(可能是.pt 或者.pth后缀)转化成onnx模型。当然YOLO官方也给出了转化的方法(太方便了)。
举个例子:
python export.py --weights yolov5s.pt --include torchscript onnx
注:查看转化后的模型结构,可以使用一个网页的模型查看网站Netron。
链接在此放上:netron
把模型放进去得到的模型太大,在此展示最开始的输入。
五、C# 使用onnx模型
1、很幸运,github中有一个使用C#运行YOLOv5的代码。
链接也在此:yolov5-net
2、修改相关的参数和产生dll
打开YoloCocoP5Model
关键是修改两个地方
1、Dimensions 个数是分类个数 + 5
public override int Dimensions { get; set; } = 7;
2、
public override List<YoloLabel> Labels { get; set; } = new List<YoloLabel>()
{
//new YoloLabel { Id = 1, Name = "person" },
//new YoloLabel { Id = 2, Name = "bicycle" },
//new YoloLabel { Id = 3, Name = "car" },
//new YoloLabel { Id = 4, Name = "motorcycle" },
//new YoloLabel { Id = 5, Name = "airplane" },
//new YoloLabel { Id = 6, Name = "bus" },
//new YoloLabel { Id = 7, Name = "train" },
//new YoloLabel { Id = 8, Name = "truck" },
//new YoloLabel { Id = 9, Name = "boat" },
//new YoloLabel { Id = 10, Name = "traffic light" },
//new YoloLabel { Id = 11, Name = "fire hydrant" },
//new YoloLabel { Id = 12, Name = "stop sign" },
//new YoloLabel { Id = 13, Name = "parking meter" },
//new YoloLabel { Id = 14, Name = "bench" },
//new YoloLabel { Id = 15, Name = "bird" },
//new YoloLabel { Id = 16, Name = "cat" },
//new YoloLabel { Id = 17, Name = "dog" },
//new YoloLabel { Id = 18, Name = "horse" },
//new YoloLabel { Id = 19, Name = "sheep" },
//new YoloLabel { Id = 20, Name = "cow" },
//new YoloLabel { Id = 21, Name = "elephant" },
//new YoloLabel { Id = 22, Name = "bear" },
//new YoloLabel { Id = 23, Name = "zebra" },
//new YoloLabel { Id = 24, Name = "giraffe" },
//new YoloLabel { Id = 25, Name = "backpack" },
//new YoloLabel { Id = 26, Name = "umbrella" },
//new YoloLabel { Id = 27, Name = "handbag" },
//new YoloLabel { Id = 28, Name = "tie" },
//new YoloLabel { Id = 29, Name = "suitcase" },
//new YoloLabel { Id = 30, Name = "frisbee" },
//new YoloLabel { Id = 31, Name = "skis" },
//new YoloLabel { Id = 32, Name = "snowboard" },
//new YoloLabel { Id = 33, Name = "sports ball" },
//new YoloLabel { Id = 34, Name = "kite" },
//new YoloLabel { Id = 35, Name = "baseball bat" },
//new YoloLabel { Id = 36, Name = "baseball glove" },
//new YoloLabel { Id = 37, Name = "skateboard" },
//new YoloLabel { Id = 38, Name = "surfboard" },
//new YoloLabel { Id = 39, Name = "tennis racket" },
//new YoloLabel { Id = 40, Name = "bottle" },
//new YoloLabel { Id = 41, Name = "wine glass" },
//new YoloLabel { Id = 42, Name = "cup" },
//new YoloLabel { Id = 43, Name = "fork" },
//new YoloLabel { Id = 44, Name = "knife" },
//new YoloLabel { Id = 45, Name = "spoon" },
//new YoloLabel { Id = 46, Name = "bowl" },
//new YoloLabel { Id = 47, Name = "banana" },
//new YoloLabel { Id = 48, Name = "apple" },
//new YoloLabel { Id = 49, Name = "sandwich" },
//new YoloLabel { Id = 50, Name = "orange" },
//new YoloLabel { Id = 51, Name = "broccoli" },
//new YoloLabel { Id = 52, Name = "carrot" },
//new YoloLabel { Id = 53, Name = "hot dog" },
//new YoloLabel { Id = 54, Name = "pizza" },
//new YoloLabel { Id = 55, Name = "donut" },
//new YoloLabel { Id = 56, Name = "cake" },
//new YoloLabel { Id = 57, Name = "chair" },
//new YoloLabel { Id = 58, Name = "couch" },
//new YoloLabel { Id = 59, Name = "potted plant" },
//new YoloLabel { Id = 60, Name = "bed" },
//new YoloLabel { Id = 61, Name = "dining table" },
//new YoloLabel { Id = 62, Name = "toilet" },
//new YoloLabel { Id = 63, Name = "tv" },
//new YoloLabel { Id = 64, Name = "laptop" },
//new YoloLabel { Id = 65, Name = "mouse" },
//new YoloLabel { Id = 66, Name = "remote" },
//new YoloLabel { Id = 67, Name = "keyboard" },
//new YoloLabel { Id = 68, Name = "cell phone" },
//new YoloLabel { Id = 69, Name = "microwave" },
//new YoloLabel { Id = 70, Name = "oven" },
//new YoloLabel { Id = 71, Name = "toaster" },
//new YoloLabel { Id = 72, Name = "sink" },
//new YoloLabel { Id = 73, Name = "refrigerator" },
//new YoloLabel { Id = 74, Name = "book" },
//new YoloLabel { Id = 75, Name = "clock" },
//new YoloLabel { Id = 76, Name = "vase" },
//new YoloLabel { Id = 77, Name = "scissors" },
//new YoloLabel { Id = 78, Name = "teddy bear" },
//new YoloLabel { Id = 79, Name = "hair drier" },
//new YoloLabel { Id = 80, Name = "toothbrush" }
new YoloLabel { Id = 1, Name = "pit" },
new YoloLabel { Id = 2, Name = "bump" }
};
修改好了可以跑一边看看,有没有结果(我之前跑了好几次都没结果,可以把最后输出的路径改成绝对路径,就有结果了)。
主要使用的模型代码为:
private void button1_Click(object sender, EventArgs e)
{
var image = Image.FromFile(path[index]);
DateTime T_start = DateTime.Now;
var scorer = new YoloScorer<YoloCocoP5Model>("D:/defect_detection/YOLO/yolov5-master/OST_best.onnx");
List<YoloPrediction> predictions = scorer.Predict(image);
var graphics = Graphics.FromImage(image);
foreach (var prediction in predictions) // iterate predictions to draw results
{
double score = Math.Round(prediction.Score, 2);
graphics.DrawRectangles(new Pen(prediction.Label.Color, 1),
new[] { prediction.Rectangle });
var (x, y) = (prediction.Rectangle.X - 3, prediction.Rectangle.Y - 23);
graphics.DrawString($"{prediction.Label.Name} ({score})",
new Font("Consolas", 16, GraphicsUnit.Pixel), new SolidBrush(prediction.Label.Color),
new PointF(x, y));
}
image.Save("D:/defect_detection/yolov5-net-master/src/Yolov5Net.App/Assets/result.jpg");
this.pictureBox1.Image = image;
DateTime T_end = DateTime.Now;
TimeSpan T_esp = T_end - T_start;
this.label1.Text = T_esp.TotalMilliseconds.ToString();
}
其他都是一些界面的代码了。