22 public Model(
string file)
25 Name = Path.GetFileNameWithoutExtension(file);
26 string dir = System.IO.Path.GetDirectoryName(Environment.ProcessPath);
27 File = dir.Replace(
"\\",
"/") +
"/Models/" + file;
28 if (file.EndsWith(
".onnx"))
30 InferenceSession =
new InferenceSession(file);
31 foreach (var m
in InferenceSession.InputMetadata)
33 InputValueTypes.Add(m.Value);
35 foreach (var m
in InferenceSession.InputNames)
37 InputValueNames.Add(m);
39 foreach (var m
in InferenceSession.OutputMetadata)
41 OutputValueTypes.Add(m.Value);
44 else if (file.EndsWith(
".pt"))
49 Module = torch.jit.load(File);
51 var chs = Module.named_modules();
52 var input = chs.First();
53 InputModule = input.module;
54 var output = chs.Last();
55 OutputModule = output.module;
59 Console.WriteLine(
"Failed to run pytorch model. Ensure that PyTorch is properly installed.");
60 Console.WriteLine(e.Message.ToString());
62 string f = System.IO.Path.GetDirectoryName(System.Environment.ProcessPath) +
"/Models/" + Path.GetFileNameWithoutExtension(file) +
".yaml";
63 if (!System.IO.File.Exists(f))
65 Gtk.MessageDialog md =
new Gtk.MessageDialog(App.tabsView, Gtk.DialogFlags.Modal, Gtk.MessageType.Error, Gtk.ButtonsType.Ok,
"No corresponding model Yaml metadata file for:" + Name);
70 using (var reader =
new StreamReader(f))
72 var dynamicDeserializer =
new DeserializerBuilder().Build();
73 Metadata = dynamicDeserializer.Deserialize<Dictionary<string, object>>(reader);
74 IDictionary conf = (IDictionary)Metadata[
"config"];
75 Object inpp = Metadata[
"inputs"];
76 List<Object> inpps = (List<Object>)inpp;
77 IDictionary inpinfo = (IDictionary)inpps[0];
78 IDictionary imagej = (IDictionary)conf[
"deepimagej"];
79 IDictionary test = (IDictionary)imagej[
"test_information"];
80 Object inputs = test[
"inputs"];
81 List<Object> inps = (List<Object>)inputs;
82 IDictionary info = (IDictionary)inps[0];
83 IDictionary inputinfo = (IDictionary)inpps[0];
84 IDictionary shapeinfo = (IDictionary)inputinfo[
"shape"];
85 if (shapeinfo !=
null)
87 List<Object> shapeinfomin = (List<Object>)shapeinfo[
"min"];
88 int len = shapeinfomin.Count;
89 string size = (string)info[
"size"];
90 string[] sts = size.Split(
"x");
91 if (len != sts.Length)
93 shape =
new long[len];
94 for (
int i = 0; i < len; i++)
96 if (len - i > sts.Length)
102 shape[i] =
long.Parse(sts[sts.Length - i]);
108 shape =
new long[sts.Length];
109 for (
int i = 0; i < sts.Length; i++)
112 shape[i] =
long.Parse(s);
115 List<Object> val = (List<Object>)inpinfo[
"data_range"];
116 MaxValue =
int.Parse(val[1].ToString());
120 string sh = (string)info[
"size"];
121 string[] sts = (
string[])sh.Split(
"x");
122 IList inp = (IList)inputinfo[
"axes"];
124 shape =
new long[co];
125 for (
int i = 0; i < co; i++)
127 IDictionary dict = (IDictionary)inp[i];
128 string type = (string)dict[
"type"];
129 string id = (string)dict[
"id"];
134 if (type ==
"channel")
136 shape[co - 4] =
long.Parse(sts[3]);
140 shape[co - 3] =
long.Parse(sts[2]);
144 shape[co - 2] =
long.Parse(sts[1]);
148 shape[co - 1] =
long.Parse(sts[0]);
155 BioLib.Recorder.AddLine(
"BioGTK.ML.Model model = new BioGTK.ML.Model(\"" + file +
"\");",
false);
157 public Dictionary<string, object> Metadata {
get;
set; } =
null;
158 public InferenceSession InferenceSession {
get;
set; }
159 public torch.jit.ScriptModule Module {
get;
set; }
160 public torch.nn.Module InputModule {
get;
set; }
161 public torch.nn.Module OutputModule {
get;
set; }
162 private List<NodeMetadata> InputValueTypes {
get;
set; } =
new List<NodeMetadata>();
163 private List<NodeMetadata> OutputValueTypes {
get;
set; } =
new List<NodeMetadata>();
164 private List<string> InputValueNames {
get;
set; } =
new List<string>();
165 public string File {
get;
set; }
166 public string Name {
get;
set; }
171 if (File.EndsWith(
".onnx"))
173 if (InputValueTypes.Count > 0)
175 int w = InputValueTypes[0].Dimensions[2];
178 if (OutputValueTypes.Count > 0)
180 for (
int i = 0; i < OutputValueTypes.Count; i++)
182 int max =
int.MinValue;
183 for (
int j = 0; j < OutputValueTypes[i].Dimensions.Length; j++)
185 if (OutputValueTypes[i].Dimensions[j] > max)
186 max = OutputValueTypes[i].Dimensions[j];
198 if (shape.Length == 4)
199 return (
int)Shape[0];
201 return (
int)Shape[4];
209 if (File.EndsWith(
".onnx"))
211 if (InputValueTypes.Count > 0)
213 int h = InputValueTypes[0].Dimensions[3];
216 if (OutputValueTypes.Count > 0)
218 for (
int i = 0; i < OutputValueTypes.Count; i++)
220 int max =
int.MinValue;
221 for (
int j = 0; j < OutputValueTypes[i].Dimensions.Length; j++)
223 if (OutputValueTypes[i].Dimensions[j] > max)
224 max = OutputValueTypes[i].Dimensions[j];
236 if (shape.Length == 4)
237 return (
int)Shape[1];
239 return (
int)Shape[3];
247 if (shape.Length == 4)
248 return (
int)Shape[2];
250 return (
int)shape[1];
258 if (Metadata ==
null)
259 return new long[] { 1, 3, 256, 256 };
266 public int MaxValue {
get;
set; }
267 public ModelOutputType ModelType {
get;
set; }
268 public enum ModelOutputType
273 public void Run(BioImage b)
275 if (File.EndsWith(
".onnx"))
277 else if (File.EndsWith(
".pt"))
279 BioLib.Recorder.AddLine(
"model.Run(Images.GetImage(\"" + b.Filename +
"\");",
false);
281 public void RunONNX(BioImage b)
283 BioImage bb =
new BioImage(
"output.ome.tif");
284 if (b.Type != BioImage.ImageType.pyramidal)
286 for (
int i = 0; i < b.Buffers.Count; i++)
288 Bitmap bm = ResizeBilinear(b.Buffers[i], Width, Height);
291 int d = InputValueTypes[0].Dimensions[1];
292 float[] img =
new float[w * h * d];
293 for (
int y = 0; y < h; y++)
295 for (
int x = 0; x < w; x++)
297 for (
int c = 0; c < d; c++)
299 int index = (y * w * d) + x;
300 if (c > bm.RGBChannelsCount)
306 if (bm.BitsPerPixel > 8)
307 img[index] = bm.GetValue(x, y, c);
309 img[index] = bm.GetValue(x, y, c);
314 var tensor =
new DenseTensor<float>(img,
new[] { 1, InputValueTypes[0].Dimensions[1], w, h });
315 var inputs =
new List<NamedOnnxValue>
317 NamedOnnxValue.CreateFromTensor(InputValueNames[0], tensor)
319 var results = InferenceSession.Run(inputs);
321 foreach (var result
in results)
323 if (OutputValueTypes[r].Dimensions[3] == Width)
325 float[] outputmask = result.AsTensor<
float>().ToArray();
326 double mean = outputmask.Mean();
327 for (
int c = 0; c < OutputValueTypes[r].Dimensions[1]; c++)
329 Bitmap bmp =
new Bitmap(Width, Height, b.Buffers[0].PixelFormat);
330 for (
int y = 0; y < h; y++)
332 for (
int x = 0; x < w; x++)
334 int index = (y * w * d) + x;
335 bmp.SetPixel(x, y,
new ColorS((ushort)(outputmask[index] / mean)));
338 bb.Buffers.Add(ResizeBilinear(bmp, b.SizeX, b.SizeY));
344 bb.Channels.AddRange(b.Channels);
345 if (OutputValueTypes[0].Dimensions[1] > 1)
347 bb.Channels.AddRange(b.Channels);
348 for (
int i = 0; i < bb.Channels.Count; i++)
350 bb.Channels[i].Index = i;
353 bb.UpdateCoords(b.SizeZ, b.SizeC * OutputValueTypes[0].Dimensions[1], b.SizeT);
354 bb.Resolutions.Add(
new Resolution(bb.SizeX, bb.SizeY, bb.Buffers[0].PixelFormat, b.PhysicalSizeX, b.PhysicalSizeY, b.PhysicalSizeZ, b.StageSizeX, b.StageSizeY, b.StageSizeZ));
355 bb.Volume = b.Volume;
356 BioImage.AutoThreshold(bb,
true);
360 throw new NotImplementedException();
362 public void RunTorch(BioImage b)
364 BioImage bb =
new BioImage(
"output.ome.tif");
365 if (b.Type != BioImage.ImageType.pyramidal)
369 if (shape.Length == 4)
371 for (
int i = 0; i < b.Buffers.Count; i++)
373 Bitmap bm = ResizeBilinear(b.Buffers[i], Width, Height);
378 if (shape[0] > shape[3])
380 img =
new float[1, Depth, Width, Height];
384 img =
new float[Width, Height, Depth, 1];
386 for (
int y = 0; y < h; y++)
388 for (
int x = 0; x < w; x++)
390 for (
int c = 0; c < d; c++)
392 int index = (y * w * c) + x;
393 if (c >= bm.RGBChannelsCount)
399 if (bm.BitsPerPixel > 8)
400 img[0, c, x, y] = ((float)bm.GetValue(x, y, c) / (
float)ushort.MaxValue) * MaxValue;
402 img[0, c, x, y] = ((float)bm.GetValue(x, y, c) / (
float)
byte.MaxValue) * MaxValue;
407 var tensor = torch.tensor(img);
408 object results =
null;
411 results = Module.forward(tensor);
415 Console.WriteLine(e.ToString());
417 TorchSharp.Utils.TensorAccessor<
float> outputmask = ((torch.Tensor)results).data<float>();
418 double mean = outputmask.Mean();
419 resDepth = (int)((torch.Tensor)results).shape[1];
420 for (
int c = 0; c < resDepth; c++)
422 Bitmap bmp =
new Bitmap(Width, Height, b.Buffers[0].PixelFormat);
423 for (
int y = 0; y < h; y++)
425 for (
int x = 0; x < w; x++)
427 int index = (y * w * c) + x;
428 bmp.SetPixel(x, y,
new ColorS((ushort)(outputmask[index] / mean)));
431 bb.Buffers.Add(ResizeBilinear(bmp, b.SizeX, b.SizeY));
432 bb.Buffers[bb.Buffers.Count - 1].RotateFlip(AForge.RotateFlipType.Rotate90FlipX);
438 else if (shape.Length == 5)
440 torch.Tensor tensor = torch.empty(shape);
441 for (
int i = 0; i < shape[2]; i++)
443 Bitmap bm = ResizeBilinear(b.Buffers[i], Width, Height);
444 for (
int y = 0; y < Height; y++)
446 for (
int x = 0; x < Width; x++)
448 for (
int c = 0; c < Depth; c++)
450 if (c >= bm.RGBChannelsCount)
452 tensor[0, c, i, x, y] = 0;
456 if (bm.BitsPerPixel > 8)
457 tensor[0, c, i, x, y] = ((float)bm.GetValue(x, y, c) / (
float)ushort.MaxValue) * MaxValue;
459 tensor[0, c, i, x, y] = ((float)bm.GetValue(x, y, c) / (
float)
byte.MaxValue) * MaxValue;
465 torch.Tensor outputmask = (torch.Tensor)Module.forward(tensor);
466 resDepth = (int)(outputmask.shape[1]);
467 for (
int c = 0; c < resDepth; c++)
469 for (
int buf = 0; buf < (int)outputmask.shape[2]; buf++)
471 Bitmap bmp =
new Bitmap((
int)outputmask.shape[3], (
int)outputmask.shape[4], b.Buffers[0].PixelFormat);
472 for (
int y = 0; y < Height; y++)
474 for (
int x = 0; x < Width; x++)
476 float by = outputmask[0, c, buf, x, y].ToSingle();
477 bmp.SetPixel(x, y,
new ColorS((ushort)(by *
byte.MaxValue)));
480 bb.Buffers.Add(ResizeBilinear(bmp, b.SizeX, b.SizeY));
481 bb.Buffers[bb.Buffers.Count - 1].RotateFlip(AForge.RotateFlipType.Rotate90FlipX);
485 bb.Channels.AddRange(b.Channels);
488 bb.Channels.AddRange(b.Channels);
489 for (
int i = 0; i < bb.Channels.Count; i++)
491 bb.Channels[i].Index = i;
494 bb.UpdateCoords(b.SizeZ, b.SizeC * resDepth, b.SizeT);
495 bb.Resolutions.Add(
new Resolution(bb.SizeX, bb.SizeY, bb.Buffers[0].PixelFormat, b.PhysicalSizeX, b.PhysicalSizeY, b.PhysicalSizeZ, b.StageSizeX, b.StageSizeY, b.StageSizeZ));
496 bb.Volume = b.Volume;
497 BioImage.AutoThreshold(bb,
true);
498 App.tabsView.AddTab(bb);
501 throw new NotImplementedException();