YOLO image recognition + drawing (.NET LTS)
This sample is the image-based equivalent of the CmdTest.Net sample flow:
- load an image from disk
- load a YOLO ONNX model via
AddYoloModelDetectionRecognitionOption - run recognition using
Recognizer - draw detections onto the image via
AddYoloModelDetectionDrawingOptions - save the resulting image
Prerequisites and packages
Applies to CapCognition SDK 2.2.x and .NET 10 on Windows x64, Linux x64, or Linux ARM64 (Raspberry Pi OS 64-bit). See platform requirements and licensing.
Place input.jpg and your YOLO object-detection ONNX export yolo-model.onnx in the working directory. The module supports YOLO 5, 8, 26, and 26 e2e variants. The export must have the input/output layout and class metadata expected by the SDK; an arbitrary ONNX model is not sufficient. Check model loading before deploying a custom export.
dotnet add package CapCognition.Net
dotnet add package CapCognition.Net.YoloModelDetection
dotnet add package Microsoft.Extensions.Logging.Console
dotnet add package Microsoft.Extensions.Logging.Debug
Use compatible 2.2.x SDK packages. Replace Program.cs with the example and run dotnet run. Expected output: a detection count and input_yolo_result.png beside the input. Zero detections is valid for an image without matching objects. Call YoloModelDetection.Use() without an argument for trial mode, or pass a production license.
Example code
using CapCognition.Net;
using CapCognition.Net.Core.Processing.Common;
using CapCognition.Net.YoloModelDetection.Common;
using CapCognition.Net.YoloModelDetection.Processor;
using Microsoft.Extensions.Logging;
using SkiaSharp;
// Input image + YOLO model
const string imagePath = @"input.jpg";
const string modelPath = @"yolo-model.onnx";
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(LogLevel.Information);
builder.AddConsole();
builder.AddDebug();
});
// Initialize CapCognition once at program start
CapCognition.Net.Core.CapCognition.Initialize(
loggerFactory,
[
YoloModelDetection.Use(/* Add your license code here */),
]);
CapCognition.Net.Core.CapCognition.EnableImageProcessingLogs = true;
// YOLO recognition options
using var modelStreamInfo = new YoloModelDetectionRecognitionOptions.ModelStreamInfo(
new FileStream(modelPath, FileMode.Open, FileAccess.Read),
streamName: Path.GetFileNameWithoutExtension(modelPath));
var recognitionOptions = new RecognitionOptionBuilder()
.AddYoloModelDetectionRecognitionOption()
.UseFittedImageForRecognition()
.UseModel(modelStreamInfo)
.ConfigureOption(opt =>
{
// Optional: control model caching behavior
//opt.ClearModelCacheFolder();
if (!opt.CreateAndLoadModel())
{
throw new InvalidOperationException("Could not load the YOLO model; check the export and metadata.");
}
})
.Done()
.Build();
try
{
// Drawing options (draw bounding boxes)
var drawingOptions = new ResultDrawingOptionsBuilder()
.AddYoloModelDetectionDrawingOptions()
.DisplayObjectSurroundingBox()
.Done()
.Build();
using var bitmap = SKBitmap.Decode(imagePath);
if (bitmap == null)
{
Console.WriteLine($"Could not load image: {imagePath}");
return;
}
using var recognizer = new Recognizer();
var prepared = recognizer.PrepareProcessorsAsync(bitmap.Width, bitmap.Height, recognitionOptions)
.GetAwaiter().GetResult();
if (!prepared)
{
Console.WriteLine("Failed to prepare YOLO processor");
return;
}
// Pass drawing options so detections are drawn onto the bitmap.
// disableBitmapDisposal keeps the bitmap alive after processing.
var result = recognizer.ProcessImageAsync(bitmap, drawingOptions, disableBitmapDisposal: true)
.GetAwaiter().GetResult();
if (result == null)
{
Console.WriteLine("Recognition failed");
return;
}
Console.WriteLine($"Detected {result.Results.Count} object(s)");
var outputDir = Path.GetDirectoryName(Path.GetFullPath(imagePath))!;
var outputPath = Path.Combine(
outputDir,
Path.GetFileNameWithoutExtension(imagePath) + "_yolo_result.png");
using var encoded = bitmap.Encode(SKEncodedImageFormat.Png, 90);
File.WriteAllBytes(outputPath, encoded.ToArray());
Console.WriteLine($"Wrote result image: {outputPath}");
}
finally
{
recognitionOptions.Dispose();
}
Step-by-step explanation
Input files
imagePathpoints to the input image.modelPathpoints to your YOLO ONNX model.- With relative paths like
"input.jpg", the files are resolved relative to the current working directory of your app.
Logging (optional, but recommended)
- A
LoggerFactoryis created so the SDK can emit diagnostic messages (console + debug output).
- A
Initialize CapCognition (once per process)
CapCognition.Initialize(...)must be called once at program startup.- You pass the license codes for the modules you want to use (here:
YoloModelDetection).
(Optional) enable image processing logs
CapCognition.EnableImageProcessingLogs = truecan help during setup/debugging.
Image-only processing
- This sample loads a bitmap directly and does not initialize video capture or download RTSP codecs.
Create YOLO recognition options
- A
ModelStreamInfois created from the ONNX file. AddYoloModelDetectionRecognitionOption()configures the YOLO processor.UseFittedImageForRecognition()typically gives good results for object detection.CreateAndLoadModel()ensures the model is loaded before processing starts.ClearModelCacheFolder()is optional; useful if you want to force a clean reload while iterating.
- A
Create drawing options
AddYoloModelDetectionDrawingOptions()controls how detections are rendered.DisplayObjectSurroundingBox()draws bounding boxes on the output image.
Load the image
SKBitmap.Decode(imagePath)loads the bitmap into memory.- If loading fails, the program exits early.
Prepare processors
PrepareProcessorsAsync(width, height, recognitionOptions)pre-allocates internal resources for the given image size.- This should be called before the first
ProcessImageAsync(...).
Run recognition + draw results
ProcessImageAsync(bitmap, drawingOptions, disableBitmapDisposal: true)runs detection.- Because you pass
drawingOptions, the SDK draws the detection overlays directly ontobitmap. disableBitmapDisposal: trueensures the bitmap stays usable after processing.
Save the result image
- The sample writes
*_yolo_result.pngnext to the input image (resolved viaPath.GetFullPath(imagePath)so relative paths work reliably).
- The sample writes
Cleanup
recognitionOptions.Dispose()releases resources associated with the configured processors/models.