package edu.stanford.rsl.conrad.phantom.renderer;
import java.io.IOException;
import ij.ImagePlus;
import ij.ImageStack;
import edu.stanford.rsl.apps.gui.Citeable;
import edu.stanford.rsl.apps.gui.GUIConfigurable;
import edu.stanford.rsl.conrad.data.numeric.Grid3D;
import edu.stanford.rsl.conrad.filtering.ImageFilteringTool;
import edu.stanford.rsl.conrad.io.ImagePlusDataSink;
import edu.stanford.rsl.conrad.opencl.OpenCLMaterialPathLengthPhantomRenderer;
import edu.stanford.rsl.conrad.opencl.OpenCLProjectionPhantomRenderer;
import edu.stanford.rsl.conrad.pipeline.IndividualImagePipelineFilteringTool;
import edu.stanford.rsl.conrad.pipeline.ParallelImageFilterPipeliner;
import edu.stanford.rsl.conrad.pipeline.ProjectionSource;
/**
* Abstract class to describe a numerical phantom.
*
* @author akmaier
*
*/
public abstract class PhantomRenderer implements ProjectionSource, Citeable, GUIConfigurable {
protected boolean configured;
protected int projectionNumber;
protected boolean init = false;
protected synchronized void init(){
//if (!init){
// createPhantom();
// init = true;
//}
}
public void initStream(String filename) throws IOException {
//
}
/**
* Returns the name of the phantom
*/
public abstract String toString();
/**
* Method to start the voxelization of the phantom.
*/
public abstract void createPhantom();
@Override
public boolean isConfigured() {
return configured;
}
/**
* Returns a list of all known numerical phantoms.
* @return the list.
*/
public static PhantomRenderer [] getPhantoms(){
PhantomRenderer [] phantoms = {new MetricPhantomRenderer(), new ParallelProjectionPhantomRenderer(), new OpenCLProjectionPhantomRenderer(), new OpenCLMaterialPathLengthPhantomRenderer()};
return phantoms;
}
/**
* Creates an empty volume which can be used to render the phantom into.
*
* @param title the title
* @param dimx the size in x direction
* @param dimy the size in y direction
* @param dimz the size in z direction (slice number)
* @return the empty volume
*/
public static ImagePlus createEmptyVolume(String title, int dimx, int dimy, int dimz){
ImageStack stack = new ImageStack(dimx, dimy, dimz);
for(int i = 0; i < dimz; i++){
stack.setPixels(new float[dimx * dimy], i+1);
}
ImagePlus projectionVolume = new ImagePlus();
projectionVolume.setStack(title, stack);
return projectionVolume;
}
@Override
public int getCurrentProjectionNumber() {
return projectionNumber;
}
@Override
public void getNextProjection(IndividualImagePipelineFilteringTool tool) {
if (!init) init();
tool.setImageProcessor(getNextProjection());
tool.setImageIndex(projectionNumber);
projectionNumber++;
}
public static Grid3D generateProjections(final PhantomRenderer phantom) throws Exception{
Thread thread = new Thread(new Runnable(){public void run(){phantom.createPhantom();}});
thread.start();
ImagePlusDataSink sink = new ImagePlusDataSink();
ParallelImageFilterPipeliner pipeliner = new ParallelImageFilterPipeliner(phantom, new ImageFilteringTool[]{}, sink);
pipeliner.project(true);
Grid3D result = sink.getResult();
return result;
}
}
/*
* Copyright (C) 2010-2014 Andreas Maier
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/