Skip to content

Instantly share code, notes, and snippets.

@NicoKiaru
Created April 11, 2022 07:40
Show Gist options
  • Save NicoKiaru/cc5135688a722dc64eb96121cc069c18 to your computer and use it in GitHub Desktop.
Save NicoKiaru/cc5135688a722dc64eb96121cc069c18 to your computer and use it in GitHub Desktop.
Demoing cartesian to polar and polar to cartesian transform with imglib2
// See https://forum.image.sc/t/reconstructing-tomographic-light-sheet-data-2d-slice-into-cylindrical-3d-volume
// Bigdataviewer-playground update site need to be activated
#@ConvertService cs
#@ImagePlus(required=false) image
#@int numberOfAngles
#@BdvHandle(required=false) bdvPolar
#@BdvHandle(required=false) bdvCar
#@ColorRGB color
#@SourceAndConverterBdvDisplayService bdvDisplay
#@Boolean adjustView
//------------------ Dataset preparation
// Downloading the dataset if not present
if (image==null) {
IJ.open("https://github.com/haesleinhuepf/BioImageAnalysisNotebooks/raw/b2d1fdab0006b8d2aa4406efc4a144730c74dba7/data/Haase_MRT_tfl3d1.tif") // robert image
image = IJ.getImage()
}
def datasetName = image.getTitle()
def voxSizeXY = (image.getCalibration().pixelWidth+image.getCalibration().pixelHeight)/2.0
def voxSizeZ = image.getCalibration().pixelDepth
def totalXYSize = Math.max(image.getWidth()*voxSizeXY,image.getHeight()*voxSizeXY)
def totalDepth = image.getNSlices()*voxSizeZ
def sources = cs.convert(datasetName, SourceAndConverter[].class)
if (sources == null) { // null sources -> need to import from the current image plus
// avoid converting two times the sources - executed only once
IJ.run("Make BDVDataset from current IJ1 image")
sources = cs.convert(datasetName, SourceAndConverter[].class)
def preTransform = new AffineTransform3D();
def center = SourceAndConverterHelper.getSourceAndConverterCenterPoint(sources[0])
preTransform.translate(-center.getDoublePosition(0),-center.getDoublePosition(1), -center.getDoublePosition(2)); // Recenter
preTransform.rotate(0, Math.PI/2.0); // Rotate axis correctly
for (source : sources) {
SourceTransformHelper.append(preTransform, new SourceAndConverterAndTimeRange(source,0))
}
}
//-------------------------- Cartesian to polar transform
def pol2car = new Wrapped2DTransformAs3D(new PolarToCartesianTransform2D());
def polarSources = new SourceAndConverter[sources.length]
for (int ch=0; ch<sources.length; ch++) {
polarSources[ch] = new SourceRealTransformer(pol2car).apply(sources[ch])
}
//-------------------------- Subsampling the number of angles acquired
// We take the interval spanning [0..Rmax, -PI..+PI, -Zmax/2..+Zmax/2]
def interval = new FinalRealInterval(
new double[]{0, -Math.PI,-totalXYSize/2.0},
new double[]{totalXYSize/2.0,Math.PI, totalXYSize/2.0})
def resamplingModel = new EmptySourceAndConverterCreator(
"Model_"+numberOfAngles,
interval,
voxSizeXY, // vox size R
Math.PI/(double)(numberOfAngles), // vox size theta
voxSizeZ // vox size Z
).get();
def imglib2color = new ARGBType(ARGBType.rgba(color.getRed(), color.getGreen(), color.getBlue(), 255));
def polarRasterSources = new SourceAndConverter[sources.length]
for (int ch=0; ch<sources.length; ch++) {
polarRasterSources[ch] = new SourceResampler(polarSources[ch],resamplingModel,sources[0].getSpimSource().getName()+"_polar_"+numberOfAngles, false, false, false, 0).get()
new ColorChanger(polarRasterSources[ch], imglib2color).run();
}
//-------------------------- Polar to cartesian transform, using subsampled source
def inversePolarRasterSources = new SourceAndConverter[sources.length]
def car2pol = new Wrapped2DTransformAs3D(new PolarToCartesianTransform2D()).inverse();
for (int ch=0; ch<sources.length; ch++) {
inversePolarRasterSources[ch] = new SourceRealTransformer(car2pol).apply(polarRasterSources[ch])
new ColorChanger(inversePolarRasterSources[ch], imglib2color).run();
}
//--------------------------- Display sources
if (bdvPolar==null) {
bdvPolar = bdvDisplay.getNewBdv()
BdvHandleHelper.setWindowTitle(bdvPolar, "Polar");
}
//bdvDisplay.show(bdvPolar, polarSources)
bdvDisplay.show(bdvPolar, polarRasterSources)
if (adjustView) new ViewerTransformAdjuster(bdvPolar, polarRasterSources[0]).run()
if (bdvCar==null) {
bdvCar = bdvDisplay.getNewBdv()
BdvHandleHelper.setWindowTitle(bdvCar, "Cartesian");
}
bdvDisplay.show(bdvCar, sources)
bdvDisplay.show(bdvCar, inversePolarRasterSources)
if (adjustView) new ViewerTransformAdjuster(bdvCar, sources[0]).run()
import bdv.viewer.SourceAndConverter
import bdv.util.BdvFunctions
import net.imglib2.img.display.imagej.ImageJFunctions
import net.imglib2.FinalRealInterval
import net.imglib2.realtransform.AffineTransform3D
import net.imglib2.realtransform.Wrapped2DTransformAs3D
import net.imglib2.realtransform.PolarToCartesianTransform2D
import net.imglib2.type.numeric.ARGBType
import sc.fiji.bdvpg.sourceandconverter.display.ColorChanger
import sc.fiji.bdvpg.sourceandconverter.transform.SourceResampler
import sc.fiji.bdvpg.sourceandconverter.SourceAndConverterHelper
import sc.fiji.bdvpg.sourceandconverter.transform.SourceTransformHelper
import sc.fiji.bdvpg.sourceandconverter.SourceAndConverterAndTimeRange
import sc.fiji.bdvpg.sourceandconverter.transform.SourceRealTransformer
import sc.fiji.bdvpg.sourceandconverter.importer.EmptySourceAndConverterCreator
import sc.fiji.bdvpg.bdv.BdvHandleHelper
import sc.fiji.bdvpg.bdv.navigate.ViewerTransformAdjuster
import ij.IJ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment