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). */