package edu.stanford.rsl.apps.gui.roi;
import ij.IJ;
import ij.gui.Plot;
import ij.gui.PointRoi;
import edu.stanford.rsl.conrad.utils.DoubleArrayUtil;
import edu.stanford.rsl.conrad.utils.FFTUtil;
import edu.stanford.rsl.conrad.utils.UserUtil;
import edu.stanford.rsl.conrad.utils.VisualizationUtil;
public class Measure2DBeadMTFMultiDirection extends Measure3DBeadMTF {
double r = 16, segments = 4;
@Override
public Object evaluate() {
if (configured) {
if (roi instanceof PointRoi){
PointRoi point = (PointRoi) roi;
double [] sum = null;
int px = point.getBounds().x;
int py = point.getBounds().y;
int pz = image.getCurrentSlice()-1;
int smallstep = 1;
for (int j=0; j < segments; j++){
double intervalSize = 360.0/ (segments*2);
int start = (int) ((j*intervalSize) - (intervalSize/2));
int end = (int) ((j*intervalSize) + (intervalSize/2));
for (int i = (int) start; i < end; i++){
double beta = ((i*smallstep) / 180.0) * Math.PI;
// direction vector
double x = r * Math.cos(beta);
double y = r * Math.sin(beta);
double z = 0;
// Interpolate along line
double [] pixels = getPixels(image, px, px+x, py,py+y,pz,pz+z, (int) (2*r));
// remove mean for frequency analysis:
double [] minmax = DoubleArrayUtil.minAndMaxOfArray(pixels);
DoubleArrayUtil.add(pixels, -minmax[0]);
double [] kernel = {-1, 0, 1};
double [] edge = DoubleArrayUtil.convolve(pixels, kernel);
// FFT
double [] fft = FFTUtil.fft(edge);
if (sum == null){
sum = fft;
} else {
DoubleArrayUtil.add(sum, fft);
}
}
int start2 = (int) (((j+segments)*intervalSize) - (intervalSize/2));
int end2 = (int) (((j+segments)*intervalSize) + (intervalSize/2));
for (int i = (int) start; i < end; i++){
double beta = ((i*smallstep) / 180.0) * Math.PI;
// direction vector
double x = r * Math.cos(beta);
double y = r * Math.sin(beta);
double z = 0;
// Interpolate along line
double [] pixels = getPixels(image, px, px+x, py,py+y,pz,pz+z, (int) (2*r));
// remove mean for frequency analysis:
double [] minmax = DoubleArrayUtil.minAndMaxOfArray(pixels);
DoubleArrayUtil.add(pixels, -minmax[0]);
double [] kernel = {-1, 0, 1};
double [] edge = DoubleArrayUtil.convolve(pixels, kernel);
// FFT
double [] fft = FFTUtil.fft(edge);
if (sum == null){
sum = fft;
} else {
DoubleArrayUtil.add(sum, fft);
}
}
DoubleArrayUtil.divide(sum, Math.abs((end - start)+(end2-start2)));
System.out.println("MTF:");
for (int i=0; i<(sum.length/4); i++) {
System.out.println(FFTUtil.abs(i, sum));
}
Plot plot = VisualizationUtil.createHalfComplexPowerPlot(sum, "Edge MTF of " + image.getTitle() + " from " + start + " to " + end + " and "+ start2 + " to " + end2 + " (deg)");
try{
plot.show();
} catch (Exception e){
}
}
}
}
return null;
}
@Override
public void configure() throws Exception {
image = IJ.getImage();
roi = image.getRoi();
if (roi != null){
r = UserUtil.queryDouble("Radius in pixels: ", r);
segments = UserUtil.queryDouble("Number of Segments: ", segments);
configured = true;
}
}
@Override
public String toString() {
return "Measure 2D Bead MTF in multiple angular intervals";
}
}
/*
* Copyright (C) 2010-2014 - Andreas Maier
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/