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.
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;
}