1 package com.github.celldynamics.quimp.plugin.dic;
2
3 import java.util.Arrays;
4
5 import org.slf4j.Logger;
6 import org.slf4j.LoggerFactory;
7
8 import com.github.celldynamics.quimp.plugin.IQuimpPluginFilter;
9 import com.github.celldynamics.quimp.plugin.ParamList;
10 import com.github.celldynamics.quimp.plugin.QuimpPluginException;
11 import com.github.celldynamics.quimp.registration.Registration;
12 import com.github.celldynamics.quimp.utils.QuimPArrayUtils;
13
14 import ij.IJ;
15 import ij.ImagePlus;
16 import ij.ImageStack;
17 import ij.gui.GenericDialog;
18 import ij.process.ImageProcessor;
19 import ij.process.ShortProcessor;
20
21
22
23
24
25
26
27
28
29 public class DicLidReconstruction_ implements IQuimpPluginFilter {
30
31
32
33
34 static final Logger LOGGER = LoggerFactory.getLogger(DicLidReconstruction_.class.getName());
35 private LidReconstructor dic;
36 private ImagePlus imp;
37
38
39
40 private double angle;
41
42
43
44 private double decay;
45
46
47
48 private int masksize;
49
50
51
52
53
54 private String prefilterangle;
55
56
57
58
59
60 private boolean invertOutput;
61
62
63
64
65
66
67 @Override
68 public int setup(String arg, ImagePlus imp) {
69 this.imp = imp;
70 return DOES_8G + NO_CHANGES;
71 }
72
73
74
75
76
77
78 @Override
79 public int setup() {
80 return 0;
81 }
82
83
84
85
86
87
88 @Override
89 public void run(ImageProcessor ip) {
90
91 new Registration(IJ.getInstance(), "QuimP Registration");
92 ImageProcessor ret;
93 if (showUi(true) == 0) {
94 return;
95 }
96 try {
97
98 ImagePlus result = new ImagePlus("DIC_" + imp.getTitle(),
99 new ShortProcessor(ip.getWidth(), ip.getHeight()));
100 dic = new LidReconstructor(imp.getProcessor(), decay, angle, prefilterangle, masksize);
101 if (imp.getStack().getSize() == 1) {
102
103 IJ.showProgress(0.0);
104 ret = dic.reconstructionDicLid();
105 if (invertOutput) {
106 ret.invert();
107 }
108 result.getProcessor().setPixels(ret.getPixels());
109 IJ.showProgress(1.0);
110 result.show();
111 } else {
112
113 ImageStack resultstack = new ImageStack(imp.getWidth(), imp.getHeight());
114 ImageStack stack = imp.getStack();
115 for (int s = 1; s <= stack.getSize(); s++) {
116 IJ.showProgress(s / ((double) stack.getSize() + 1));
117 dic.setIp(stack.getProcessor(s));
118 ret = dic.reconstructionDicLid();
119 if (invertOutput) {
120 ret.invert();
121 }
122 resultstack.addSlice(ret);
123 }
124 IJ.showProgress(1.0);
125
126 new ImagePlus("DIC_" + imp.getTitle(), resultstack).show();
127 }
128 } catch (DicException e) {
129 IJ.log(e.getMessage());
130 LOGGER.debug(e.getMessage(), e);
131 LOGGER.error("Problem with DIC reconstruction: " + e.getMessage());
132 } finally {
133 imp.updateAndDraw();
134 }
135 }
136
137
138
139
140
141
142
143 String roundtofull(double angle) {
144 int anglei = (int) angle;
145 if (anglei >= 180) {
146 anglei -= 180;
147 }
148
149 Integer[] d = new Integer[5];
150 d[0] = Math.abs(0 - anglei);
151 d[1] = Math.abs(45 - anglei);
152 d[2] = Math.abs(90 - anglei);
153 d[3] = Math.abs(135 - anglei);
154 d[4] = Math.abs(180 - anglei);
155
156 int i = QuimPArrayUtils.minListIndex(Arrays.asList(d));
157 i = i > 3 ? 0 : i;
158 return Integer.toString(i * 45);
159 }
160
161
162
163
164
165
166
167
168 @Override
169 public void setPluginConfig(ParamList par) throws QuimpPluginException {
170 }
171
172
173
174
175
176
177 @Override
178 public ParamList getPluginConfig() {
179 return null;
180 }
181
182
183
184
185
186
187
188 @Override
189 public int showUi(boolean val) {
190 GenericDialog gd = new GenericDialog("DIC reconstruction");
191 gd.addMessage("Reconstruction of DIC image by Line Integrals.\n");
192 gd.addNumericField("Shear angle (measured counterclockwise)", 45.0, 0, 6, "[deg]");
193 gd.addNumericField("Decay factor (>0)", 0.0, 2, 6, "[-]");
194
195
196 gd.addNumericField("Filter mask size (odd, 0 to switch filtering off)", 0, 0);
197 gd.addCheckbox("Invert output", false);
198
199 gd.setResizable(false);
200 gd.showDialog();
201 if (gd.wasCanceled()) {
202 return 0;
203 }
204
205
206 angle = Math.abs(gd.getNextNumber());
207 if (angle >= 360) {
208 angle -= 360;
209 }
210 decay = gd.getNextNumber();
211 prefilterangle = roundtofull(angle + 90);
212 masksize = (int) gd.getNextNumber();
213 invertOutput = gd.getNextBoolean();
214
215 if (gd.invalidNumber()) {
216 IJ.error("One of the numbers in dialog box is not valid");
217 return 0;
218 }
219 if (masksize != 0 && masksize % 2 == 0) {
220 IJ.error("Mask size must be uneven");
221 return 0;
222 }
223
224 return 1;
225 }
226
227
228
229
230
231
232 @Override
233 public String getVersion() {
234 return "See QuimP version";
235 }
236
237
238
239
240
241
242 @Override
243 public String about() {
244 return "DIC plugin.\n" + "Author: Piotr Baniukiewicz\n" + "mail: p.baniukiewicz@warwick.ac.uk\n"
245 + "This plugin supports macro parameters\n" + "Check macro recorder";
246 }
247
248 }