Inference with Halcon integration.
Inference with Halcon integration.
The example takes no command-line arguments.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using HalconDotNet;
namespace Mmind.Dl.Examples
{
public class InferWithHalcon
{
public static int Run()
{
Console.WriteLine("MechMind DL SDK C# Halcon Integration Example");
Console.WriteLine("============================================");
try
{
var imagePaths = GetImagePaths();
if (imagePaths.Count == 0)
{
Console.WriteLine("No images found in DefectSegmentation directory");
return 1;
}
Console.WriteLine($"Found {imagePaths.Count} image(s)");
var images = new List<MMindImage>();
foreach (var imagePath in imagePaths)
{
Console.WriteLine($"Loading image with Halcon: {Path.GetFileName(imagePath)}");
HImage halconImage = new HImage();
try
{
halconImage.ReadImage(imagePath);
}
catch (HOperatorException ex)
{
Console.WriteLine($" Failed to load image with Halcon: {ex.Message}");
halconImage.Dispose();
continue;
}
HTuple width = new HTuple(), height = new HTuple();
halconImage.GetImageSize(out width, out height);
int imgWidth = width.I;
int imgHeight = height.I;
Console.WriteLine($" Halcon image loaded: {imgWidth}x{imgHeight}");
byte[] rgbData = HalconImageToRgbBytes(halconImage);
if (rgbData == null || rgbData.Length == 0)
{
Console.WriteLine(" Failed to extract RGB data from Halcon image");
halconImage.Dispose();
continue;
}
Console.WriteLine($" Successfully extracted RGB data from Halcon image: {rgbData.Length} bytes");
var mmindImage = new MMindImage();
var createStatus = mmindImage.CreateFromRgbData(rgbData, imgWidth, imgHeight);
halconImage.Dispose();
{
Console.WriteLine($" Failed to create MMindImage from RGB data: {createStatus}");
continue;
}
Console.WriteLine($" Successfully created MMindImage: {imgWidth}x{imgHeight}");
images.Add(mmindImage);
}
if (images.Count == 0)
{
Console.WriteLine("No images loaded successfully");
return 1;
}
Console.WriteLine("Loading inference engine...");
using (var engine = new MMindInferEngine())
{
engine.Create(GetPackPath());
var status = engine.Load();
{
Console.WriteLine($"Failed to load model: {status}");
return 1;
}
Console.WriteLine("Performing inference...");
status = engine.Infer(images);
{
Console.WriteLine($"Inference failed: {status}");
return 1;
}
status = engine.GetModuleResult("DefectSegmentation_0", out var results);
{
Console.WriteLine($"Failed to get module results: {status}");
return 1;
}
Console.WriteLine("Inference completed successfully!");
Console.WriteLine($"Number of results: {results.Count}");
for (int i = 0; i < results.Count; i++)
{
Console.WriteLine($"Result {i}: {results[i].contours.Count} contours, {results[i].bboxes.Count} bboxes");
}
status = engine.ResultVisualization(images);
{
Console.WriteLine("Results visualized");
try
{
for (int i = 0; i < images.Count; i++)
{
images[i].Show($"Halcon Inference Result {i}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Visualization not available: {ex.Message}");
}
}
foreach (var image in images)
{
image.Dispose();
}
}
return 0;
}
catch (HOperatorException ex)
{
Console.WriteLine($"Halcon error: {ex.Message}");
return 1;
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
Console.WriteLine($"Stack trace: {ex.StackTrace}");
return 1;
}
}
private static byte[] HalconImageToRgbBytes(HImage halconImage)
{
try
{
HTuple width, height;
halconImage.GetImageSize(out width, out height);
int imgWidth = width.I;
int imgHeight = height.I;
HTuple channels = halconImage.CountChannels();
int numChannels = channels.I;
Console.WriteLine($"Halcon image channels: {numChannels}");
if (numChannels == 1)
{
return ConvertGrayToRgb(halconImage, imgWidth, imgHeight);
}
else if (numChannels == 3)
{
return ConvertRgbToRgb(halconImage, imgWidth, imgHeight);
}
else
{
Console.WriteLine($"Unsupported channel count: {numChannels}");
return null;
}
}
catch (Exception ex)
{
Console.WriteLine($"Error converting Halcon image: {ex.Message}");
return null;
}
}
private static byte[] ConvertGrayToRgb(HImage grayImage, int width, int height)
{
try
{
HTuple pointer, type, imgWidth, imgHeight;
HOperatorSet.GetImagePointer1(grayImage, out pointer, out type, out imgWidth, out imgHeight);
string imageType = type.S;
if (imageType != "byte")
{
Console.WriteLine($"Unsupported gray image type: {imageType}. Only byte type is supported.");
return null;
}
int actualWidth = imgWidth.I;
int actualHeight = imgHeight.I;
int grayDataSize = actualWidth * actualHeight;
byte[] grayData = new byte[grayDataSize];
Marshal.Copy(pointer.IP, grayData, 0, grayDataSize);
byte[] rgbData = new byte[grayDataSize * 3];
for (int i = 0; i < grayDataSize; i++)
{
rgbData[i * 3] = grayData[i];
rgbData[i * 3 + 1] = grayData[i];
rgbData[i * 3 + 2] = grayData[i];
}
Console.WriteLine($"Converted grayscale image to RGB: {rgbData.Length} bytes");
return rgbData;
}
catch (Exception ex)
{
Console.WriteLine($"Error converting grayscale to RGB: {ex.Message}");
return null;
}
}
private static byte[] ConvertRgbToRgb(HImage rgbImage, int width, int height)
{
try
{
HTuple pointerRed, pointerGreen, pointerBlue, type, imgWidth, imgHeight;
HOperatorSet.GetImagePointer3(rgbImage, out pointerRed, out pointerGreen, out pointerBlue,
out type, out imgWidth, out imgHeight);
string imageType = type.S;
if (imageType != "byte")
{
Console.WriteLine($"Unsupported RGB image type: {imageType}. Only byte type is supported.");
return null;
}
if (imgWidth.I != width || imgHeight.I != height)
{
Console.WriteLine($"Image size mismatch: expected {width}x{height}, got {imgWidth.I}x{imgHeight.I}");
return null;
}
int channelSize = width * height;
byte[] redChannel = new byte[channelSize];
byte[] greenChannel = new byte[channelSize];
byte[] blueChannel = new byte[channelSize];
Marshal.Copy(pointerRed.IP, redChannel, 0, channelSize);
Marshal.Copy(pointerGreen.IP, greenChannel, 0, channelSize);
Marshal.Copy(pointerBlue.IP, blueChannel, 0, channelSize);
byte[] rgbData = new byte[channelSize * 3];
for (int i = 0; i < channelSize; i++)
{
rgbData[i * 3] = redChannel[i];
rgbData[i * 3 + 1] = greenChannel[i];
rgbData[i * 3 + 2] = blueChannel[i];
}
Console.WriteLine($"Converted RGB image to interleaved format: {rgbData.Length} bytes");
return rgbData;
}
catch (Exception ex)
{
Console.WriteLine($"Error converting RGB image: {ex.Message}");
return null;
}
}
private static string GetPackPath()
{
var resourcesPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..", "resources");
return Path.Combine(resourcesPath, "DefectSegmentation", "defect_segmentation_model.dlkpack");
}
private static List<string> GetImagePaths()
{
var resourcesPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..", "resources");
var imageDir = Path.Combine(resourcesPath, "DefectSegmentation");
var imagePaths = new List<string>();
var imageExtensions = new[] { ".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".tif" };
if (Directory.Exists(imageDir))
{
var files = Directory.GetFiles(imageDir);
foreach (var file in files)
{
var ext = Path.GetExtension(file).ToLower();
if (imageExtensions.Contains(ext))
{
imagePaths.Add(file);
}
}
imagePaths.Sort();
}
return imagePaths;
}
}
}
StatusCode
Status codes for MechMind DL SDK operations.