BioGTK  6.7.0
A .NET library & program for annotating, editing various microscopy imaging formats using Bioformats supported images. Including whole slide, pyramidal, and series.
Loading...
Searching...
No Matches
ROIManager.cs
1using AForge;
2using BioGTK;
3using CSScripting;
4using Gtk;
5using System;
6using System.Collections.Generic;
7using System.ComponentModel;
8using System.Data;
9using System.IO;
10using System.Linq;
11using System.Text;
12using System.Threading.Tasks;
13
14namespace Bio
15{
16 public partial class ROIManager : Window
17 {
18 #region Properties
19
21 private Builder _builder;
22
23#pragma warning disable 649
24 [Builder.Object]
25 private TreeView roiView;
26 [Builder.Object]
27 private SpinButton xBox;
28 [Builder.Object]
29 private SpinButton yBox;
30 [Builder.Object]
31 private SpinButton wBox;
32 [Builder.Object]
33 private SpinButton hBox;
34 [Builder.Object]
35 private SpinButton zBox;
36 [Builder.Object]
37 private SpinButton cBox;
38 [Builder.Object]
39 private SpinButton tBox;
40 [Builder.Object]
41 private SpinButton widthBox;
42 [Builder.Object]
43 private SpinButton rBox;
44 [Builder.Object]
45 private SpinButton gBox;
46 [Builder.Object]
47 private SpinButton bBox;
48 [Builder.Object]
49 private Label typeLabel;
50 [Builder.Object]
51 private Entry textBox;
52 [Builder.Object]
53 private Entry idBox;
54 [Builder.Object]
55 private SpinButton pointBox;
56 [Builder.Object]
57 private SpinButton pointXBox;
58 [Builder.Object]
59 private SpinButton pointYBox;
60 [Builder.Object]
61 private SpinButton selBox;
62 [Builder.Object]
63 private FontButton fontBut;
64 [Builder.Object]
65 private CheckButton boundsBox;
66 [Builder.Object]
67 private CheckButton showTextBox;
68 [Builder.Object]
69 private CheckButton showRBox;
70 [Builder.Object]
71 private CheckButton showGBox;
72 [Builder.Object]
73 private CheckButton showBBox;
74 [Builder.Object]
75 private Label imageNameLabel;
76 [Builder.Object]
77 private CheckButton showMasksBox;
78 [Builder.Object]
79 private Menu menu;
80 [Builder.Object]
81 private MenuItem menuDelete;
82 [Builder.Object]
83 private MenuItem menuCopy;
84 [Builder.Object]
85 private MenuItem menuPaste;
86#pragma warning restore 649
87
88 #endregion
89 private static Random rng = new Random(DateTime.Now.Millisecond);
90 #region Constructors / Destructors
91 public BioImage image;
92 private static Dictionary<string, ROI> rts = new Dictionary<string, ROI>();
93 public static Dictionary<string, ROI> rois
94 {
95 get
96 {
97 ROI[] selectedAnnotations = ImageView.SelectedImage?.Annotations?.ToArray() ?? Array.Empty<ROI>();
98 foreach (var item in selectedAnnotations)
99 {
100 if (item == null)
101 continue;
102 if(!rts.ContainsKey(item.id))
103 {
104 if (item.id == "" || item.id == null)
105 item.id = rng.Next(0,999999999).ToString();
106 rts.Add(item.id, item);
107 }
108 }
109 if (App.viewer != null && ImageView.SelectedImage != null)
110 {
111 ROI[] overlays = App.viewer.GetZarrLabelOverlaysForImage(ImageView.SelectedImage).ToArray();
112 foreach (var item in overlays)
113 {
114 if (item == null)
115 continue;
116 if (!rts.ContainsKey(item.id))
117 {
118 if (item.id == "" || item.id == null)
119 item.id = rng.Next(0, 999999999).ToString();
120 rts.Add(item.id, item);
121 }
122 }
123 }
124 return rts;
125 }
126 set
127 {
128 rts = value;
129 }
130 }
131 public static ROIManager Create()
132 {
133 Builder builder = new Builder(new FileStream(System.IO.Path.GetDirectoryName(Environment.ProcessPath) + "/" + "Glade/ROIManager.glade", FileMode.Open));
134 return new ROIManager(builder, builder.GetObject("roiManager").Handle);
135 }
136 /* The above code is initializing the ROIManager class. */
137 protected ROIManager(Builder builder, IntPtr handle) : base(handle)
138 {
139 _builder = builder;
140 builder.Autoconnect(this);
141 xBox.ValueChanged += xBox_ValueChanged;
142 yBox.ValueChanged += yBox_ValueChanged;
143 wBox.ValueChanged += wBox_ValueChanged;
144 hBox.ValueChanged += hBox_ValueChanged;
145 rBox.ValueChanged += rBox_ValueChanged;
146 gBox.ValueChanged += gBox_ValueChanged;
147 bBox.ValueChanged += bBox_ValueChanged;
148 zBox.ValueChanged += zBox_ValueChanged;
149 cBox.ValueChanged += cBox_ValueChanged;
150 tBox.ValueChanged += tBox_ValueChanged;
151 widthBox.ValueChanged += strokeWBox_ValueChanged;
152 pointXBox.ValueChanged += pointXBox_ValueChanged;
153 pointYBox.ValueChanged += pointYBox_ValueChanged;
154 pointBox.ValueChanged += pointBox_ValueChanged;
155 selBox.ValueChanged += selectBoxSize_ValueChanged;
156 widthBox.ValueChanged += strokeWBox_ValueChanged;
157 textBox.Changed += textBox_TextChanged;
158 idBox.Changed += idBox_TextChanged;
159 boundsBox.Clicked += showBoundsBox_ActiveChanged;
160 showTextBox.Clicked += showTextBox_ActiveChanged;
161 showRBox.Clicked += showRBox_ActiveChanged;
162 showGBox.Clicked += showGBox_ActiveChanged;
163 showBBox.Clicked += showBBox_ActiveChanged;
164 showMasksBox.Clicked += ShowMasksBox_Clicked;
165 this.DeleteEvent += ROIManager_DeleteEvent;
166 menuDelete.ButtonPressEvent += MenuDelete_ButtonPressEvent;
167 menuCopy.ButtonPressEvent += MenuCopy_ButtonPressEvent;
168 menuPaste.ButtonPressEvent += MenuPaste_ButtonPressEvent;
169
170 //roiView.Selection.Changed += roiView_SelectedIndexChanged;
171 roiView.RowActivated += RoiView_RowActivated;
172 this.FocusInEvent += ROIManager_FocusInEvent;
173 this.FocusActivated += ROIManager_Activated;
174 roiView.ButtonPressEvent += RoiView_ButtonPressEvent;
175
176 xBox.Adjustment.Upper = PointD.MaxX;
177 xBox.Adjustment.StepIncrement= 0.1;
178 xBox.Adjustment.PageIncrement= 1;
179 yBox.Adjustment.Upper = PointD.MaxY;
180 yBox.Adjustment.StepIncrement = 0.1;
181 yBox.Adjustment.PageIncrement = 1;
182 wBox.Adjustment.Upper = PointD.MaxX;
183 wBox.Adjustment.StepIncrement = 0.1;
184 wBox.Adjustment.PageIncrement = 1;
185 hBox.Adjustment.Upper = PointD.MaxY;
186 xBox.Adjustment.StepIncrement = 0.1;
187 xBox.Adjustment.PageIncrement = 1;
188 rBox.Adjustment.Upper = byte.MaxValue;
189 rBox.Adjustment.StepIncrement = 1;
190 rBox.Adjustment.PageIncrement = 1;
191 gBox.Adjustment.Upper = byte.MaxValue;
192 gBox.Adjustment.StepIncrement = 1;
193 gBox.Adjustment.PageIncrement = 1;
194 bBox.Adjustment.Upper = byte.MaxValue;
195 bBox.Adjustment.StepIncrement = 1;
196 bBox.Adjustment.PageIncrement = 1;
197 zBox.Adjustment.Upper = 10000;
198 zBox.Adjustment.StepIncrement = 1;
199 zBox.Adjustment.PageIncrement = 1;
200 cBox.Adjustment.Upper = 10000;
201 cBox.Adjustment.StepIncrement = 1;
202 cBox.Adjustment.PageIncrement = 1;
203 tBox.Adjustment.Upper = 10000;
204 tBox.Adjustment.StepIncrement = 1;
205 tBox.Adjustment.PageIncrement = 1;
206 widthBox.Adjustment.Upper = 100;
207 widthBox.Adjustment.StepIncrement = 1;
208 widthBox.Adjustment.PageIncrement = 1;
209 pointBox.Adjustment.Upper = 100000;
210 pointBox.Adjustment.StepIncrement = 1;
211 pointBox.Adjustment.PageIncrement = 1;
212 pointXBox.Adjustment.Upper = PointD.MaxX;
213 pointXBox.Adjustment.StepIncrement = 0.1;
214 pointXBox.Adjustment.PageIncrement = 1;
215 pointYBox.Adjustment.Upper = PointD.MaxY;
216 pointYBox.Adjustment.StepIncrement = 0.1;
217 pointYBox.Adjustment.PageIncrement = 1;
218 selBox.Value = ROI.selectBoxSize;
219 selBox.Adjustment.Upper = 100;
220 selBox.Adjustment.StepIncrement = 1;
221 roiView.ActivateOnSingleClick = true;
222 InitItems();
223 if (ImageView.SelectedImage != null)
225 App.ApplyStyles(this);
226 }
227
228 private void RoiView_ButtonPressEvent(object o, ButtonPressEventArgs args)
229 {
230 if (args.Event.Button == 3)
231 menu.Popup();
232 }
233
234 private List<ROI> copys = new List<ROI>();
236 public void CopySelection()
237 {
238 copys.Clear();
239 string s = "";
240 List<ROI> rois = new List<ROI>();
241 rois.AddRange(ImageView.SelectedImage.AnnotationsR);
242 rois.AddRange(ImageView.SelectedImage.AnnotationsG);
243 rois.AddRange(ImageView.SelectedImage.AnnotationsB);
244 foreach (ROI item in rois)
245 {
246 if (item.Selected)
247 {
248 copys.Add(item);
249 s += BioImage.ROIToString(item);
250 }
251 }
252 Clipboard clipboard = Clipboard.Get(Gdk.Selection.Clipboard);
253 clipboard.Text = s;
254 }
257 public void PasteSelection()
258 {
259 Clipboard clipboard = Clipboard.Get(Gdk.Selection.Clipboard);
260 string text = clipboard.WaitForText();
261 string[] sts = text.Split(BioImage.NewLine);
262 foreach (string line in sts)
263 {
264 if (line.Length > 8)
265 {
266 ROI an = BioImage.StringToROI(line);
267 //We set the coordinates of the ROI's we are pasting
268 an.coord = App.viewer.GetCoordinate();
269 ImageView.SelectedImage.Annotations.Add(an);
270 }
271 }
272 UpdateView();
273 }
274
275
276 private void MenuPaste_ButtonPressEvent(object o, ButtonPressEventArgs args)
277 {
279 }
280
281 private void MenuCopy_ButtonPressEvent(object o, ButtonPressEventArgs args)
282 {
284 }
285
286 private void MenuDelete_ButtonPressEvent(object o, ButtonPressEventArgs args)
287 {
288 if (anno != null && ImageView.SelectedImage != null)
289 {
290 // Remove the selected annotation
291 ImageView.SelectedImage.Annotations.Remove(anno);
293 }
294 }
295
296 private void ShowMasksBox_Clicked(object sender, EventArgs e)
297 {
298 App.viewer.ShowMasks = showMasksBox.Active;
299 UpdateView();
300 }
301
302 private void ROIManager_DeleteEvent(object o, DeleteEventArgs args)
303 {
304 args.RetVal = true;
305 Hide();
306 }
307
312
313 private void ROIManager_FocusInEvent(object o, FocusInEventArgs args)
314 {
316 }
317
318
319 #endregion
320
321 public ROI anno = new ROI();
322
331 private void RoiView_RowActivated(object o, RowActivatedArgs args)
332 {
333 TreeIter iter;
334 if (roiView.Model.GetIter(out iter, args.Path))
335 {
336 string type = (string)roiView.Model.GetValue(iter, 0);
337 ROI.Type t;
338 if (Enum.TryParse<ROI.Type>(type,out t))
339 {
340 string id = (string)roiView.Model.GetValue(iter, 1);
341 string text = (string)roiView.Model.GetValue(iter, 2);
342 string bounds = (string)roiView.Model.GetValue(iter, 3);
343 if (rois.ContainsKey(id))
344 {
345 anno = rois[id];
346 if (App.viewer != null)
347 App.viewer.SetCoordinate(anno.coord.Z, anno.coord.C, anno.coord.T);
348 xBox.Value = anno.X;
349 yBox.Value = anno.Y;
350 wBox.Value = anno.W;
351 hBox.Value = anno.H;
352 zBox.Value = anno.coord.Z;
353 cBox.Value = anno.coord.C;
354 tBox.Value = anno.coord.T;
355 rBox.Value = anno.strokeColor.R;
356 gBox.Value = anno.strokeColor.G;
357 bBox.Value = anno.strokeColor.B;
358 widthBox.Value = anno.strokeWidth;
359 idBox.Text = anno.id;
360 textBox.Text = anno.Text;
361 typeLabel.Text = anno.type.ToString();
362 imageNameLabel.Text = ImageView.SelectedImage.Filename;
364 if (ImageView.SelectedImage.isPyramidal)
365 {
366 App.viewer.PyramidalOrigin = new PointD((int)(anno.X), (int)(anno.Y));
367 App.viewer.UpdateView(true);
368 }
369 }
370 else return;
371 }
372 else return;
373 }
374 else
375 return;
376 }
379 public void InitItems()
380 {
381 Gtk.TreeViewColumn typeCol = new Gtk.TreeViewColumn();
382 typeCol.Title = "Type";
383 Gtk.CellRendererText typeCell = new Gtk.CellRendererText();
384 typeCol.PackStart(typeCell, true);
385
386 Gtk.TreeViewColumn idCol = new Gtk.TreeViewColumn();
387 idCol.Title = "ID";
388 Gtk.CellRendererText idCell = new Gtk.CellRendererText();
389 idCol.PackStart(idCell, true);
390
391 Gtk.TreeViewColumn textCol = new Gtk.TreeViewColumn();
392 textCol.Title = "Text";
393 Gtk.CellRendererText textCell = new Gtk.CellRendererText();
394 textCol.PackStart(textCell, true);
395
396 Gtk.TreeViewColumn rectCol = new Gtk.TreeViewColumn();
397 rectCol.Title = "Bounds";
398 Gtk.CellRendererText rectCell = new Gtk.CellRendererText();
399 rectCol.PackStart(rectCell, true);
400
401
402 roiView.AppendColumn(typeCol);
403 roiView.AppendColumn(idCol);
404 roiView.AppendColumn(textCol);
405 roiView.AppendColumn(rectCol);
406
407 typeCol.AddAttribute(typeCell, "text", 0);
408 idCol.AddAttribute(idCell, "text", 1);
409 textCol.AddAttribute(textCell, "text", 2);
410 rectCol.AddAttribute(rectCell, "text", 3);
411
412 Gtk.TreeStore store = new Gtk.TreeStore(typeof(string), typeof(string), typeof(string), typeof(string));
413
414 foreach (BioImage b in Images.images)
415 {
416 Gtk.TreeIter iter = store.AppendValues(System.IO.Path.GetFileName(b.Filename));
417 foreach (ROI r in b.Annotations)
418 {
419 store.AppendValues(iter, r.type.ToString(), r.id, r.Text, r.BoundingBox.ToString());
420 }
421 if (App.viewer != null)
422 {
423 foreach (ROI r in App.viewer.GetZarrLabelOverlaysForImage(b))
424 {
425 if (r == null || b.Annotations.Contains(r))
426 continue;
427 store.AppendValues(iter, r.type.ToString(), r.id, r.Text, r.BoundingBox.ToString());
428 }
429 }
430 }
431 roiView.Model = store;
432
433 }
438 {
439 rois.Clear();
440 Gtk.TreeStore store = new Gtk.TreeStore(typeof(string), typeof(string), typeof(string), typeof(string));
441 List<BioImage> sourceImages = new List<BioImage>(Images.images);
442 if (ImageView.SelectedImage != null && !sourceImages.Contains(ImageView.SelectedImage))
443 sourceImages.Insert(0, ImageView.SelectedImage);
444
445 foreach (BioImage b in sourceImages)
446 {
447 Gtk.TreeIter iter = store.AppendValues(System.IO.Path.GetFileName(b.Filename));
448 ROI[] annotations = b.Annotations?.ToArray() ?? Array.Empty<ROI>();
449 HashSet<ROI> annotationSet = new HashSet<ROI>(annotations.Where(r => r != null));
450 foreach (ROI r in annotations)
451 {
452 if (r == null)
453 continue;
454 if (r.id == "")
455 {
456 store.AppendValues(iter, r.type.ToString(), rng.Next(), r.Text, r.BoundingBox.ToString());
457 }
458 else
459 {
460 if(!rois.ContainsKey(r.id))
461 rois.Add(r.id, r);
462 store.AppendValues(iter, r.type.ToString(), r.id, r.Text, r.BoundingBox.ToString());
463 }
464 }
465 if (App.viewer != null)
466 {
467 ROI[] overlays = App.viewer.GetZarrLabelOverlaysForImage(b).ToArray();
468 foreach (ROI r in overlays)
469 {
470 if (r == null || annotationSet.Contains(r))
471 continue;
472 if (r.id == "")
473 {
474 store.AppendValues(iter, r.type.ToString(), rng.Next(), r.Text, r.BoundingBox.ToString());
475 }
476 else
477 {
478 if (!rois.ContainsKey(r.id))
479 rois.Add(r.id, r);
480 store.AppendValues(iter, r.type.ToString(), r.id, r.Text, r.BoundingBox.ToString());
481 }
482 }
483 }
484 }
485 roiView.Model = store;
486 }
487
489 private void UpdateView()
490 {
491 App.viewer.UpdateView();
492 }
499 public void updateROI(int index, ROI an)
500 {
501 if (ImageView.SelectedImage == null)
502 return;
503 ImageView.SelectedImage.Annotations[index] = an;
504 UpdateView();
505 }
512 private void xBox_ValueChanged(object sender, EventArgs e)
513 {
514 if (anno == null)
515 return;
516 anno.BoundingBox = new RectangleD(xBox.Value, anno.Y, anno.W, anno.H);
517 UpdateView();
518 }
526 private void yBox_ValueChanged(object sender, EventArgs e)
527 {
528 if (anno == null)
529 return;
530 anno.BoundingBox = new RectangleD(anno.X, yBox.Value, anno.W, anno.H);
531 UpdateView();
532 }
539 private void wBox_ValueChanged(object sender, EventArgs e)
540 {
541 if (anno == null)
542 return;
543 if(anno.type == ROI.Type.Rectangle || anno.type == ROI.Type.Ellipse)
544 anno.BoundingBox = new RectangleD(anno.X, anno.Y, wBox.Value, anno.H);
545 UpdateView();
546 }
553 private void hBox_ValueChanged(object sender, EventArgs e)
554 {
555 if (anno == null)
556 return;
557 if (anno.type == ROI.Type.Rectangle || anno.type == ROI.Type.Ellipse)
558 anno.BoundingBox = new RectangleD(anno.X, anno.Y, anno.W, hBox.Value);
559 UpdateView();
560 }
567 private void sBox_ValueChanged(object sender, EventArgs e)
568 {
569 if (anno == null)
570 return;
571 //anno.serie = (int)sBox.Value;
572 UpdateView();
573 }
581 private void zBox_ValueChanged(object sender, EventArgs e)
582 {
583 if (anno == null)
584 return;
585 anno.coord.Z = (int)zBox.Value;
586 UpdateView();
587 }
595 private void cBox_ValueChanged(object sender, EventArgs e)
596 {
597 if (anno == null)
598 return;
599 anno.coord.C = (int)cBox.Value;
600 UpdateView();
601 }
609 private void tBox_ValueChanged(object sender, EventArgs e)
610 {
611 if (anno == null)
612 return;
613 anno.coord.T = (int)cBox.Value;
614 UpdateView();
615 }
623 private void rBox_ValueChanged(object sender, EventArgs e)
624 {
625 if (anno == null)
626 return;
627 anno.strokeColor = Color.FromArgb((byte)rBox.Value, anno.strokeColor.G, anno.strokeColor.B);
628 UpdateView();
629 }
637 private void gBox_ValueChanged(object sender, EventArgs e)
638 {
639 if (anno == null)
640 return;
641 anno.strokeColor = Color.FromArgb(anno.strokeColor.R, (byte)gBox.Value, anno.strokeColor.B);
642 UpdateView();
643 }
651 private void bBox_ValueChanged(object sender, EventArgs e)
652 {
653 if (anno == null)
654 return;
655 anno.strokeColor = Color.FromArgb(anno.strokeColor.R, anno.strokeColor.G, (byte)bBox.Value);
656 UpdateView();
657 }
665 private void textBox_TextChanged(object sender, EventArgs e)
666 {
667 if (anno == null)
668 return;
669 anno.Text = textBox.Text;
670 UpdateView();
671 }
679 private void idBox_TextChanged(object sender, EventArgs e)
680 {
681 if (anno == null)
682 return;
683 anno.id = idBox.Text;
684 UpdateView();
685 }
693 private void ROIManager_Activated(object sender, EventArgs e)
694 {
695 if (ImageView.SelectedImage == null)
696 return;
697 string n = System.IO.Path.GetFileName(ImageView.SelectedImage.ID);
698 if (imageNameLabel.Text != n)
699 imageNameLabel.Text = n;
701 }
702
707 private void addButton_Click(object sender, EventArgs e)
708 {
709 ImageView.SelectedImage.Annotations.Add(anno);
710 UpdateView();
711 }
712 public static bool showBounds = true;
713 public static bool showText = false;
714 public static bool showR = true;
715 public static bool showG = true;
716 public static bool showB = true;
721 private void showBoundsBox_ActiveChanged(object sender, EventArgs e)
722 {
723 showBounds = boundsBox.Active;
724 UpdateView();
725 }
730 private void showTextBox_ActiveChanged(object sender, EventArgs e)
731 {
732 showText = showTextBox.Active;
733 UpdateView();
734 }
743 private void pointXBox_ValueChanged(object sender, EventArgs e)
744 {
745 if (anno == null)
746 return;
747 if (anno.type == ROI.Type.Rectangle || anno.type == ROI.Type.Ellipse)
748 return;
749 anno.UpdatePoint(new PointD((double)pointXBox.Value, (double)pointYBox.Value),(int)pointBox.Value);
750 UpdateView();
751 }
759 private void pointYBox_ValueChanged(object sender, EventArgs e)
760 {
761 if (anno == null)
762 return;
763 if (anno.type == ROI.Type.Rectangle || anno.type == ROI.Type.Ellipse)
764 return;
765 anno.UpdatePoint(new PointD((double)pointXBox.Value, (double)pointYBox.Value), (int)pointBox.Value);
766 UpdateView();
767 }
768 public bool autoUpdate = true;
772 public void UpdatePointBox()
773 {
774 if (anno == null)
775 return;
776 PointD d = anno.GetPoint((int)pointBox.Value);
777 pointXBox.Value = (int)d.X;
778 pointYBox.Value = (int)d.Y;
779 }
784 private void pointBox_ValueChanged(object sender, EventArgs e)
785 {
787 }
795 private void strokeWBox_ValueChanged(object sender, EventArgs e)
796 {
797 if (anno == null)
798 return;
799 anno.strokeWidth = (int)widthBox.Value;
800 UpdateView();
801 }
807 private void selectBoxSize_ValueChanged(object sender, EventArgs e)
808 {
809 ROI.selectBoxSize = (int)widthBox.Value;
810 UpdateView();
811 }
818 private void showRBox_ActiveChanged(object sender, EventArgs e)
819 {
820 if (App.viewer == null)
821 return;
822 App.viewer.showRROIs = showRBox.Active;
823 UpdateView();
824 }
831 private void showGBox_ActiveChanged(object sender, EventArgs e)
832 {
833 if (App.viewer == null)
834 return;
835 App.viewer.showGROIs = showGBox.Active;
836 UpdateView();
837 }
845 private void showBBox_ActiveChanged(object sender, EventArgs e)
846 {
847 if (App.viewer == null)
848 return;
849 App.viewer.showBROIs = showBBox.Active;
850 UpdateView();
851 }
852
857 private void saveToolStripMenuItem_Click(object sender, EventArgs e)
858 {
859
860 }
861
862 }
863}
void PasteSelection()
void UpdateAnnotationList()
void CopySelection()
It takes the selected ROIs and copies them to the clipboard.
void UpdatePointBox()
void updateROI(int index, ROI an)
Definition ML.cs:17