Files
HawkeyeVision/VisionBuilder.UI.Ringbuffer/VisionBuilderRingbuffer.cs
2025-07-14 12:03:59 +02:00

127 lines
4.2 KiB
C#

using Inspectron.Fastbuffer;
using Inspectron.Fastbuffer.Filesystems;
using System.Drawing;
using System.Drawing.Imaging;
using OpenCvSharp;
using VisionBuilder.UI.Common.Commands;
using VisionBuilder.UI.Common.RecipeProcessing;
namespace Lindt.Colorballs.Duo.Utils;
public class VisionBuilderRingbuffer
{
private readonly VisionBuilderRingbufferSettings _settings;
private readonly IRecognitionControl _recognitionControl;
public VisionBuilderRingbuffer(VisionBuilderRingbufferSettings settings, IRecognitionControl recognitionControl)
{
_settings = settings;
_recognitionControl = recognitionControl;
_recognitionControl.SessionStarted += _recognitionControl_SessionStarted;
_recognitionControl.ImageProcessed += _recognitionControl_ImageProcessed;
}
private void _recognitionControl_ImageProcessed(VisionBuilder.UI.Common.Commands.ImageProcessedEvent obj)
{
if (obj.HasError)
{
WriteBadResult(obj);
return;
}
WriteGoodResult(obj);
}
private void _recognitionControl_SessionStarted(VisionBuilder.UI.Common.Commands.SessionStartedEvent obj)
{
NewProduct(obj.RecipeName);
}
private IsolatedRingbuffer _goodRingbufferIsolated;
private string _path;
private DateTime _startTime;
private string _product;
public void Dispose()
{
}
public void WriteGoodResult(ImageProcessedEvent result)
{
if (result.ImageOriginal == null) return;
var filename = PathSettingsUtils.ConvertVariables(_settings.FilenameTemplate, DateTime.Now, _startTime, _product,cameraName: _settings.CameraName) + ".png";
try
{
var image = result.ImageOriginal;
// save to memory stream
_goodRingbufferIsolated.Write(image.ToBytes(), filename);
}
catch (Exception e)
{
Console.WriteLine($"Error writing good result at {filename}: " + e.Message);
}
}
Dictionary<string, IsolatedRingbuffer> _badRingbuffers = new Dictionary<string, IsolatedRingbuffer>();
private IsolatedRingbuffer GetBadRingbuffer(string defectName)
{
if (_badRingbuffers.ContainsKey(defectName))
{
return _badRingbuffers[defectName];
}
var path = PathSettingsUtils.ConvertVariables(Path.Combine(_settings.Root, _settings.BadImagesPathTemplate), _startTime, _startTime, _product, cameraName: _settings.CameraName);
var ringbuffer = new IsolatedRingbuffer(path, _settings.MaxBad, new AsyncFilesystem());
_badRingbuffers[defectName] = ringbuffer;
return ringbuffer;
}
private void SaveResultImage(Mat image, string defectName, DateTime time, bool isAnalysis)
{
var filename = PathSettingsUtils.ConvertVariables(_settings.FilenameTemplate,time,_startTime,_product,defectName,_settings.CameraName) + (isAnalysis ? "_analysis" : "") + ".png";
var ringbuffer = GetBadRingbuffer(defectName);
try
{
ringbuffer.Write(image.ToBytes(), filename);
}
catch (Exception e)
{
Console.WriteLine($"Error writing bad result for {filename}: " + e.Message);
}
}
public void WriteBadResult(ImageProcessedEvent result)
{
var defectName = "unknown";
if (result.ErrorNames.Any())
{
defectName = result.ErrorNames.First();
}
var time = DateTime.Now;
SaveResultImage(result.ImageOriginal, defectName, time, false);
SaveResultImage(result.ImageAnalysis, defectName, time, true);
}
public void NewProduct(string product)
{
_startTime = DateTime.Now;
_product = product;
_path = PathSettingsUtils.ConvertVariables(Path.Combine(_settings.Root,_settings.GoodImagesPathTemplate), _startTime, _startTime, _product,cameraName:_settings.CameraName);
_goodRingbufferIsolated?.Dispose();
_goodRingbufferIsolated = new IsolatedRingbuffer(_path, _settings.MaxGood, new AsyncFilesystem());
foreach (var ringbuffer in _badRingbuffers)
{
ringbuffer.Value.Dispose();
}
_badRingbuffers.Clear();
}
}