1 package com.github.celldynamics.quimp.plugin.randomwalk;
2
3 import java.awt.BorderLayout;
4 import java.awt.Color;
5 import java.awt.Dimension;
6 import java.awt.FlowLayout;
7 import java.awt.Font;
8 import java.awt.GridBagConstraints;
9 import java.awt.GridBagLayout;
10 import java.awt.GridLayout;
11 import java.awt.Insets;
12 import java.awt.event.ActionEvent;
13 import java.awt.event.ActionListener;
14 import java.awt.event.ItemEvent;
15 import java.awt.event.ItemListener;
16 import java.awt.event.WindowFocusListener;
17 import java.util.Collections;
18
19 import javax.swing.BorderFactory;
20 import javax.swing.BoxLayout;
21 import javax.swing.JButton;
22 import javax.swing.JCheckBox;
23 import javax.swing.JComboBox;
24 import javax.swing.JComponent;
25 import javax.swing.JFrame;
26 import javax.swing.JLabel;
27 import javax.swing.JPanel;
28 import javax.swing.JSpinner;
29 import javax.swing.JToggleButton;
30 import javax.swing.SpinnerNumberModel;
31 import javax.swing.ToolTipManager;
32
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 import com.github.celldynamics.quimp.plugin.randomwalk.RandomWalkModel.SeedSource;
37 import com.github.celldynamics.quimp.utils.QuimpToolsCollection;
38 import com.github.celldynamics.quimp.utils.UiTools;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 public class RandomWalkView implements ActionListener, ItemListener {
130
131
132
133
134 static final Logger LOGGER = LoggerFactory.getLogger(RandomWalkView.class.getName());
135
136
137
138
139 private JFrame wnd;
140
141
142
143
144
145
146 public JFrame getWnd() {
147 return wnd;
148 }
149
150
151
152
153 private JPanel panel;
154
155
156 private JPanel panelMain;
157
158
159
160
161 private JComboBox<String> cbOrginalImage;
162
163
164
165
166
167
168 public String getCbOrginalImage() {
169 return (String) cbOrginalImage.getSelectedItem();
170 }
171
172
173
174
175
176
177
178
179 public void setCbOrginalImage(String[] item, String sel) {
180 cbOrginalImage.removeAllItems();
181 setJComboBox(cbOrginalImage, item, sel);
182 }
183
184
185 private JComboBox<String> cbSeedSource;
186
187
188
189
190
191
192
193
194 public void setSeedSource(String[] item, String sel) {
195 setJComboBox(cbSeedSource, item, sel);
196 }
197
198
199
200
201
202
203 public int getSeedSource() {
204 return getJComboBox(cbSeedSource);
205 }
206
207
208 private JLabel lbQconfFile;
209
210
211
212
213
214
215 public void setLqconfFile(String lab) {
216 lbQconfFile.setFont(new Font(lbQconfFile.getFont().getName(), Font.ITALIC,
217 lbQconfFile.getFont().getSize()));
218 lbQconfFile.setText(lab);
219 }
220
221
222 private JComboBox<String> cbRgbSeedImage;
223
224
225
226
227
228
229 public String getCbRgbSeedImage() {
230 return (String) cbRgbSeedImage.getSelectedItem();
231 }
232
233
234
235
236
237
238
239 public void setCbRgbSeedImage(String[] item, String sel) {
240 cbRgbSeedImage.removeAllItems();
241 setJComboBox(cbRgbSeedImage, item, sel);
242 }
243
244
245 private JComboBox<String> cbMaskSeedImage;
246
247
248
249
250
251
252 public String getCbMaskSeedImage() {
253 return (String) cbMaskSeedImage.getSelectedItem();
254 }
255
256
257
258
259
260
261
262 public void setCbMaskSeedImage(String[] item, String sel) {
263 cbMaskSeedImage.removeAllItems();
264 setJComboBox(cbMaskSeedImage, item, sel);
265 }
266
267
268 private JButton bnQconfSeedImage;
269
270
271 private JButton bnQconfShowSeedImage;
272
273
274 private JButton bnClone;
275
276
277 private JButton bnSeedRoi;
278
279
280 private JToggleButton bnFore;
281
282
283
284
285
286
287 public JToggleButton getBnFore() {
288 return bnFore;
289 }
290
291
292 private JToggleButton bnBack;
293
294
295
296
297
298
299 public JToggleButton getBnBack() {
300 return bnBack;
301 }
302
303
304 private JComboBox<String> cbCreatedSeedImage;
305
306
307
308
309
310
311 public String getCbCreatedSeedImage() {
312 return (String) cbCreatedSeedImage.getSelectedItem();
313 }
314
315
316
317
318
319
320
321 public void setCbCreatedSeedImage(String[] item, String sel) {
322 cbCreatedSeedImage.removeAllItems();
323 setJComboBox(cbCreatedSeedImage, item, sel);
324 }
325
326
327 private JLabel lbRoiSeedsInfo;
328
329
330
331
332
333
334 public void setLroiSeedsInfo(String lab) {
335 lbRoiSeedsInfo.setFont(new Font(lbRoiSeedsInfo.getFont().getName(), Font.ITALIC,
336 lbRoiSeedsInfo.getFont().getSize()));
337 lbRoiSeedsInfo.setText(lab);
338 }
339
340
341
342 private JSpinner srAlpha;
343
344
345
346
347
348
349 public double getSrAlpha() {
350 return ((Number) srAlpha.getValue()).doubleValue();
351 }
352
353
354
355
356
357
358 public void setSrAlpha(double srAlpha) {
359 this.srAlpha.setValue(srAlpha);
360 }
361
362
363 private JSpinner srBeta;
364
365
366
367
368
369
370 public double getSrBeta() {
371 return ((Number) srBeta.getValue()).doubleValue();
372 }
373
374
375
376
377
378
379 public void setSrBeta(double srBeta) {
380 this.srBeta.setValue(srBeta);
381 }
382
383
384 private JSpinner srGamma0;
385
386
387
388
389
390
391 public double getSrGamma0() {
392 return ((Number) srGamma0.getValue()).doubleValue();
393 }
394
395
396
397
398
399
400 public void setSrGamma0(double srGamma0) {
401 this.srGamma0.setValue(srGamma0);
402 }
403
404
405 private JSpinner srGamma1;
406
407
408
409
410
411
412 public double getSrGamma1() {
413 return ((Number) srGamma1.getValue()).doubleValue();
414 }
415
416
417
418
419
420
421 public void setSrGamma1(double srGamma1) {
422 this.srGamma1.setValue(srGamma1);
423 }
424
425
426 private JSpinner srIter;
427
428
429
430
431
432
433 public int getSrIter() {
434 return ((Number) srIter.getValue()).intValue();
435 }
436
437
438
439
440
441
442 public void setSrIter(int srIter) {
443 this.srIter.setValue((double) srIter);
444 }
445
446
447 private JSpinner srRelerr;
448
449
450
451
452
453
454 public double getSrRelerr() {
455 return ((Number) srRelerr.getValue()).doubleValue();
456 }
457
458
459
460
461
462
463 public void setSrRelerr(double srRelerr) {
464 this.srRelerr.setValue(srRelerr);
465 }
466
467
468 private JComboBox<String> cbShrinkMethod;
469
470
471
472
473
474
475
476
477 public void setShrinkMethod(String[] item, String sel) {
478 setJComboBox(cbShrinkMethod, item, sel);
479 }
480
481
482
483
484
485
486 public int getShrinkMethod() {
487 return getJComboBox(cbShrinkMethod);
488 }
489
490
491 private JSpinner srShrinkPower;
492
493
494
495
496
497
498 public double getSrShrinkPower() {
499 return ((Number) srShrinkPower.getValue()).doubleValue();
500 }
501
502
503
504
505
506
507 public void setSrShrinkPower(double srShrinkPower) {
508 this.srShrinkPower.setValue(srShrinkPower);
509 }
510
511
512 private JSpinner srExpandPower;
513
514
515
516
517
518
519 public double getSrExpandPower() {
520 return ((Number) srExpandPower.getValue()).doubleValue();
521 }
522
523
524
525
526
527
528 public void setSrExpandPower(double srExpandPower) {
529 this.srExpandPower.setValue(srExpandPower);
530 }
531
532
533 private JSpinner srScaleSigma;
534
535
536
537
538
539
540 public double getSrScaleSigma() {
541 return ((Number) srScaleSigma.getValue()).doubleValue();
542 }
543
544
545
546
547
548
549 public void setSrScaleSigma(double srScaleSigma) {
550 this.srScaleSigma.setValue(srScaleSigma);
551 }
552
553
554 private JSpinner srScaleMagn;
555
556
557
558
559
560
561 public double getSrScaleMagn() {
562 return ((Number) srScaleMagn.getValue()).doubleValue();
563 }
564
565
566
567
568
569
570 public void setSrScaleMagn(double srScaleMagn) {
571 this.srScaleMagn.setValue(srScaleMagn);
572 }
573
574
575 private JSpinner srScaleEqNormalsDist;
576
577
578
579
580
581
582 public double getSrScaleEqNormalsDist() {
583 return ((Number) srScaleEqNormalsDist.getValue()).doubleValue();
584 }
585
586
587
588
589
590
591 public void setSrScaleEqNormalsDist(double srScaleEqNormalsDist) {
592 this.srScaleEqNormalsDist.setValue(srScaleEqNormalsDist);
593 }
594
595
596 private JSpinner srScaleCurvDistDist;
597
598
599
600
601
602
603 public double getSrScaleCurvDistDist() {
604 return ((Number) srScaleCurvDistDist.getValue()).doubleValue();
605 }
606
607
608
609
610
611
612 public void setSrScaleCurvDistDist(double srScaleCurvDistDist) {
613 this.srScaleCurvDistDist.setValue(srScaleCurvDistDist);
614 }
615
616
617 private JComboBox<String> cbFilteringMethod;
618
619
620
621
622
623
624
625
626 public void setFilteringMethod(String[] item, String sel) {
627 setJComboBox(cbFilteringMethod, item, sel);
628 }
629
630
631
632
633
634
635 public int getFilteringMethod() {
636 return getJComboBox(cbFilteringMethod);
637 }
638
639
640 private JCheckBox chTrueBackground;
641
642
643
644
645
646
647 public boolean getChTrueBackground() {
648 return chTrueBackground.isSelected();
649 }
650
651
652
653
654
655
656 public void setChTrueBackground(boolean chTrueBackground) {
657 this.chTrueBackground.setSelected(chTrueBackground);
658 }
659
660
661 private JCheckBox chInterFrameFilter;
662
663
664
665
666
667
668 public boolean getChInterFrameFilter() {
669 return chInterFrameFilter.isSelected();
670 }
671
672
673
674
675
676
677 public void setChInterFrameFilter(boolean chInterFrameFilter) {
678 this.chInterFrameFilter.setSelected(chInterFrameFilter);
679 }
680
681
682 private JCheckBox chLocalMean;
683
684
685
686
687
688
689 public boolean getChLocalMean() {
690 return chLocalMean.isSelected();
691 }
692
693
694
695
696
697
698 public void setChLocalMean(boolean chLocalMean) {
699 this.chLocalMean.setSelected(chLocalMean);
700 }
701
702
703 private JSpinner srLocalMeanWindow;
704
705
706
707
708
709
710 public int getSrLocalMeanWindow() {
711 return ((Number) srLocalMeanWindow.getValue()).intValue();
712 }
713
714
715
716
717
718
719 public void setSrLocalMeanWindow(int srWindow) {
720 this.srLocalMeanWindow.setValue((double) srWindow);
721 }
722
723
724 private JCheckBox chHatFilter;
725
726
727
728
729
730
731 public boolean getChHatFilter() {
732 return chHatFilter.isSelected();
733 }
734
735
736
737
738
739
740 public void setChHatFilter(boolean chHatFilter) {
741 this.chHatFilter.setSelected(chHatFilter);
742 }
743
744
745 private JSpinner srAlev;
746
747
748
749
750
751
752 public double getSrAlev() {
753 return ((Number) srAlev.getValue()).doubleValue();
754 }
755
756
757
758
759
760
761 public void setSrAlev(double srAlev) {
762 this.srAlev.setValue(srAlev);
763 }
764
765
766 private JSpinner srNum;
767
768
769
770
771
772
773 public int getSrNum() {
774 return ((Number) srNum.getValue()).intValue();
775 }
776
777
778
779
780
781
782 public void setSrNum(int srNum) {
783 this.srNum.setValue((double) srNum);
784 }
785
786
787 private JSpinner srWindow;
788
789
790
791
792
793
794 public int getSrWindow() {
795 return ((Number) srWindow.getValue()).intValue();
796 }
797
798
799
800
801
802
803 public void setSrWindow(int srWindow) {
804 this.srWindow.setValue((double) srWindow);
805 }
806
807
808 private JComboBox<String> cbFilteringPostMethod;
809
810
811
812
813
814
815
816
817 public void setFilteringPostMethod(String[] item, String sel) {
818 setJComboBox(cbFilteringPostMethod, item, sel);
819 }
820
821
822
823
824
825
826 public int getFilteringPostMethod() {
827 return getJComboBox(cbFilteringPostMethod);
828 }
829
830
831 private JCheckBox chMaskCut;
832
833
834
835
836
837
838 public boolean getChMaskCut() {
839 return chMaskCut.isSelected();
840 }
841
842
843
844
845
846
847 public void setChMaskCut(boolean chMaskCut) {
848 this.chMaskCut.setSelected(chMaskCut);
849 }
850
851
852 private JCheckBox chShowSeed;
853
854
855
856
857
858
859 public boolean getChShowSeed() {
860 return chShowSeed.isSelected();
861 }
862
863
864
865
866
867
868 public void setChShowSeed(boolean chShowSeed) {
869 this.chShowSeed.setSelected(chShowSeed);
870 }
871
872
873 private JCheckBox chShowPreview;
874
875
876
877
878
879
880 public boolean getChShowPreview() {
881 return chShowPreview.isSelected();
882 }
883
884
885
886
887
888
889 public void setChShowPreview(boolean chShowPreview) {
890 this.chShowPreview.setSelected(chShowPreview);
891 }
892
893
894 private JCheckBox chShowProbMaps;
895
896
897
898
899
900
901 public boolean getChShowProbMaps() {
902 return chShowProbMaps.isSelected();
903 }
904
905
906
907
908
909
910 public void setChShowProbMaps(boolean chShowProbMaps) {
911 this.chShowProbMaps.setSelected(chShowProbMaps);
912 }
913
914
915 private JButton bnRun;
916
917
918 private JButton bnCancel;
919
920
921 private JButton bnHelp;
922
923
924 private JButton bnRunActive;
925
926
927
928
929 public RandomWalkView() {
930
931
932
933
934
935
936 ToolTipManager.sharedInstance().setDismissDelay(UiTools.TOOLTIPDELAY);
937 wnd = new JFrame("Random Walker Segmentation");
938 wnd.setResizable(false);
939
940 JPanel imagePanel = new JPanel();
941 imagePanel.setBorder(BorderFactory
942 .createTitledBorder(BorderFactory.createLineBorder(Color.RED, 1), "Image selection"));
943 imagePanel.setLayout(new GridLayout(1, 1, 2, 2));
944 cbOrginalImage = new JComboBox<String>();
945 imagePanel.add(getControlwithoutLabel(cbOrginalImage, "Select image to be processed"));
946
947 JPanel seedSelPanel = new JPanel();
948 seedSelPanel.setBorder(BorderFactory.createTitledBorder(
949 BorderFactory.createLineBorder(Color.ORANGE, 1), "Get seeds from:"));
950 seedSelPanel.setLayout(new GridLayout(2, 1, 2, 2));
951 cbSeedSource = new JComboBox<String>();
952 cbSeedSource.setPreferredSize(new Dimension(250, cbOrginalImage.getPreferredSize().height));
953 cbSeedSource.addActionListener(this);
954 UiTools.setToolTip(cbSeedSource, "Select seed source.");
955
956
957
958
959
960
961
962
963 seedSelPanel.add(cbSeedSource);
964
965 cbCreatedSeedImage = new JComboBox<String>();
966 cbRgbSeedImage = new JComboBox<String>();
967 cbMaskSeedImage = new JComboBox<String>();
968 bnQconfSeedImage = new JButton("Load");
969 bnQconfShowSeedImage = new JButton("Show");
970 UiTools.setToolTip(bnQconfShowSeedImage, "Show mask generated from loaded QCONF file.");
971 UiTools.setToolTip(bnQconfSeedImage, "Load mask from QCONF file.");
972 bnClone = new JButton("Clone");
973 UiTools.setToolTip(bnClone, "Clone selected original image.");
974 bnSeedRoi = new JButton("Seed");
975 UiTools.setToolTip(bnSeedRoi, "Open ROI seed tool.");
976 bnFore = new JToggleButton("FG");
977 UiTools.setToolTip(bnFore,
978 "Select Foreground pen. Not used and will be removed in next version.");
979 bnFore.addActionListener(this);
980 bnFore.setBackground(Color.ORANGE);
981 bnBack = new JToggleButton("BG");
982 UiTools.setToolTip(bnBack,
983 "Select Background pen. Not used and will be removed in next version.");
984 bnBack.addActionListener(this);
985 bnBack.setBackground(Color.GREEN);
986 lbQconfFile = new JLabel("");
987 lbRoiSeedsInfo = new JLabel("");
988
989 JPanel optionsPanel = new JPanel();
990 optionsPanel.setBorder(BorderFactory.createTitledBorder("Segmentation options"));
991 optionsPanel.setLayout(new GridLayout(8, 1, 2, 2));
992 srAlpha = getDoubleSpinner(400, 0, 1e5, 1, 0);
993 optionsPanel.add(getControlwithLabel(srAlpha, "Alpha",
994 "alpha penalises pixels whose intensities are far away from the mean seed intensity"));
995 srBeta = getDoubleSpinner(50, 0, 1e5, 1, 0);
996 optionsPanel.add(getControlwithLabel(srBeta, "Beta",
997 "beta penalises pixels located at an edge, i.e.where there is a large gradient in"
998 + " intensity. Diffusion will be reduced</html>"));
999 srGamma0 = getDoubleSpinner(100, 0, 1e5, 1, 0);
1000 optionsPanel.add(getControlwithLabel(srGamma0, "Gamma 0",
1001 "gamma is the strength of competition between foreground and background."
1002 + " gamma 0 is for preliminary segmentation whereas gamma 1 for fine"
1003 + " segmentation. Temporally disabled"));
1004 srGamma0.setEnabled(false);
1005 srGamma1 = getDoubleSpinner(300, 0, 1e5, 1, 0);
1006 optionsPanel.add(getControlwithLabel(srGamma1, "Gamma 1",
1007 "Set to 0 to skip second sweep. Any other value is currently ignored."));
1008 srIter = getDoubleSpinner(300, 1, 10000, 1, 0);
1009 optionsPanel.add(getControlwithLabel(srIter, "Iterations",
1010 "Maximum number of iterations." + "Second sweep uses half of this value"));
1011 srRelerr = getDoubleSpinner(8.1e-3, 0, 10, 1e-5, 6);
1012 optionsPanel.add(getControlwithLabel(srRelerr, "Rel error", "Relative error."));
1013
1014 JPanel processPanel = new JPanel();
1015 processPanel.setBorder(BorderFactory.createTitledBorder("Inter-process"));
1016 processPanel.setLayout(new GridBagLayout());
1017 GridBagConstraints constrProc = new GridBagConstraints();
1018 constrProc.gridx = 0;
1019 constrProc.gridy = 0;
1020 constrProc.fill = GridBagConstraints.HORIZONTAL;
1021 constrProc.weightx = 1;
1022 constrProc.insets = new Insets(1, 2, 1, 2);
1023 cbShrinkMethod = new JComboBox<String>();
1024 processPanel.add(getControlwithLabel(cbShrinkMethod, "Shrink method",
1025 "Shrinking/expanding if nth frame result is used as n+1 frame seed or"
1026 + " seed is binary mask bigger than object (e.g. Active Contour segmentation)"
1027 + " Ignored if seed is RGB image."),
1028 constrProc);
1029 cbShrinkMethod.addItemListener(this);
1030 srShrinkPower = getDoubleSpinner(10, 0, 10000, 1, 0);
1031 constrProc.gridx = 0;
1032 constrProc.gridy = 1;
1033 processPanel.add(getControlwithLabel(srShrinkPower, "Shrink power", ""), constrProc);
1034 srExpandPower = getDoubleSpinner(15, 0, 10000, 1, 0);
1035 constrProc.gridx = 0;
1036 constrProc.gridy = 2;
1037 processPanel.add(getControlwithLabel(srExpandPower, "Expand power", ""), constrProc);
1038
1039 JPanel scalePanel = new JPanel();
1040 GridLayout gr = new GridLayout(2, 2);
1041 gr.setHgap(2);
1042 scalePanel.setLayout(gr);
1043 srScaleSigma = getDoubleSpinner(0.3, 1e-2, 1, 1e-2, 2);
1044 scalePanel.add(getControlwithLabel(srScaleSigma, "Sigma",
1045 "Set up expotential relation between negative curvature and node translocation"));
1046 srScaleMagn = getDoubleSpinner(1, 1, 10, 1, 0);
1047 scalePanel.add(getControlwithLabel(srScaleMagn, "Magn",
1048 "Maximum multiplier of shrink power. Set to 1.0 to disable"));
1049 srScaleCurvDistDist = getDoubleSpinner(1, 1, 100, 1, 1);
1050 scalePanel.add(getControlwithLabel(srScaleCurvDistDist, "Curv dist",
1051 "Approximated number of nodes used for averaging curvature. "
1052 + "At least 3 nodes are always used"));
1053 srScaleEqNormalsDist = getDoubleSpinner(0, 0, 100, 1, 1);
1054 scalePanel.add(getControlwithLabel(srScaleEqNormalsDist, "Norm dist",
1055 "Approximated number of nodes used for normals alignment "
1056 + "Set to 0 to disable otherwise at least 3 nodes are used"));
1057 constrProc.gridx = 0;
1058 constrProc.gridy = 3;
1059
1060 processPanel.add(scalePanel, constrProc);
1061
1062 cbFilteringMethod = new JComboBox<String>();
1063 constrProc.gridx = 0;
1064 constrProc.gridy = 4;
1065 processPanel.add(
1066 getControlwithLabel(cbFilteringMethod, "Inter-sweep filter",
1067 "Filtering applied for result between sweeps. Ignored if gamma[1]==0"),
1068 constrProc);
1069
1070
1071 JPanel interFilterPanel = new JPanel();
1072 interFilterPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
1073 chTrueBackground = new JCheckBox("Estimate Background");
1074 chInterFrameFilter = new JCheckBox("Inter-frame filter");
1075 interFilterPanel.add(getControlwithTooltip(chInterFrameFilter,
1076 "Apply additional filtering"
1077 + " before shinking. It helps in case of touching objects but it"
1078 + " can also remove small protrusions for more complicated shapes."));
1079 interFilterPanel.add(getControlwithTooltip(chTrueBackground,
1080 "Try to estimate background level. Disable is background is homogenous"));
1081 constrProc.gridx = 0;
1082 constrProc.gridy = 5;
1083 processPanel.add(interFilterPanel, constrProc);
1084
1085
1086 JPanel localMeanPanel = new JPanel();
1087 localMeanPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
1088 localMeanPanel.setBorder(BorderFactory.createTitledBorder("Use local mean"));
1089 chLocalMean = new JCheckBox("Local mean");
1090 chLocalMean.addItemListener(this);
1091 localMeanPanel.add(getControlwithLabel(chLocalMean, "",
1092 "Enable local mean feature. LM works best if mask is greater that object"
1093 + " (external masks). Apply only for binary masks or seeds "
1094 + "propagation between frames."));
1095 srLocalMeanWindow = getDoubleSpinner(23, 3, 501, 2, 0);
1096 localMeanPanel.add(getControlwithLabel(srLocalMeanWindow, "Window",
1097 "Odd mask within the local mean is evaluated"));
1098 constrProc.gridx = 0;
1099 constrProc.gridy = 6;
1100 processPanel.add(localMeanPanel, constrProc);
1101
1102
1103 JPanel postprocessPanel = new JPanel();
1104 postprocessPanel.setBorder(BorderFactory.createTitledBorder("Post-process"));
1105 postprocessPanel.setLayout(new GridBagLayout());
1106 JPanel postprocesshatPanel = new JPanel();
1107 postprocesshatPanel.setLayout(new GridLayout(4, 1, 0, 2));
1108 postprocesshatPanel.setBorder(BorderFactory.createTitledBorder("Hat filter"));
1109 chHatFilter = new JCheckBox("Hat Filter");
1110 chHatFilter.addItemListener(this);
1111 UiTools.setToolTip(chHatFilter, "Try to remove small inclusions in contour");
1112 postprocesshatPanel.add(getControlwithLabel(chHatFilter, "", ""));
1113 srAlev = getDoubleSpinner(0.9, 0, 1, 0.01, 4);
1114 postprocesshatPanel.add(getControlwithLabel(srAlev, "srAlev", ""));
1115 srNum = getDoubleSpinner(1, 0, 500, 1, 0);
1116 postprocesshatPanel.add(getControlwithLabel(srNum, "srNum",
1117 "If set to 0 all features with rank > srAlew will be removed"));
1118 srWindow = getDoubleSpinner(15, 1, 500, 1, 0);
1119 postprocesshatPanel.add(getControlwithLabel(srWindow, "srWindow", ""));
1120 GridBagConstraints constrPost = new GridBagConstraints();
1121 constrPost.gridx = 0;
1122 constrPost.gridy = 0;
1123 constrPost.fill = GridBagConstraints.HORIZONTAL;
1124 constrPost.anchor = GridBagConstraints.NORTH;
1125 constrPost.weightx = 1;
1126 postprocessPanel.add(postprocesshatPanel, constrPost);
1127 cbFilteringPostMethod = new JComboBox<String>();
1128 constrPost.gridx = 0;
1129 constrPost.gridy = 1;
1130 constrPost.insets = new Insets(5, 0, 0, 0);
1131 postprocessPanel.add(getControlwithLabel(cbFilteringPostMethod, "Binary filter",
1132 "Filtering applied after segmentation"), constrPost);
1133 chMaskCut = new JCheckBox("Cut output");
1134 constrPost.gridx = 0;
1135 constrPost.gridy = 2;
1136 UiTools.setToolTip(chMaskCut, "Cut output mask by initial mask (if present)");
1137 postprocessPanel.add(getControlwithLabel(chMaskCut, "", ""), constrPost);
1138
1139 JPanel displayPanel = new JPanel();
1140 displayPanel.setBorder(BorderFactory.createTitledBorder("Display options"));
1141 displayPanel.setLayout(new BoxLayout(displayPanel, BoxLayout.Y_AXIS));
1142 chShowSeed = new JCheckBox("Show seeds");
1143 UiTools.setToolTip(chShowSeed,
1144 "Show generated seeds. Works only if seeds are polpulated between frames"
1145 + " or if seeds are given as stack of masks");
1146 chShowSeed.setSelected(false);
1147 chShowPreview = new JCheckBox("Show preview");
1148 chShowPreview.setSelected(false);
1149 chShowProbMaps = new JCheckBox("Show maps");
1150 chShowProbMaps.setSelected(false);
1151 UiTools.setToolTip(chShowProbMaps,
1152 "Show probability maps for current frame. Does not work for stacks.");
1153 displayPanel.add(chShowSeed);
1154 displayPanel.add(chShowPreview);
1155 displayPanel.add(chShowProbMaps);
1156
1157
1158 JPanel caButtons = new JPanel();
1159 caButtons.setLayout(new FlowLayout(FlowLayout.CENTER));
1160 bnRun = new JButton("Run");
1161 UiTools.setToolTip(bnRun, "Run segmentation for all slices");
1162 bnRunActive = new JButton("Run active");
1163 UiTools.setToolTip(bnRunActive, "Run segmentation for selected slice only");
1164 bnCancel = new JButton("Cancel");
1165 bnHelp = new JButton("Help");
1166 caButtons.add(bnRun);
1167 caButtons.add(bnRunActive);
1168 caButtons.add(bnCancel);
1169 caButtons.add(bnHelp);
1170
1171 GridBagConstraints constrains = new GridBagConstraints();
1172 panel = new JPanel(new BorderLayout());
1173 panelMain = new JPanel(new GridBagLayout());
1174 panel.add(panelMain, BorderLayout.CENTER);
1175 JPanel panelButtons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
1176 panel.add(panelButtons, BorderLayout.SOUTH);
1177
1178 constrains.gridx = 0;
1179 constrains.gridy = 0;
1180 constrains.weighty = 1;
1181 constrains.gridheight = 1;
1182 constrains.anchor = GridBagConstraints.NORTH;
1183 constrains.fill = GridBagConstraints.HORIZONTAL;
1184 panelMain.add(imagePanel, constrains);
1185
1186 constrains.gridx = 0;
1187 constrains.gridy = 1;
1188 constrains.weighty = 1;
1189 constrains.gridheight = 1;
1190 constrains.anchor = GridBagConstraints.NORTH;
1191 constrains.fill = GridBagConstraints.HORIZONTAL;
1192 panelMain.add(seedSelPanel, constrains);
1193
1194 constrains.gridx = 0;
1195 constrains.gridy = 2;
1196 constrains.gridheight = 1;
1197 constrains.fill = GridBagConstraints.HORIZONTAL;
1198 constrains.weighty = 1;
1199 constrains.anchor = GridBagConstraints.NORTH;
1200 panelMain.add(getRgbImage(), constrains);
1201
1202 constrains.gridx = 3;
1203 constrains.gridy = 0;
1204 constrains.weighty = 1;
1205 constrains.gridheight = 3;
1206 constrains.anchor = GridBagConstraints.NORTH;
1207 constrains.fill = GridBagConstraints.VERTICAL;
1208 panelMain.add(optionsPanel, constrains);
1209
1210 constrains.gridx = 4;
1211 constrains.gridy = 0;
1212 constrains.weighty = 1;
1213 constrains.gridheight = 3;
1214 constrains.anchor = GridBagConstraints.NORTH;
1215 constrains.fill = GridBagConstraints.VERTICAL;
1216 panelMain.add(processPanel, constrains);
1217
1218 constrains.gridx = 5;
1219 constrains.gridy = 0;
1220 constrains.weighty = 1;
1221 constrains.gridheight = 3;
1222 constrains.anchor = GridBagConstraints.NORTH;
1223 constrains.fill = GridBagConstraints.VERTICAL;
1224 panelMain.add(postprocessPanel, constrains);
1225
1226 constrains.gridx = 7;
1227 constrains.gridy = 0;
1228 constrains.weighty = 0;
1229 constrains.fill = GridBagConstraints.VERTICAL;
1230 panelMain.add(displayPanel, constrains);
1231
1232 panelButtons.add(caButtons);
1233
1234 wnd.add(panel);
1235
1236 wnd.pack();
1237 wnd.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
1238 setInitial();
1239
1240 }
1241
1242
1243
1244
1245
1246
1247 public void enableUI(boolean status) {
1248 cbOrginalImage.setEnabled(status);
1249 cbRgbSeedImage.setEnabled(status);
1250 cbSeedSource.setEnabled(status);
1251 cbMaskSeedImage.setEnabled(status);
1252 bnQconfSeedImage.setEnabled(status);
1253 bnQconfShowSeedImage.setEnabled(status);
1254 bnClone.setEnabled(status);
1255 bnSeedRoi.setEnabled(status);
1256 bnFore.setEnabled(status);
1257 bnBack.setEnabled(status);
1258 cbCreatedSeedImage.setEnabled(status);
1259 srAlpha.setEnabled(status);
1260 srBeta.setEnabled(status);
1261 srGamma0.setEnabled(status);
1262 srGamma1.setEnabled(status);
1263 srIter.setEnabled(status);
1264 srRelerr.setEnabled(status);
1265 cbShrinkMethod.setEnabled(status);
1266 srShrinkPower.setEnabled(status);
1267 srExpandPower.setEnabled(status);
1268 if (cbShrinkMethod.getSelectedItem().equals("CONTOUR")) {
1269 srScaleMagn.setEnabled(status);
1270 srScaleSigma.setEnabled(status);
1271 srScaleCurvDistDist.setEnabled(status);
1272 srScaleEqNormalsDist.setEnabled(status);
1273 } else {
1274 cbShrinkMethod.setEnabled(status);
1275 }
1276 cbFilteringMethod.setEnabled(status);
1277 chTrueBackground.setEnabled(status);
1278 chInterFrameFilter.setEnabled(status);
1279 chHatFilter.setEnabled(status);
1280 if (chHatFilter.isSelected()) {
1281 chHatFilter.setEnabled(status);
1282 srAlev.setEnabled(status);
1283 srNum.setEnabled(status);
1284 srWindow.setEnabled(status);
1285 } else {
1286 chHatFilter.setEnabled(status);
1287 }
1288 chLocalMean.setEnabled(status);
1289 if (chLocalMean.isSelected()) {
1290 chLocalMean.setEnabled(status);
1291 srLocalMeanWindow.setEnabled(status);
1292 } else {
1293 chLocalMean.setEnabled(status);
1294 }
1295 cbFilteringMethod.setEnabled(status);
1296 chMaskCut.setEnabled(status);
1297 chShowPreview.setEnabled(status);
1298 chShowSeed.setEnabled(status);
1299 chShowProbMaps.setEnabled(status);
1300 cbFilteringPostMethod.setEnabled(status);
1301 bnRun.setEnabled(status);
1302 bnRunActive.setEnabled(status);
1303 bnHelp.setEnabled(status);
1304
1305
1306 srGamma0.setEnabled(false);
1307 }
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317 private JPanel getControlwithLabel(JComponent c, String label, String toolTip) {
1318 JPanel panel = new JPanel();
1319 panel.setLayout(new GridLayout(1, 2, 2, 2));
1320 JLabel lab = new JLabel(label);
1321 panel.add(lab);
1322 panel.add(c);
1323 UiTools.setToolTip(c, toolTip);
1324 UiTools.setToolTip(lab, toolTip);
1325 return panel;
1326 }
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336 private JPanel getControlwithLabelSqueezed(JComponent c, String label, String toolTip) {
1337 JPanel panel = new JPanel();
1338 panel.setLayout(new FlowLayout(FlowLayout.RIGHT));
1339 JLabel lab = new JLabel(label);
1340 panel.add(lab);
1341 panel.add(c);
1342 UiTools.setToolTip(c, toolTip);
1343 UiTools.setToolTip(lab, toolTip);
1344 return panel;
1345 }
1346
1347
1348
1349
1350
1351
1352
1353
1354 private JPanel getControlwithoutLabel(JComponent c, String toolTip) {
1355 JPanel panel = new JPanel();
1356 panel.setLayout(new GridLayout(1, 1, 2, 2));
1357 panel.add(c);
1358 if (toolTip != null && !toolTip.isEmpty()) {
1359 String text = "<html>" + QuimpToolsCollection.stringWrap(toolTip, 40, "<br>") + "</html>";
1360 c.setToolTipText(text);
1361 }
1362 return panel;
1363 }
1364
1365
1366
1367
1368
1369
1370
1371
1372 private JComponent getControlwithTooltip(JComponent c, String toolTip) {
1373 if (toolTip != null && !toolTip.isEmpty()) {
1374 String text = "<html>" + QuimpToolsCollection.stringWrap(toolTip, 40, "<br>") + "</html>";
1375 c.setToolTipText(text);
1376 }
1377 return c;
1378 }
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390 private JSpinner getDoubleSpinner(double d, double min, double max, double step, int columns) {
1391 SpinnerNumberModel model = new SpinnerNumberModel(d, min, max, step);
1392 JSpinner spinner = new JSpinner(model);
1393 String c = "";
1394 if (columns == 0) {
1395 c = "0";
1396 } else {
1397 c = "0." + String.join("", Collections.nCopies(columns, "0"));
1398 }
1399 spinner.setEditor(new JSpinner.NumberEditor(spinner, c));
1400 return spinner;
1401 }
1402
1403
1404
1405
1406 private void setInitial() {
1407 srAlev.setEnabled(false);
1408 srNum.setEnabled(false);
1409 srWindow.setEnabled(false);
1410 srLocalMeanWindow.setEnabled(false);
1411
1412 }
1413
1414
1415
1416
1417
1418
1419 private JPanel getRgbImage() {
1420 JPanel dynPanel;
1421 try {
1422 dynPanel = (JPanel) panelMain.getComponent(2);
1423 dynPanel.removeAll();
1424 } catch (ArrayIndexOutOfBoundsException e) {
1425 dynPanel = new JPanel();
1426 }
1427 dynPanel.setBorder(BorderFactory.createTitledBorder(
1428 BorderFactory.createLineBorder(Color.ORANGE), "Seeds fom RGB image"));
1429 dynPanel.setLayout(new GridLayout(2, 1, 2, 2));
1430
1431 dynPanel.add(cbRgbSeedImage);
1432 dynPanel.add(new JLabel());
1433 return dynPanel;
1434 }
1435
1436
1437
1438
1439
1440
1441 private JPanel getCreateImage() {
1442 JPanel dynPanel = (JPanel) panelMain.getComponent(2);
1443 dynPanel.removeAll();
1444
1445 dynPanel.setBorder(BorderFactory
1446 .createTitledBorder(BorderFactory.createLineBorder(Color.ORANGE), "Seed build"));
1447 dynPanel.setLayout(new BorderLayout());
1448 ((BorderLayout) dynPanel.getLayout()).setVgap(2);
1449
1450 JPanel seedBuildPanel = new JPanel();
1451 seedBuildPanel.setLayout(new GridLayout(2, 1, 2, 2));
1452 JPanel seedBuildPanelButtons = new JPanel();
1453 seedBuildPanelButtons.setLayout(new GridBagLayout());
1454
1455 GridBagConstraints constrProc = new GridBagConstraints();
1456 constrProc.gridx = 0;
1457 constrProc.gridy = 0;
1458 constrProc.weightx = 1;
1459 constrProc.weighty = 1;
1460 constrProc.fill = GridBagConstraints.HORIZONTAL;
1461
1462 seedBuildPanelButtons.add(bnClone, constrProc);
1463 constrProc.gridx = 1;
1464 constrProc.weightx = 1;
1465 constrProc.fill = GridBagConstraints.HORIZONTAL;
1466
1467 seedBuildPanelButtons.add(bnFore, constrProc);
1468 constrProc.gridx = 2;
1469 constrProc.weightx = 1;
1470 constrProc.fill = GridBagConstraints.HORIZONTAL;
1471
1472 seedBuildPanelButtons.add(bnBack, constrProc);
1473
1474 seedBuildPanel.add(seedBuildPanelButtons);
1475 seedBuildPanel.add(cbCreatedSeedImage);
1476
1477 dynPanel.add(seedBuildPanel);
1478
1479 return dynPanel;
1480 }
1481
1482
1483
1484
1485
1486
1487 private JPanel getMaskImage() {
1488 JPanel dynPanel = (JPanel) panelMain.getComponent(2);
1489 dynPanel.removeAll();
1490
1491 dynPanel.setBorder(BorderFactory
1492 .createTitledBorder(BorderFactory.createLineBorder(Color.ORANGE), "Seed from mask"));
1493 dynPanel.setLayout(new GridLayout(2, 1, 2, 2));
1494
1495 dynPanel.add(cbMaskSeedImage);
1496 dynPanel.add(new JLabel());
1497
1498 return dynPanel;
1499 }
1500
1501
1502
1503
1504
1505
1506 private JPanel getQconfImage() {
1507 JPanel dynPanel = (JPanel) panelMain.getComponent(2);
1508 dynPanel.removeAll();
1509
1510 dynPanel.setBorder(BorderFactory
1511 .createTitledBorder(BorderFactory.createLineBorder(Color.ORANGE), "Seed from QCONF"));
1512 dynPanel.setLayout(new GridLayout(2, 1, 2, 2));
1513
1514 JPanel upperrow = new JPanel();
1515 upperrow.setLayout(new GridBagLayout());
1516 GridBagConstraints constrProc = new GridBagConstraints();
1517 constrProc.gridx = 0;
1518 constrProc.gridy = 0;
1519 constrProc.weightx = 1;
1520 constrProc.weighty = 1;
1521 constrProc.fill = GridBagConstraints.HORIZONTAL;
1522 upperrow.add(bnQconfSeedImage, constrProc);
1523 constrProc.gridx = 1;
1524 constrProc.gridy = 0;
1525 constrProc.weightx = 1;
1526 constrProc.weighty = 1;
1527 constrProc.fill = GridBagConstraints.HORIZONTAL;
1528 upperrow.add(bnQconfShowSeedImage, constrProc);
1529 dynPanel.add(upperrow);
1530 dynPanel.add(lbQconfFile);
1531
1532 return dynPanel;
1533 }
1534
1535
1536
1537
1538
1539
1540 private JPanel getRois() {
1541 JPanel dynPanel = (JPanel) panelMain.getComponent(2);
1542 dynPanel.removeAll();
1543
1544 dynPanel.setBorder(BorderFactory
1545 .createTitledBorder(BorderFactory.createLineBorder(Color.ORANGE), "Seed from ROIs"));
1546 dynPanel.setLayout(new BorderLayout());
1547 ((BorderLayout) dynPanel.getLayout()).setVgap(2);
1548
1549 JPanel seedBuildPanel = new JPanel();
1550 seedBuildPanel.setLayout(new GridLayout(2, 1, 2, 2));
1551 JPanel seedBuildPanelButtons = new JPanel();
1552 seedBuildPanelButtons.setLayout(new GridBagLayout());
1553
1554 GridBagConstraints constrProc = new GridBagConstraints();
1555 constrProc.gridx = 0;
1556 constrProc.gridy = 0;
1557 constrProc.weightx = 1;
1558 constrProc.weighty = 1;
1559 constrProc.fill = GridBagConstraints.HORIZONTAL;
1560
1561 seedBuildPanelButtons.add(bnClone, constrProc);
1562 constrProc.gridx = 1;
1563 constrProc.weightx = 1;
1564 constrProc.fill = GridBagConstraints.HORIZONTAL;
1565
1566 seedBuildPanelButtons.add(bnSeedRoi, constrProc);
1567
1568 seedBuildPanel.add(seedBuildPanelButtons);
1569 seedBuildPanel.add(lbRoiSeedsInfo);
1570
1571 dynPanel.add(seedBuildPanel);
1572
1573 return dynPanel;
1574 }
1575
1576
1577
1578
1579 public void show() {
1580 wnd.setVisible(true);
1581
1582 }
1583
1584
1585
1586
1587
1588
1589 @Override
1590 public void actionPerformed(ActionEvent e) {
1591 Object source = e.getSource();
1592 if (source == cbSeedSource) {
1593 SeedSource val = SeedSource.valueOf((String) cbSeedSource.getSelectedItem());
1594 switch (val) {
1595 case RGBImage:
1596 getRgbImage();
1597 panelMain.revalidate();
1598 wnd.validate();
1599 break;
1600 case CreatedImage:
1601 getCreateImage();
1602 panelMain.revalidate();
1603 wnd.validate();
1604 break;
1605 case MaskImage:
1606 getMaskImage();
1607 panelMain.revalidate();
1608 wnd.validate();
1609 break;
1610 case QconfFile:
1611 getQconfImage();
1612 panelMain.revalidate();
1613 wnd.validate();
1614 break;
1615 case Rois:
1616 getRois();
1617 panelMain.revalidate();
1618 wnd.validate();
1619 break;
1620 }
1621 }
1622 if (source == bnFore) {
1623 if (bnFore.isSelected()) {
1624 bnBack.setSelected(false);
1625 }
1626 }
1627 if (source == bnBack) {
1628 if (bnBack.isSelected()) {
1629 bnFore.setSelected(false);
1630 }
1631 }
1632 }
1633
1634
1635
1636
1637
1638
1639 @Override
1640 public void itemStateChanged(ItemEvent arg0) {
1641 Object source = arg0.getItemSelectable();
1642 if (source == chHatFilter) {
1643 srAlev.setEnabled(chHatFilter.isSelected());
1644 srNum.setEnabled(chHatFilter.isSelected());
1645 srWindow.setEnabled(chHatFilter.isSelected());
1646 }
1647 if (source == chLocalMean) {
1648 srLocalMeanWindow.setEnabled(chLocalMean.isSelected());
1649 }
1650 if (source == cbShrinkMethod) {
1651 if (!cbShrinkMethod.getSelectedItem().equals("CONTOUR")) {
1652 srScaleMagn.setEnabled(false);
1653 srScaleSigma.setEnabled(false);
1654 srScaleEqNormalsDist.setEnabled(false);
1655 srScaleCurvDistDist.setEnabled(false);
1656 } else {
1657 srScaleMagn.setEnabled(true);
1658 srScaleSigma.setEnabled(true);
1659 srScaleEqNormalsDist.setEnabled(true);
1660 srScaleCurvDistDist.setEnabled(true);
1661 }
1662 }
1663 }
1664
1665
1666
1667
1668
1669
1670
1671
1672 private void setJComboBox(JComboBox<String> component, String[] item, String sel) {
1673 for (String i : item) {
1674 component.addItem(i);
1675 }
1676 if (item.length > 0) {
1677 component.setSelectedItem(sel);
1678 }
1679 component.revalidate();
1680 wnd.pack();
1681 }
1682
1683
1684
1685
1686
1687
1688
1689 private int getJComboBox(JComboBox<String> component) {
1690 return component.getSelectedIndex();
1691 }
1692
1693
1694
1695
1696
1697
1698 public void addWindowController(WindowFocusListener listener) {
1699 wnd.addWindowFocusListener(listener);
1700 }
1701
1702
1703
1704
1705
1706
1707 public void addRunController(ActionListener list) {
1708 bnRun.addActionListener(list);
1709 }
1710
1711
1712
1713
1714
1715
1716 public void addHelpController(ActionListener list) {
1717 bnHelp.addActionListener(list);
1718 }
1719
1720
1721
1722
1723
1724
1725 public void addRunActiveController(ActionListener list) {
1726 bnRunActive.addActionListener(list);
1727 }
1728
1729
1730
1731
1732
1733
1734 public void addCancelController(ActionListener list) {
1735 bnCancel.addActionListener(list);
1736 }
1737
1738
1739
1740
1741
1742
1743 public void addCloneController(ActionListener list) {
1744 bnClone.addActionListener(list);
1745 }
1746
1747
1748
1749
1750
1751
1752 public void addSeedRoiController(ActionListener list) {
1753 bnSeedRoi.addActionListener(list);
1754 }
1755
1756
1757
1758
1759
1760
1761 public void addFgController(ActionListener list) {
1762 bnFore.addActionListener(list);
1763 }
1764
1765
1766
1767
1768
1769
1770 public void addBgController(ActionListener list) {
1771 bnBack.addActionListener(list);
1772 }
1773
1774
1775
1776
1777
1778
1779 public void addLoadQconfController(ActionListener list) {
1780 bnQconfSeedImage.addActionListener(list);
1781 }
1782
1783
1784
1785
1786
1787
1788 public void addQconfShowSeedImageController(ActionListener list) {
1789 bnQconfShowSeedImage.addActionListener(list);
1790 }
1791
1792
1793
1794
1795
1796
1797 public void addImageController(ActionListener list) {
1798 cbOrginalImage.addActionListener(list);
1799 }
1800
1801
1802
1803
1804
1805
1806 public void addSeedController(ActionListener list) {
1807 cbRgbSeedImage.addActionListener(list);
1808 cbMaskSeedImage.addActionListener(list);
1809 cbCreatedSeedImage.addActionListener(list);
1810 }
1811
1812
1813
1814
1815
1816
1817 public void setCancelLabel(String label) {
1818 bnCancel.setText(label);
1819 }
1820
1821 }