微信公众号:OpenCV学堂
关注获取更多计算机视觉与深度学习知识
免费领学习资料+微信:OpenCVXueTang_Asst
https://mp.weixin.qq.com/s/_R-qtDvlXoQWzwFjK4L6jQ
1. 图像读取与预处理
2. 模型加载
3. 模型推理
4. 预测结果数据后处理与显示
// Read class list
List
classList = File.ReadAllLines(classesFilePath).Select(line => line.Trim()).ToList(); var colors = new List<(int, int, int)> { (255, 255, 0), (0, 255, 0), (0, 255, 255), (255, 0, 0) };
// Load the model
using var model = CvDnn.ReadNetFromOnnx(modelPath);
// Open video capture
using var capture = new VideoCapture(videoPath);
if (!capture.IsOpened())
{
Console.WriteLine("无法打开视频文件");
return;
}
while (true)
{
Mat frame = new Mat();
bool isSuccess = capture.Read(frame);
if (!isSuccess || frame == null)
{
Console.WriteLine("视频流结束");
break;
}
// Preprocess the frame
var bgr = FormatYolov5(frame);
int img_h = bgr.Height;
int img_w = bgr.Width;
int img_c = bgr.Channels();
using var blob = CvDnn.BlobFromImage(bgr, 1 / 255.0, new Size(640, 640), new Scalar(), true, false);
model.SetInput(blob);
// Perform inference
Mat outputs = model.Forward();
Mat rows = outputs.Reshape(0, 1).T();
List<int> classIds = new List<int>();
List<float> confidences = new List<float>();
List
boxes = new List (); double xFactor = img_w / 640.0;
double yFactor = img_h / 640.0;
for (int r = 0; r < rows.Rows; r++)
{
Mat row = rows.Row(r);
//Console.WriteLine("row width: " + row.Rows);
Mat classesScores = new Mat();
Rect roi = new Rect(4, 0, 80, 1);
row[roi].CopyTo(classesScores);
double minv = 0, maxv = 0;
Point minLoc = new Point(0, 0);
Point maxLoc = new Point(0, 0);
Cv2.MinMaxLoc(classesScores, out minv, out maxv, out minLoc, out maxLoc);
int classId = maxLoc.X;
if (classesScores.At<float>(0, classId) > 0.25)
{
confidences.Add(classesScores.At<float>(0, classId));
classIds.Add(classId);
float cx = row.At<float>(0, 0);
float cy = row.At<float>(0, 1);
float w = row.At<float>(0, 2);
float h = row.At<float>(0, 3);
int left = (int)((cx - 0.5 * w) * xFactor);
int top = (int)((cy - 0.5 * h) * yFactor);
int width = (int)(w * xFactor);
int height = (int)(h * yFactor);
boxes.Add(new Rect(left, top, width, height));
}
}
// Non-maximum suppression
int[] indexes;
CvDnn.NMSBoxes(boxes, confidences, 0.25f, 0.45f, out indexes);
foreach (int index in indexes)
{
Rect box = boxes[index];
var color = colors[(classIds[index] % colors.Count)];
Cv2.Rectangle(frame, box, new Scalar(color.Item1, color.Item2, color.Item3), 2);
Cv2.Rectangle(frame, new Rect(box.X, box.Y - 20, box.Width, 15), new Scalar(color.Item1, color.Item2, color.Item3), -1);
Cv2.PutText(frame, classList[classIds[index]], new Point(box.X, box.Y - 10), HersheyFonts.HersheySimplex, 0.5, new Scalar(0, 0, 0));
}
Cv2.ImShow("OpenCV学堂C#版本-YOLO12对象检测 ", frame);
if (Cv2.WaitKey(1) == 27) break;
}
运行结果显示如下:
OpenCV4系统化学习
推荐阅读
OpenCV4.8+YOLOv8对象检测C++推理演示
ZXING+OpenCV打造开源条码检测应用
攻略 | 学习深度学习只需要三个月的好方法
三行代码实现 TensorRT8.6 C++ 深度学习模型部署
实战 | YOLOv8+OpenCV 实现DM码定位检测与解析
对象检测边界框损失 – 从IOU到ProbIOU
初学者必看 | 学习深度学习的五个误区