YOLOv8实例分割-使用.Net /.net Core 实例分割

A 背景

最近在学习实例分割,对于小白来说。整理自己学习的过程。

会包含以下几个部署

1:YoloV8部署与demo运行,及相关问题(整理中)

2:YoloV8 自定义数据集训练与及相关要点(整理中)

3:YoloV8 实例分割怎样落地到应用-python方案(整理中)

4:YoloV8 实例分割怎样落地应用-使用.Net /.net Core方案(本文)

基于.Net 实现YoloV8分割模型YoloV8Net.Segment

(本人是小白,内容有参考及引用以下小神,多谢了。 基于.Net6使用YoloV8的分割模型_Heliophyte阳的博客-CSDN博客

B 前言

为什么要使用 .Net /.net Core来实现 YoloV8的实例分割。因我的项目是做图书的图书脊梁图片分割(基于图脊的盘点方案实现)。我的项目都是.net 来实现的,分割只是其中一个小环节。为了程序的统一及方便部署等。

效果及目标

1掩码图

2对应分割图(矩形)

 

 3截取分割图对应掩码图

 C 将yolov8 pt模型转为onnx

训练后你会得到best.pt文件(也可以使用官方的 模型文件 如 yolov8x-seg.pt)

import sys
from ultralytics import YOLO
# Create a new YOLO model from scratch
#model = YOLO('yolov8n.yaml')
if __name__ == '__main__':

    model = YOLO('你的具体地址/best.pt')

    success = model.export(format='onnx')#,opset=12
'''

D 代码要点与调整

1调整分割标签

protected void UseCoCoLabels()
        {
            var s = new string[] { "book" };
            //var s = new string[] { "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch", "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush" };
            UseCustomLabels(s);
        }

2根据情况,调整过滤(分割结果)的关健条件(占比)

   public float Overlap { get; protected set; } = 0.65f;//hcrain  0.45f;

3修复掩码的bug 且将掩码区转为透明(我也不太明白 小神这里的操作(后面再分割吧),我只是加工了下)

for (int r = 0; r < nms_results.Length; r++)
            {
                Mat rgb_mask = Mat.Zeros(new OpenCvSharp.Size(image.Width, image.Height), MatType.CV_8UC3);
                Rect box = nms_results[r].Rectangle;
                int box_x1 = box.X;
                int box_y1 = box.Y;
                int box_x2 = box.BottomRight.X;
                int box_y2 = box.BottomRight.Y;
                // Segment Result
                Mat original_mask = nms_results[r].Mask * proto_data;
                //Mat original_mask = result.ToList()[10].Mask * proto_data;
                Parallel.For(0, original_mask.Cols, col =>
                {
                    original_mask.At<float>(0, col) = Utils.Sigmoid(original_mask.At<float>(0, col));
                });
                // 1x25600 -> 160x160
                Mat reshape_mask = original_mask.Reshape(1, 160);
                // scale
                //float scale = Math.Max(w, h) / 640f;
                int mx1 = Math.Max(0, (int)(box_x1 * gain * 0.25));
                int mx2 = Math.Max(0, (int)(box_x2 * gain * 0.25));
                int my1 = Math.Max(0, (int)(box_y1 * gain * 0.25));
                int my2 = Math.Max(0, (int)(box_y2 * gain * 0.25));
                // get roi
                Mat mask_roi = new Mat(reshape_mask, new OpenCvSharp.Range(my1, my2), new OpenCvSharp.Range(mx1, mx2));
                Mat actual_maskm = new Mat();
                Cv2.Resize(mask_roi, actual_maskm, new OpenCvSharp.Size((int)nms_results[r].Rectangle.Width,
                    (int)nms_results[r].Rectangle.Height));
                Cv2.Threshold(actual_maskm, actual_maskm, 0.5, 255, ThresholdTypes.Binary);
                // predict
                Mat bin_mask = new Mat();
                //actual_maskm.ImWrite("actual_maskm.png");
                actual_maskm.ConvertTo(bin_mask, MatType.CV_8UC1);
                if ((nms_results[r].Rectangle.Y + bin_mask.Rows) >= image.Height)
                {
                    box_y2 = (int)image.Height - 1;
                }
                if ((box_x1 + bin_mask.Cols) >= image.Width)
                {
                    box_x2 = (int)image.Width - 1;//image.Width = 3
                }
                // get segment region
                Mat mask = Mat.Zeros(new OpenCvSharp.Size((int)image.Width, (int)image.Height), MatType.CV_8UC1);
                bin_mask = new Mat(bin_mask, new OpenCvSharp.Range(0, box_y2 - box_y1), new OpenCvSharp.Range(0, box_x2 - box_x1));
                Rect roi = new Rect(box_x1, box_y1, box_x2 - box_x1, box_y2 - box_y1);
                bin_mask.CopyTo(new Mat(mask, roi));
                //segment region colorful
// Cv2.Add(rgb_mask, new Scalar(rd.Next(0, 255), rd.Next(0, 255), rd.Next(0, 255), 255), rgb_mask, mask);
                //        Cv2.Add(rgb_mask,null, rgb_mask, mask);
                nms_results[r].RgbMask = rgb_mask;
            }

F 有了分割结果,就看怎样与自己的业务结合处理了,这里对我来说的最重要的是过滤。

过滤无效的书

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值