Skip to content

Instantly share code, notes, and snippets.

@bnorthan
Created December 9, 2019 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bnorthan/bc674b3ad116ae64d4a4bd38aa95e666 to your computer and use it in GitHub Desktop.
Save bnorthan/bc674b3ad116ae64d4a4bd38aa95e666 to your computer and use it in GitHub Desktop.
package com.example;
import java.io.IOException;
import net.imagej.Dataset;
import net.imagej.ImageJ;
import net.imagej.ImgPlus;
import net.imagej.ops.filter.pad.PadInputFFTMethods;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.type.numeric.complex.ComplexFloatType;
import net.imglib2.type.numeric.real.FloatType;
import net.imglib2.view.Views;
/**
* Tests involving convolvers.
*/
public class FFTConvolve {
static String workingDir = "/home/bnorthan/images/DeconQuickTest/";
static String imgName = workingDir + "CElegans-CY3.tif";
public static <T extends RealType<T> & NativeType<T>> void main(
final String[] args) throws IOException
{
System.out.println(System.getProperty("user.dir"));
// create an instance of imagej
final ImageJ ij = new ImageJ();
// launch it
ij.launch(args);
// get an image
Dataset dataBridge = (Dataset) ij.io().open("../../images/bridge.tif");
ImgPlus<T> impBridge = (ImgPlus<T>) dataBridge.getImgPlus();
// convert to float
RandomAccessibleInterval<FloatType> img = ij.op().convert().float32(
impBridge);
ij.ui().show(img);
// create a kernel
RandomAccessibleInterval<T> kernel = (RandomAccessibleInterval<T>) ij.op()
.create().kernelGauss(4.0, 4.0);
// pad image to next valid FFT size.. there is currently an op matching bug so
// the namespace call doesn't work...
// img = ij.op().filter().padFFTInput(img, img);
// so run the pad op directly
img = Views.zeroMin((RandomAccessibleInterval<FloatType>) ij.op().run(
PadInputFFTMethods.class, img, img));
// now pad the kernel... note we also need to shift the kernel so the center is at 0,0
// there is an op that pads to next valid FFT size and shifts at the same time
kernel = Views.zeroMin(ij.op().filter().padShiftFFTKernel(kernel, img));
// create an image for the output
RandomAccessibleInterval<FloatType> convolved = ij.op().copy().rai(img);
// take the FFT of the kernel
RandomAccessibleInterval<ComplexFloatType> kernelFFT = ij.op().filter().fft(
kernel);
// now we can call convolve with parameters
// convolved (output)
// img (input)
// img (dummy variable for kernel, we should be able to pass null in for this someday)
// ij.op().copy().rai(kernelFFT), buffer for the img FFT
// kernelFFT - the pre-computed kernel FFT
// true - indicates we need to do FFT on the image
// false - indicates we don't need to do FFT on the kernel (because it was already computed)
ij.op().filter().convolve(convolved, img, img, ij.op().copy().rai(
kernelFFT), kernelFFT, true, false);
ij.ui().show(convolved);
// need to unpad as well...
System.out.println("finished");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment