C# OpenCvSharp DNN HybridNets simultaneously handles vehicle detection, drivable area segmentation, and lane line segmentation

Table of Contents

Effect

Model information

project

code

download


Effect

Simultaneously handles vehicle detection, drivable area segmentation, and lane line segmentation

Model information

Inputs
———————–
name: input
tensor: Float[1, 3, 256, 384]
————————————————– ————-

Outputs
———————–
name:regression
tensor: Float[1, 18414, 4]
name:classification
tensor: Float[1, 18414, 1]
name:segmentation
tensor: Float[1, 3, 256, 384]
————————————————– ————-

project

VS2022

.net framework 4.8

OpenCvSharp 4.8

Microsoft.ML.OnnxRuntime 1.16.2

code

Normalize method

public static void Normalize(Mat src,float[] mean,float[] std)
{
src.ConvertTo(src, MatType.CV_32FC3, 1.0 / 255);

Mat[] bgr = src.Split();
for (int i = 0; i < bgr.Length; + + i)
{
bgr[i].ConvertTo(bgr[i], MatType.CV_32FC1, 1 / std[i], (0.0 – mean[i]) / std[i]);
}

Cv2.Merge(bgr, src);

foreach (Mat channel in bgr)
{
channel.Dispose();
}

}

using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Windows.Forms;

namespace OpenCvSharp_DNN_Demo
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";

        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;

        float confThreshold;
        float nmsThreshold;
        string modelpath;
        string anchorpath;

        int inpHeight;
        int inpWidth;

        float[] mean = { 0.485f, 0.456f, 0.406f };
        float[] std = { 0.229f, 0.224f, 0.225f };

        List<string> det_class_names = new List<string>() { "car" };
        List<string> seg_class_names = new List<string>() { "Background", "Lane", "Line" };
        List<Vec3b> class_colors = new List<Vec3b> { new Vec3b(0, 0, 0), new Vec3b(0, 255, 0), new Vec3b(255, 0, 0) };

        int det_num_class = 1;
        int seg_numclass = 3;

        float[] anchors;

        Net opencv_net;
        Mat BN_image;

        Mat image;
        Mat result_image;

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;

            pictureBox1.Image = null;
            pictureBox2.Image = null;
            textBox1.Text = "";

            image_path = ofd.FileName;
            pictureBox1.Image = new Bitmap(image_path);
            image = new Mat(image_path);
        }

        private void Form1_Load(object sender, EventArgs e)
        {

            confThreshold = 0.3f;
            nmsThreshold = 0.5f;
            modelpath = "model/hybridnets_256x384.onnx";
            anchorpath = "model/anchors_73656.bin";

            inpHeight = 256;
            inpWidth = 384;

            opencv_net = CvDnn.ReadNetFromOnnx(modelpath);

            FileStream fileStream = new FileStream(anchorpath, FileMode.Open);
            //Read binary file class
            BinaryReader br = new BinaryReader(fileStream, Encoding.UTF8);
            int len = 73656;
            anchors = new float[len];

            byte[] byteTemp;
            float fTemp;
            for (int i = 0; i < len; i + + )
            {
                byteTemp = br.ReadBytes(4);
                fTemp = BitConverter.ToSingle(byteTemp, 0);
                anchors[i] = fTemp;
            }
            br.Close();

            image_path = "test_img/test.jpg";
            pictureBox1.Image = new Bitmap(image_path);

        }

        private unsafe void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }
            textBox1.Text = "Detecting, please wait...";
            pictureBox2.Image = null;
            Application.DoEvents();

            image = new Mat(image_path);

            int newh = 0, neww = 0, padh = 0, padw = 0;
            Mat resize_img = Common.ResizeImage(image, inpHeight, inpWidth, ref newh, ref neww, ref padh, ref padw);

            float ratioh = (float)image.Rows / newh;
            float ratiow = (float)image.Cols / neww;

            Mat normalize = Common.Normalize(resize_img, mean, std);

            dt1 = DateTime.Now;

            BN_image = CvDnn.BlobFromImage(normalize);

            //Configure image input data
            opencv_net.SetInput(BN_image);

            //Model inference, read inference results
            Mat[] outs = new Mat[3] { new Mat(), new Mat(), new Mat() };
            string[] outBlobNames = opencv_net.GetUnconnectedOutLayersNames().ToArray();

            opencv_net.Forward(outs, outBlobNames);

            dt2 = DateTime.Now;

            float* classification = (float*)outs[0].Data;
            float* box_regression = (float*)outs[1].Data;
            float* seg = (float*)outs[2].Data;

            List<Rect> boxes = new List<Rect>();
            List<float> confidences = new List<float>();
            List<int> classIds = new List<int>();

            int num_proposal = outs[1].Size(1); //The input is a single image, the 0th dimension batchsize is ignored

            for (int n = 0; n < num_proposal; n + + )
            {
                float conf = classification[n];

                if (conf > confThreshold)
                {
                    int row_ind = n * 4;
                    float x_centers = box_regression[row_ind + 1] * anchors[row_ind + 2] + anchors[row_ind];
                    float y_centers = box_regression[row_ind] * anchors[row_ind + 3] + anchors[row_ind + 1];
                    float w = (float)(Math.Exp(box_regression[row_ind + 3]) * anchors[row_ind + 2]);
                    float h = (float)(Math.Exp(box_regression[row_ind + 2]) * anchors[row_ind + 3]);

                    float xmin = (float)((x_centers - w * 0.5 - padw) * ratiow);
                    float ymin = (float)((y_centers - h * 0.5 - padh) * ratioh);
                    w *= ratiow;
                    h *= ratioh;
                    Rect box = new Rect((int)xmin, (int)ymin, (int)w, (int)h);
                    boxes.Add(box);
                    confidences.Add(conf);
                    classIds.Add(0);
                }

            }

            int[] indices;
            CvDnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, out indices);

            result_image = image.Clone();

            for (int ii = 0; ii < indices.Length; + + ii)
            {
                int idx = indices[ii];
                Rect box = boxes[idx];
                Cv2.Rectangle(result_image, new OpenCvSharp.Point(box.X, box.Y), new OpenCvSharp.Point(box.X + box.Width, box.Y + box.Height), new Scalar(0, 0, 255 ), 2);
                string label = det_class_names[classIds[idx]] + ":" + confidences[idx].ToString("0.00");
                Cv2.PutText(result_image, label, new OpenCvSharp.Point(box.X, box.Y - 5), HersheyFonts.HersheySimplex, 0.75, new Scalar(0, 0, 255), 1);
            }

            int area = inpHeight * inpWidth;
            int i = 0, j = 0, c = 0;
            for (i = 0; i < result_image.Rows; i + + )
            {
                for (j = 0; j < result_image.Cols; j + + )
                {
                    int x = (int)((j / ratiow) + padw); ///Map from the original image back to the output feature map
                    int y = (int)((i / ratioh) + padh);
                    int max_id = -1;
                    float max_conf = -10000;
                    for (c = 0; c < seg_numclass; c + + )
                    {
                        float seg_conf = seg[c * area + y * inpWidth + x];
                        if (seg_conf > max_conf)
                        {
                            max_id = c;
                            max_conf = seg_conf;
                        }
                    }
                    if (max_id > 0)
                    {
                        result_image.Set<Vec3b>(i, j, class_colors[max_id]);
                    }
                }
            }

            pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
            textBox1.Text = "Inference time consumption:" + (dt2 - dt1).TotalMilliseconds + "ms";

        }

        private void pictureBox2_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox2.Image);
        }

        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            Common.ShowNormalImg(pictureBox1.Image);
        }
    }
}

Download

Source code download

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Python entry skill treeHomepageOverview 388590 people are learning the system