21 public static MicroSAM theSingleton =
null;
22 InferenceSession decoder;
23 InferenceSession encoder;
24 public float mask_threshold = 0.0f;
25 public bool Initialized
27 get {
if (encoder !=
null)
return true;
else return false; }
38 if (
null == theSingleton)
48 if (this.decoder !=
null)
49 this.decoder.Dispose();
50 if (this.encoder !=
null)
51 this.encoder.Dispose();
52 string exePath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
53 string decoder_model_path = exePath +
"/micro-sam-decoder.onnx";
54 this.decoder =
new InferenceSession(decoder_model_path);
55 string encoder_model_path = exePath +
"/micro-sam-encoder.onnx";
56 this.encoder =
new InferenceSession(encoder_model_path);
59 public new void Encode()
71 if (b.Buffers.Count * 3 * 1024 * 1024 > 4e8)
74 MessageDialog msgBox =
new MessageDialog(
78 ButtonsType.Ok | ButtonsType.Cancel,
79 "Memory required is more than 4GB are you sure you want to continue?"
83 if (msgBox.Run() != (
int)ResponseType.Ok)
88 Application.Invoke(delegate
94 foreach (Bitmap bu
in b.Buffers)
98 var tensor =
new DenseTensor<float>(img,
new[] { 1, 3, 1024, 1024 });
99 IDisposableReadOnlyCollection<DisposableNamedOnnxValue> results =
null;
100 List<NamedOnnxValue> inputs =
new List<NamedOnnxValue>
102 NamedOnnxValue.CreateFromTensor(
"image", tensor)
106 results = this.encoder.Run(inputs);
110 Console.WriteLine(
"Tried running SAM-2 next trying SAM-1");
115 inputs =
new List<NamedOnnxValue>
117 NamedOnnxValue.CreateFromTensor(
"x", tensor)
119 results = this.encoder.Run(inputs);
123 b.Tag =
new List<float[]>();
125 List<float[]> l = (List<float[]>)b.Tag;
127 l.Add(results.First().AsTensor<
float>().ToArray());
129 l.Add(results.Last().AsTensor<
float>().ToArray());
132 pr.ProgressValue = (double)i / b.Buffers.Count;
136 Application.Invoke(delegate
140 BioLib.Recorder.AddLine(
"MicroSAM.Encode(Images.GetImage(\"" + b.Filename +
"\"));",
false);
152 public new float[]
Decode(BioImage b, List<Promotion> promotions,
int orgWid,
int orgHei)
154 ZCT c = App.viewer.GetCoordinate();
155 List<float[]> lts = (List<float[]>)b.Tag;
156 int fr = b.GetFrameIndex(c.Z, c.C, c.T);
157 var embedding_tensor =
new DenseTensor<float>(lts[fr],
new[] { 1, 256, 64, 64 });
158 var bpmos = promotions.FindAll(e => e.mType == PromotionType.Box);
159 var pproms = promotions.FindAll(e => e.mType == PromotionType.Point);
160 int boxCount = promotions.FindAll(e => e.mType == PromotionType.Box).Count();
161 int pointCount = promotions.FindAll(e => e.mType == PromotionType.Point).Count();
162 float[] promotion =
new float[2 * (boxCount * 2 + pointCount)];
163 float[] label =
new float[boxCount * 2 + pointCount];
164 for (
int i = 0; i < boxCount; i++)
166 var input = bpmos[i].GetInput();
167 for (
int j = 0; j < input.Count(); j++)
169 promotion[4 * i + j] = input[j];
171 var la = bpmos[i].GetLable();
172 for (
int j = 0; j < la.Count(); j++)
174 label[2 * i + j] = la[j];
177 for (
int i = 0; i < pointCount; i++)
179 var p = pproms[i].GetInput();
180 for (
int j = 0; j < p.Count(); j++)
182 promotion[boxCount * 4 + 2 * i + j] = p[j];
184 var la = pproms[i].GetLable();
185 for (
int j = 0; j < la.Count(); j++)
187 label[boxCount * 2 + i + j] = la[j];
191 var point_coords_tensor =
new DenseTensor<float>(promotion,
new[] { 1, boxCount * 2 + pointCount, 2 });
193 var point_label_tensor =
new DenseTensor<float>(label,
new[] { 1, boxCount * 2 + pointCount });
195 float[] mask =
new float[256 * 256];
196 for (
int i = 0; i < mask.Count(); i++)
200 var mask_tensor =
new DenseTensor<float>(mask,
new[] { 1, 1, 256, 256 });
202 float[] hasMaskValues =
new float[1] { 0 };
203 var hasMaskValues_tensor =
new DenseTensor<float>(hasMaskValues,
new[] { 1 });
205 var decode_inputs =
new List<NamedOnnxValue>();
207 float[] orig_im_size_values = { (float)orgHei, (
float)orgWid };
208 var orig_im_size_values_tensor =
new DenseTensor<float>(orig_im_size_values,
new[] { 2 });
209 decode_inputs =
new List<NamedOnnxValue>
211 NamedOnnxValue.CreateFromTensor(
"image_embeddings", embedding_tensor),
212 NamedOnnxValue.CreateFromTensor(
"point_coords", point_coords_tensor),
213 NamedOnnxValue.CreateFromTensor(
"point_labels", point_label_tensor),
214 NamedOnnxValue.CreateFromTensor(
"mask_input", mask_tensor),
215 NamedOnnxValue.CreateFromTensor(
"has_mask_input", hasMaskValues_tensor),
216 NamedOnnxValue.CreateFromTensor(
"orig_im_size", orig_im_size_values_tensor)
219 var segmask = this.decoder.Run(decode_inputs);
220 var outputmask = segmask.First().AsTensor<
float>().ToArray();
221 BioLib.Recorder.AddLine(
"App.samTool.microsam.Decode(Images.GetImage(\"" + b.Filename +
"\"),App.samTool.Promotions," + orgWid +
"," + orgHei +
");",
false);
225 public new MaskData Decode(List<Promotion> promotions,
float[] embedding,
int orgWid,
int orgHei)
227 var embedding_tensor =
new DenseTensor<float>(embedding,
new[] { 1, 256, 64, 64 });
229 var bpmos = promotions.FindAll(e => e.mType == PromotionType.Box);
230 var pproms = promotions.FindAll(e => e.mType == PromotionType.Point);
231 int boxCount = promotions.FindAll(e => e.mType == PromotionType.Box).Count();
232 int pointCount = promotions.FindAll(e => e.mType == PromotionType.Point).Count();
233 float[] promotion =
new float[2 * (boxCount * 2 + pointCount)];
234 float[] label =
new float[boxCount * 2 + pointCount];
235 for (
int i = 0; i < boxCount; i++)
237 var input = bpmos[i].GetInput();
238 for (
int j = 0; j < input.Count(); j++)
240 promotion[4 * i + j] = input[j];
242 var la = bpmos[i].GetLable();
243 for (
int j = 0; j < la.Count(); j++)
245 label[2 * i + j] = la[j];
248 for (
int i = 0; i < pointCount; i++)
250 var p = pproms[i].GetInput();
251 for (
int j = 0; j < p.Count(); j++)
253 promotion[boxCount * 4 + 2 * i + j] = p[j];
255 var la = pproms[i].GetLable();
256 for (
int j = 0; j < la.Count(); j++)
258 label[boxCount * 2 + i + j] = la[j];
262 var point_coords_tensor =
new DenseTensor<float>(promotion,
new[] { 1, boxCount * 2 + pointCount, 2 });
264 var point_label_tensor =
new DenseTensor<float>(label,
new[] { 1, boxCount * 2 + pointCount });
266 float[] mask =
new float[256 * 256];
267 for (
int i = 0; i < mask.Count(); i++)
271 var mask_tensor =
new DenseTensor<float>(mask,
new[] { 1, 1, 256, 256 });
273 float[] hasMaskValues =
new float[1] { 0 };
274 var hasMaskValues_tensor =
new DenseTensor<float>(hasMaskValues,
new[] { 1 });
275 List<NamedOnnxValue> decode_inputs;
277 float[] orig_im_size_values = { (float)orgHei, (
float)orgWid };
278 var orig_im_size_values_tensor =
new DenseTensor<float>(orig_im_size_values,
new[] { 2 });
279 decode_inputs =
new List<NamedOnnxValue>
281 NamedOnnxValue.CreateFromTensor(
"image_embeddings", embedding_tensor),
282 NamedOnnxValue.CreateFromTensor(
"point_coords", point_coords_tensor),
283 NamedOnnxValue.CreateFromTensor(
"point_labels", point_label_tensor),
284 NamedOnnxValue.CreateFromTensor(
"mask_input", mask_tensor),
285 NamedOnnxValue.CreateFromTensor(
"has_mask_input", hasMaskValues_tensor),
286 NamedOnnxValue.CreateFromTensor(
"orig_im_size", orig_im_size_values_tensor)
290 var segmask = this.decoder.Run(decode_inputs).ToList();
291 md.mMask = segmask[0].AsTensor<
float>().ToArray().ToList();
292 md.mShape = segmask[0].AsTensor<
float>().Dimensions.ToArray();
293 md.mIoU = segmask[1].AsTensor<
float>().ToList();
294 BioLib.Recorder.AddLine(
"MaskData md = App.samTool.microsam.Decode(App.samTool.Promotions,(float[])ImageView.SelectedImage.Tag," + orgWid +
"," + orgHei +
");",
false);
307 public static float[]
ResizeTensor(
float[] tensor,
int sizeX,
int sizeY,
int newSizeX,
int newSizeY)
309 float[] resizedTensor =
new float[newSizeX * newSizeY];
312 float scaleX = (float)sizeX / newSizeX;
313 float scaleY = (float)sizeY / newSizeY;
315 for (
int y = 0; y < newSizeY; y++)
317 for (
int x = 0; x < newSizeX; x++)
320 float origX = x * scaleX;
321 float origY = y * scaleY;
324 int x0 = (int)Math.Floor(origX);
325 int y0 = (int)Math.Floor(origY);
326 int x1 = Math.Min(x0 + 1, sizeX - 1);
327 int y1 = Math.Min(y0 + 1, sizeY - 1);
329 float xFrac = origX - x0;
330 float yFrac = origY - y0;
333 float topLeft = tensor[y0 * sizeX + x0];
334 float topRight = tensor[y0 * sizeX + x1];
335 float bottomLeft = tensor[y1 * sizeX + x0];
336 float bottomRight = tensor[y1 * sizeX + x1];
339 float top = topLeft + xFrac * (topRight - topLeft);
340 float bottom = bottomLeft + xFrac * (bottomRight - bottomLeft);
341 float value = top + yFrac * (bottom - top);
344 resizedTensor[y * newSizeX + x] = value;
348 return resizedTensor;
static float[] ResizeTensor(float[] tensor, int sizeX, int sizeY, int newSizeX, int newSizeY)
Resizes a tensor of shape [1, sizeX, sizeY] using bilinear interpolation.