c# script support

python server support
This commit is contained in:
meelstorm
2025-08-25 17:02:33 +02:00
parent af8ee449a0
commit 07002dd875
22 changed files with 1710 additions and 95 deletions

View File

@@ -14,11 +14,11 @@ public abstract class ColorAIOperation:BaseOperation
public ColorAIOperation(string model_name)
{
_modelName = model_name;
_cSharpDataTransferMQRPC = PythonModelProxyRPC.GetInterface();
_cSharpDataTransferMQRPC = PythonModelProxyHTTP.GetInterface();
CanHaveProcessingError = false;
}
private readonly CSharpDataTransferMQRPC _cSharpDataTransferMQRPC;
private readonly CSharpDataTransferHTTP _cSharpDataTransferMQRPC;
private int _imageWidth;
private int _imageHeight;
@@ -52,15 +52,16 @@ public abstract class ColorAIOperation:BaseOperation
this.SetError("Model file not found");
return;
}
_cSharpDataTransferMQRPC.TransferData<object>(new MethodCall("load_model", ModelFilePath.Path, _modelName));
_cSharpDataTransferMQRPC.LoadModel(ModelFilePath.Path, _modelName);
_initialized = true;
}
_cSharpDataTransferMQRPC.ActivateModel(_modelName);
var sizeEncoded = _cSharpDataTransferMQRPC.GetAcceptSize();
_cSharpDataTransferMQRPC.TransferData<object>(new MethodCall("activate_model", _modelName));
var sizeEncoded = _cSharpDataTransferMQRPC.TransferData<object[]>(new MethodCall("get_accept_size"));
var size = sizeEncoded.Select(Convert.ToInt32).ToArray();
_imageWidth = size[1];
_imageHeight = size[2];
@@ -82,22 +83,30 @@ public abstract class ColorAIOperation:BaseOperation
allowedFlags[i] = 1;
}
var resultEncoded = _cSharpDataTransferMQRPC.TransferData<object[]>(new MethodCall(IsRaw?"predict_raw": "predict", byteArray));
var result = resultEncoded.Select(Convert.ToByte).ToArray();
byte[] result;
if (IsRaw)
{
result = _cSharpDataTransferMQRPC.PredictRaw(byteArray);
}
else
{
result = _cSharpDataTransferMQRPC.Predict(byteArray);
}
byte[] resultColor;
if (IsRaw)
{
resultColor = result.Chunk(25).Select(x =>
{
return x.Select((x, i) => allowedFlags[i] == 1 ? (byte) (x) : (byte) 0).Max();
}).ToArray();
//resultColor = result.Select(x => (byte)(x)).ToArray();
}
else
{
resultColor = result.Select(x => allowedFlags[x]==1? (byte)(x * 255) : (byte)0).ToArray();
resultColor = result.Select(x => allowedFlags[x]==1? (byte)(x * 255.0) : (byte)0).ToArray();
}

View File

@@ -16,11 +16,11 @@ public class RawModelAIOperation: BaseOperation
public RawModelAIOperation()
{
_cSharpDataTransferMQRPC = PythonModelProxyRPC.GetInterface();
_cSharpDataTransferMQRPC = PythonModelProxyHTTP.GetInterface();
CanHaveProcessingError = false;
}
private CSharpDataTransferMQRPC _cSharpDataTransferMQRPC;
private CSharpDataTransferHTTP _cSharpDataTransferMQRPC;
private int _imageWidth;
private int _imageHeight;
@@ -66,34 +66,22 @@ public class RawModelAIOperation: BaseOperation
var absPath = Path.GetFullPath(Path.Combine(dir, ModelFilePath.Path));
ModelFilePath.Path = absPath;
}
_cSharpDataTransferMQRPC.TransferData<object>(new MethodCall("load_model", ModelFilePath.Path, _modelName));
_cSharpDataTransferMQRPC.LoadModel(ModelFilePath.Path, _modelName);
_initialized = true;
}
_cSharpDataTransferMQRPC.ActivateModel(_modelName);
_cSharpDataTransferMQRPC.TransferData<object>(new MethodCall("activate_model", _modelName));
var sizeEncoded = _cSharpDataTransferMQRPC.TransferData<object[]>(new MethodCall("get_accept_size"));
var sizeEncoded = _cSharpDataTransferMQRPC.GetAcceptSize();
var size = sizeEncoded.Select(Convert.ToInt32).ToArray();
_imageWidth = size[1];
_imageHeight = size[2];
_imageWidth = size[0];
_imageHeight = size[1];
var outputSize = _cSharpDataTransferMQRPC.TransferData<object[]>(new MethodCall("get_output_size"));
var outputSize = _cSharpDataTransferMQRPC.GetOutputSize();
var outputSizeArray = outputSize.Select(Convert.ToInt32).ToArray();
int classes;
if (outputSizeArray.Length<3)
{
classes=1;
}
else
{
classes = outputSizeArray[2];
}
var currentImage = context.ActiveImage;
@@ -105,20 +93,11 @@ public class RawModelAIOperation: BaseOperation
var allowed = FilterClasses.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(x => Convert.ToInt32(x)).ToArray();
var allowedFlags = new byte[128];
foreach (var i in allowed)
{
allowedFlags[i] = 1;
}
var resultEncoded = _cSharpDataTransferMQRPC.TransferData<object[]>(new MethodCall("predict_raw", byteArray));
var result = resultEncoded.Select(Convert.ToByte).ToArray();
var result = _cSharpDataTransferMQRPC.PredictRaw(byteArray);
byte[] resultColor;
resultColor = result.Select(x => (byte)(x) ).ToArray();
// black and white mask
var mask = new Mat(outputSizeArray[0], outputSizeArray[1], MatType.CV_8UC1, resultColor);

View File

@@ -59,6 +59,7 @@ public class YoloDetectionOperation:BaseOperation
}
protected override void InterpretInternal(Context context)
{
CheckImageExists(context);
CheckColorful(context);
try
{

View File

@@ -0,0 +1,76 @@
using System.Reflection;
using Compunet.YoloV8;
using Hawkeye.VisionBuilder.Workflow.Datatypes;
using Hawkeye.VisionBuilder.Workflow.Operations.Attributes;
using Microsoft.Scripting.Runtime;
using OpenCvSharp;
namespace Hawkeye.VisionBuilder.Workflow.Operations.Scripts;
[Category("Script")]
public class CSharpProcessOperation:BaseOperation
{
private FilePath _scriptFilePath = new FilePath() { Format = "C# dll(*.dll)|*.dll" };
private bool _initialized;
private object _processor;
private MethodInfo? _method;
public FilePath ScriptFilePath
{
get => _scriptFilePath;
set
{
_scriptFilePath = value;
_initialized = false;
}
}
bool EnsureInitialized()
{
if (!_initialized)
{
if (!File.Exists(ScriptFilePath?.Path))
{
this.SetError("Script file not found");
return false;
}
var absPath = Path.GetFullPath(ScriptFilePath?.Path);
var loadContext = new PluginLoadContext(absPath);
var assembly = loadContext.LoadFromAssemblyPath(absPath);
// find class that has Process method
foreach (var type in assembly.GetTypes())
{
var method = type.GetMethod("ProcessImage", BindingFlags.Public | BindingFlags.Instance);
if (method != null)
{
_processor = Activator.CreateInstance(type);
_method = method;
break;
}
}
Label = Path.GetFileNameWithoutExtension(ScriptFilePath?.Path);
_initialized = true;
}
return true;
}
protected override void InterpretInternal(Context context)
{
CheckImageExists(context);
if (!EnsureInitialized()) return;
var image = context.ActiveImage.ImageData;
var result = (Mat)_method.Invoke(_processor, new []{ image });
context.ActiveImage = new HawkeyeImage()
{
ImageData = result
};
}
}

View File

@@ -0,0 +1,37 @@
using System.Reflection;
using System.Runtime.Loader;
namespace Hawkeye.VisionBuilder.Workflow.Operations.Scripts;
class PluginLoadContext : AssemblyLoadContext
{
private AssemblyDependencyResolver _resolver;
public PluginLoadContext(string pluginPath)
{
_resolver = new AssemblyDependencyResolver(pluginPath);
}
protected override Assembly Load(AssemblyName assemblyName)
{
string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
if (assemblyPath != null)
{
return LoadFromAssemblyPath(assemblyPath);
}
return null;
}
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
{
string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
if (libraryPath != null)
{
return LoadUnmanagedDllFromPath(libraryPath);
}
return IntPtr.Zero;
}
}