object detection in csharp

To perform object detection in C#, we can use open source frameworks such as TensorFlowSharp or CNTK (Microsoft Cognitive Toolkit) to leverage machine learning models such as YOLO (You Only Look Once) or SSD (Single Shot Detector). These models are pre-trained on large datasets and can detect objects in real-time images or video.

Here is a sample code using TensorFlowSharp to perform object detection:

main.cs
using TensorFlow;
using System.Linq;

public void DetectObjects(byte[] imageBytes)
{
    using (var graph = new TFGraph())
    {
        var model = File.ReadAllBytes("model.pb");
        graph.Import(model, "");

        using (var session = new TFSession(graph))
        {
            var tensor = ImageUtil.CreateTensorFromBytes(imageBytes);
            var runner = session.GetRunner();

            runner.AddInput(graph["image_tensor"][0], tensor)
                  .Fetch(graph["detection_boxes"][0],
                         graph["detection_scores"][0],
                         graph["detection_classes"][0],
                         graph["num_detections"][0]);

            var output = runner.Run();

            var boxes = (float[,,]) output[0].GetValue(jagged: false);
            var scores = (float[,]) output[1].GetValue(jagged: false);
            var classes = (float[,]) output[2].GetValue(jagged: false);
            var num = (float[]) output[3].GetValue(jagged: false);

            var filteredBoxes = FilterBoxes(boxes, scores, threshold: 0.5f);
            var objects = MapBoxesToObjects(filteredBoxes, classes);

            foreach (var obj in objects)
            {
                Console.WriteLine($"Object: {obj.Label} ({obj.Score})");
                Console.WriteLine($"    Box: [{obj.Box.Left}, {obj.Box.Top}, {obj.Box.Right}, {obj.Box.Bottom}]");
            }
        }
    }
}

public List<YoloResult> MapBoxesToObjects(float[,,] boxes, float[,] classes)
{
    var objects = new List<YoloResult>();

    for (int i = 0; i < boxes.GetLength(1); i++)
    {
        var scores = boxes[0, i, 4];

        if (scores > 0.5)
        {
            var box = new YoloBoundingBox(
                left: boxes[0, i, 1],
                top: boxes[0, i, 0],
                right: boxes[0, i, 3],
                bottom: boxes[0, i, 2]);

            int cls = classes[0, i].ConvertToInt32();
            string label = ObjectClasses.GetClassName(cls);

            objects.Add(new YoloResult() { Label = label, Box = box, Score = scores });
        }
    }

    return objects;
}

public static float IntersectionOverUnion(RectangleF rectA, RectangleF rectB)
{
    float areaA = rectA.Width * rectA.Height;
    float areaB = rectB.Width * rectB.Height;

    float minX = Math.Max(rectA.Left, rectB.Left);
    float minY = Math.Max(rectA.Top, rectB.Top);
    float maxX = Math.Min(rectA.Right, rectB.Right);
    float maxY = Math.Min(rectA.Bottom, rectB.Bottom);

    float intersectionArea = Math.Max(maxY - minY, 0) * Math.Max(maxX - minX, 0);
    float unionArea = areaA + areaB - intersectionArea;

    return intersectionArea / unionArea;
}

public static List<YoloBoundingBox> FilterBoxes(float[,,] boxes, float[,] scores, float threshold)
{
    var results = new List<YoloBoundingBox>();

    for (int i = 0; i < boxes.GetLength(1); i++)
    {
        float score = scores[0, i];

        if (score > threshold)
        {
            var box = new YoloBoundingBox(
                left: boxes[0, i, 1],
                top: boxes[0, i, 0],
                right: boxes[0, i, 3],
                bottom: boxes[0, i, 2]);

            results.Add(box);
        }
    }

    return results;
}
3227 chars
105 lines

Note: This code assumes that the YOLOv2 model is saved in a frozen model.pb file, and object classes are available in ObjectClasses.cs.

gistlibby LogSnag