/*************************************************************************
* Compilation: javac SE_MTF_2xNyquist.java
* Execution: java SE_MTF_2xNyquist
*
* Calculates the Modulation Transfer Function (MTF) for an image of f rows and c columns of pixels selected.
* For FFT requirements, uses a sample of power of 2 rows for both the calculation of the MTF and the SPP.
*
* Calcula la Función de Transferencia de Modulación (MTF) para una imagen de un tamaño f filas y
* c columnas de pixels seleccionados.
* Por requisitos de la fft, se utiliza una muestra de hileras potencia de 2 tanto para el calculo
* de la MTF como de la SPP.
*
*
* Limitations
* -----------
* * TIFF image only
*
*
*************************************************************************/
import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.*;
import java.awt.event.*;
import ij.plugin.PlugIn;
import ij.plugin.frame.*;
import ij.measure.*;
import ij.io.*;
import java.math.BigDecimal;
import ij.text.*;
import java.util.*;
import java.lang.Object.*;
import java.lang.Integer;
import ij.process.ColorProcessor;
import ij.process.ImageConverter;
import ij.process.StackConverter;
import ij.plugin.filter.*;
import ij.plugin.filter.RGBStackSplitter;
import ij.*;
import ij.process.*;
import ij.gui.*;
import ij.measure.Calibration;
import java.awt.*;
import ij.plugin.FFT.*;
import java.util.EventObject;
public class SE_MTF_2xNyquist implements PlugIn,ActionListener,WindowListener,DialogListener{
Frame frame;
ImagePlus imp,impOriginal;
ProfilePlot plotESF;
Plot plotResult;
int k;
int i;
int selecWidth;
int selecHeight;
int sppLength;
double[] ESFLinea;
double[][] ESFArray;
double[][] LSFArray;
double[] Vector;
double[][] Array;
double[][] ArrayF;
double[][] ESFArrayF;
double[][] LSFArrayF;
double[][] PosMax;
double[]ESFVector;
double[]LSFVector;
double[]LSFDVector;
double[]MTFVector;
double[]SPPVector;
double[]Max;
String title;
Roi roi;
int optWidth;
int optHeight;
int sChannel;
int sFrequnits;
int type;
boolean isStack;
int roiType;
int sSize;
boolean cancel;
int bit;
int yMax;
double mmSensors=0.0;
int nPhotodetectors=0;
double ny=1;
// Message that asks the user what to do
public void run(String arg){
frame = new Frame("SE_MTF");
frame.setLayout(new GridBagLayout());
frame.setBounds(100, 100, 450, 100);
Button button1 = new Button("Generate MTF");
button1.addActionListener(this);
GridBagConstraints c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 1;
c.gridwidth = 1;
c.anchor = GridBagConstraints.NORTH;
c.insets.top = 0;
c.insets.left = 0;
c.insets.bottom= 0;
c.insets.right = 0;
c.weightx = 0;
c.weighty = 0;
c.fill = GridBagConstraints.NONE;
((GridBagLayout)frame.getLayout()).setConstraints(button1, c);
frame.add(button1);
frame.validate();
frame.show();
frame.setBackground(Color.lightGray);
frame.setResizable(false);
frame.setLocation(0,0);
frame.addWindowListener(this);
}
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command==null){
return;
}
if (command.equals("Generate MTF")){
cancel=false;
openImage();
if (cancel==false){
options();
}
if (cancel==false){
generateESFArray("ESF Plot",imp,roi);
generateLSFArray("LSF Plot",ESFArray);
calculateMax();
ESFArrayF=alignArray(ESFArray);
if (cancel==false){
LSFArrayF=alignArray(LSFArray);
}
if (cancel==false){
ESFVector=averageVector(ESFArrayF);
}
if (cancel==false){
LSFVector=averageVector(LSFArrayF);
int aura = (LSFVector.length * 2);
LSFDVector = new double [aura];
int j = 0;
int aura2 = (LSFVector.length);
for(i=0;i<(LSFDVector.length-3); i++){
if(i % 2 == 0) {
LSFDVector[i]= LSFVector[j];
j=j+1;
}else {
LSFDVector[i]= ((0.375*LSFVector[(j-1)]) + (0.75*LSFVector[(j)]) - (0.125*LSFVector[(j+1)]));
}
}
LSFDVector[i] = ((LSFVector[j-1] + LSFVector[j])*0.5);
LSFDVector[i+1] = LSFVector[j];
LSFDVector[i+2] = LSFVector[j];
int indexMax = 0;
double valorMax = LSFDVector[0];
for(int i=0;i<LSFDVector.length;i++){
if(valorMax < LSFDVector[i]){
indexMax = i;
valorMax = LSFDVector[i];
}
}
i=indexMax;
LSFDVector[i-1]=((LSFDVector[i-2] + LSFDVector[i])*0.5);
MTFVector=fftConversion(LSFDVector, "MTF");
Max=obtenerMax();
SPPVector=fftConversion(Max,"SPP");
//-****************************************************************-S'hauria d'intentar que no quedéssin superposats, sinó en escala, cada un 10 més avall
generatePlot(MTFVector,"MTF");
generatePlot(LSFVector,"LSF");
generatePlot(ESFVector,"ESF");
generatePlot(SPPVector,"SPP");
}
}
cleanImage();
}
}
public void openImage(){
boolean opButton=true;
imp = WindowManager.getCurrentImage();
if (imp==null){
IJ.showMessage("Error","There are no images open\nProcess canceled");
cancel=true;
}
title=imp.getTitle();
if (cancel==false){
type=imp.getType();
switch(type){
case ImagePlus.GRAY8:{
isStack=false;
yMax=255;
} break;
case ImagePlus.GRAY16:{
isStack=false;
yMax=65535;
} break;
case ImagePlus.GRAY32:{
isStack=false;
yMax=2147483647;
} break;
case ImagePlus.COLOR_256:{
isStack=true;
yMax=255;
} break;
case ImagePlus.COLOR_RGB:{
isStack=true;
yMax=255;
} break;
default: yMax=255;
}
//Get the selection
roi = imp.getRoi();
if (roi==null) {
imp.setRoi(0, 0, imp.getWidth(), imp.getHeight());
roi = imp.getRoi();
opButton=IJ.showMessageWithCancel("Warning","All image selected");
if (opButton==false) cancel=true;
}
}
if (cancel==false){
//Rectangular selection
roiType = roi.getType();
if (!(roi.isLine() || roiType==Roi.RECTANGLE)) {
IJ.showMessage("Error","Line or rectangular selection required\nProcess canceled");
cancel=true;
}
}
}
void cleanImage(){
imp.killRoi();
}
void generateStack(){
if (isStack==true && sChannel!=3){
ImageConverter ic = new ImageConverter(imp);
ic.convertToRGBStack();
ImageStack is;
is=imp.getStack();
}
}
void options(){
GenericDialog gd = new GenericDialog("MTF - Options",frame);
//User can choose the units
gd.addDialogListener(this);
String[]frequnits=new String[3];
frequnits[0]="Absolute (lp/mm)";
frequnits[1]="Relative (cycles/pixel)";
frequnits[2]="Line widths per picture height (LW/PH)";
gd.addChoice("Frequency units:",frequnits,frequnits[1]);
//Input data
gd.addNumericField("Sensor size (mm): ",mmSensors,1);
gd.addNumericField("Number of photodetectors: ",nPhotodetectors,0);
((Component) gd.getNumericFields().get(0)).setEnabled(false);
((Component) gd.getNumericFields().get(1)).setEnabled(false);
//The user can choose the sample width
String[]sampleSize=new String[5];
sampleSize[0]="32";
sampleSize[1]="64";
sampleSize[2]="128";
sampleSize[3]="256";
sampleSize[4]="512";
gd.addChoice("Sample size (pixels):",sampleSize,sampleSize[0]);
//If is a greyscale image there is no options avaliable
if (isStack==false){
gd.addMessage("This is a greyscale image, no optio
- 1
- 2
前往页