guojin-yan / YoloDeployCsharp

Deploying Yolov8-det, Yolov8-pose, Yolov8-cls, and Yolov8-seg models based on C # programming language.
Apache License 2.0
132 stars 35 forks source link

Yolov5-cls #3

Closed sctrueew closed 1 year ago

sctrueew commented 1 year ago

Hi, thanks for your work

Is it possible to give me a tip to infer Yolov5-cls with this code? I tested it for y5 and I got the strange result.

Thanks in advanced

guojin-yan commented 1 year ago

I have not tested the Yolov5-cls model, but the conventional processing method of the classification model is consistent. Therefore, you need to modify the corresponding result processing code according to the output nodes of the Yolov5-cls model

sctrueew commented 1 year ago

I have trained a Yolov8-cls model with 3 classes.

Train: yolo classify train data=d:\classify model=yolov8s-cls.pt epochs=10 imgsz=224

Export: yolo export model="..\weights\best.pt" format=onnx imgsz=224 opset=12

and the prediction successfully works yolo classify predict model=..\weights\best.onnx source="../test.jpg" imgsz=224

but when I want to infer with this code I get the strange results

`

string model_path = @"..\weights\best.onnx";

 int numclass = 3;
 Size netSize = new Size(224, 224);

 Console.WriteLine("------Yolov8 Classification model deploy OpenCV-------\n");
 Net? opencv_net = CvDnn.ReadNetFromOnnx(model_path);

foreach (var item in Directory.GetFiles(@"..\test").Take(100))
 {

    Mat image = new Mat(item);
    int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows;
    Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3);
    Rect roi = new Rect(0, 0, image.Cols, image.Rows);
    image.CopyTo(new Mat(max_image, roi));

    Mat BN_image = CvDnn.BlobFromImage(max_image, 1 / 255.0, netSize, new Scalar(0, 0, 0), true, false);

    opencv_net.SetInput(BN_image);
    Mat result_mat = opencv_net.Forward();
    Mat result_mat_to_float = new Mat(1, numclass, MatType.CV_32F, result_mat.Data);

    float[] result_array = new float[numclass];
    result_mat_to_float.GetArray<float>(out result_array);

    ClasResult result_pro = new ClasResult();
    var result_cls = result_pro.process_result(result_array);
    var str = string.Join(", ", result_cls.Select(f => $"{f.Key} = {f.Value}").ToArray());
    Console.WriteLine($"{Path.GetFileNameWithoutExtension(item)} ==> {str}");

}

`

sctrueew commented 1 year ago

the result for Yolo is:

image 1/1 ..\2ba7c53d9c994bdb84c550dc6c6655ea_1239.jpg: 224x224 cls_2 1.00, cls_1 0.00, cls_0 0.00, 3.0ms

but the result in .Net:

..\2ba7c53d9c994bdb84c550dc6c6655ea_1239.jpg ==> cls_1 = 0.8034762 cls_2 = 0.1888457 cls_0 = 0.007678033

guojin-yan commented 1 year ago

You can check whether the preprocessing of the image is consistent with the requirements of the model, and whether the input and output data types of the model are consistent.

sctrueew commented 1 year ago

You can check whether the preprocessing of the image is consistent with the requirements of the model, and whether the input and output data types of the model are consistent.

I'm using the default setting

sctrueew commented 1 year ago

@guojin-yan Could you please guide me? I couldn't solve the problem.

guojin-yan commented 1 year ago

At present, I can not find the reason for your problem. Because the problem with the general inference result is mainly caused by the inconsistency between the input pre-processing and the model, or the data type error when the model result is read, it should not be caused by the model inference tool. You can compare the input of the model with that of yolov5. Or print out the output of the model and see if there is a problem

sctrueew commented 1 year ago

I'm using yolov8 not v5 and my model is trained by v8. It may be from the image input, I am using your code and OpenCV. I tested with the original model (yolov8s-cls) and the result is correct but in the custom dataset, the result is wrong.

guojin-yan commented 1 year ago

You can just read the output of the model and see if the output is faulty? Or is there a problem with the latter processing

sctrueew commented 1 year ago

I fixed it, you should change this part of your code:

From: `

Mat image = new Mat(image_path);
int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows;
Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3);
Rect roi = new Rect(0, 0, image.Cols, image.Rows);
image.CopyTo(new Mat(max_image, roi));
Mat BN_image = CvDnn.BlobFromImage(max_image , 1.0 / 255.0, netSize, new Scalar(0, 0, 0), true, false);

`

To: `

Mat image = new Mat(image_path);
Mat BN_image = CvDnn.BlobFromImage(image, 1.0 / 255.0, netSize, new Scalar(0, 0, 0), true, true);

`