Skip to content

Commit

Permalink
0.0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
ekatrukha committed May 31, 2023
1 parent 8dc1057 commit 7307d5e
Show file tree
Hide file tree
Showing 8 changed files with 641 additions and 66 deletions.
40 changes: 38 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,40 @@
# RegisterNDFFT

Registration of ND images using FFT.
Work in progress.
Registration of ND (2/3/4D) images using FFT.
Work in progress, use at your own risk.

This plugin uses masked normalized cross-correlation calculation according to the paper:
_D. Padfield, “[Masked object registration in the Fourier domain](https://doi.org/10.1109/TIP.2011.2181402)” IEEE Transactions on Image Processing (2012)._
So basically it can account (exclude) image values that are zero and does not need arbitrary image padding during fast CC calculation using FFT.

To install it, you need to copy jar file from the [latest release](https://github.com/ekatrukha/RegisterNDFFT/releases) to jar folder of your [FIJI](https://fiji.sc/) installation. The plugin commands should appear in the _Plugins->ARegisterNDFFT_ menu (it starts with an extra A letter).

The plugin works with 2D/3D/multichannel images.

## Single template registration

This command registers template image(dataset) to the reference image using rigid translation (in all axis).
The precision of registration is up to one voxel (subpixel is not available).
It is possible to limit the maximum shift of the template by a fraction of its size (in all dimensions).
In case of multi-channel images, only one user selected channel from each image will be used for the registration.


## Iterative registration

Provided with a set of opened in FIJI or stored on hard drive images of the same dimensions, the plugin will perform iterative registration/averaging.
At the initial step it will create an reference image as an average of input images (depending on initial template settings).
After that it will iteratively register input images to this average, update it, register again.
Depending on the number of iterations or convergence of average CC it will stop and show the final image.

## Pairwise CC

Given a set of input images, the plugin will pairwise calculate the maximum of cross-correlation among them.

----------

Developed in <a href='http://cellbiology.science.uu.nl/'>Cell Biology group</a> of Utrecht University.
<a href="mailto:katpyxa@gmail.com">E-mail</a> for any questions.




9 changes: 3 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
<parent>
<groupId>org.scijava</groupId>
<artifactId>pom-scijava</artifactId>
<version>30.0.0</version>
<version>34.0.0</version>
<relativePath />
</parent>

<groupId>sc.fiji</groupId>
<artifactId>RegisterNDFFT</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>0.0.3</version>

<name>RegisterNDFFT</name>
<description>Registration of ND images using FFT and imglib2. </description>
Expand Down Expand Up @@ -108,10 +108,7 @@
<groupId>net.imglib2</groupId>
<artifactId>imglib2-realtransform</artifactId>
</dependency>
<dependency>
<groupId>net.imglib2</groupId>
<artifactId>imglib2-ui</artifactId>
</dependency>


<!-- ImageJ dependencies -->
<dependency>
Expand Down
15 changes: 11 additions & 4 deletions src/main/java/fiji/plugin/RegisterNDFFT/AverageWithoutZero.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.util.ArrayList;

import ij.IJ;
import ij.ImagePlus;

import ij.WindowManager;
import ij.plugin.PlugIn;
import net.imglib2.Cursor;
Expand Down Expand Up @@ -62,6 +62,7 @@ public void run(String arg0) {
averagedIP.show();
*/
}
/** returns an interval that encompasses all RAIs in the input ArrayList **/
public static FinalInterval getIntervalAverageArray(ArrayList<RandomAccessibleInterval< FloatType >> imgs)
{
int i,j;
Expand Down Expand Up @@ -100,7 +101,7 @@ public static FinalInterval getIntervalAverageArray(ArrayList<RandomAccessibleIn
public static IntervalView<FloatType> averageArray(ArrayList<RandomAccessibleInterval< FloatType >> imgs)
{
int i;
int nDim = imgs.get(0).numDimensions();
//int nDim = imgs.get(0).numDimensions();

FinalInterval intervalMax = getIntervalAverageArray(imgs);

Expand Down Expand Up @@ -147,7 +148,11 @@ public static IntervalView<FloatType> averageArray(ArrayList<RandomAccessibleInt

}


/** Provided with an ArrayList of RAI, returns a new ArrayList with two RAIs:
* the first contains sum of all intensities at a current voxel/pixel location,
* the second contains an integer equal to how many RAIs have a pixel at this location.
* Since input RAIs could be of different sizeslocations, the output size is made to include
* all of them, i.e. hyper box that includes them all **/

public static ArrayList<IntervalView<FloatType>> sumAndCountArray(ArrayList<RandomAccessibleInterval< FloatType >> imgs)
{
Expand Down Expand Up @@ -207,7 +212,9 @@ public static ArrayList<IntervalView<FloatType>> sumAndCountArray(ArrayList<Rand
return finalSumCnt;

}

/** returns an average RAI provided ArrayList with two RAIs:
* first being intensity values and the second is count number.
* Checks for zero counts and returned RAI origin is at zeros. **/
public static IntervalView<FloatType> averageFromSumAndCount(ArrayList<IntervalView<FloatType>> alSumCnt)
{

Expand Down
35 changes: 32 additions & 3 deletions src/main/java/fiji/plugin/RegisterNDFFT/GenNormCC.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@ public class GenNormCC {
/** whether to log results to IJ.log window **/
public boolean bVerbose = true;

/** **/

/** whether to exclude/ignore voxels that are zeros **/
public boolean bExcludeZeros = false;

/** whether to look for the zero with X shift = 0,
* needed for rotation registration **/
public boolean bZeroX = false;


/**
* @param image
Expand Down Expand Up @@ -293,7 +296,33 @@ public boolean caclulateGenNormCC(final RandomAccessibleInterval< FloatType > im

//now find max value
Point shift = new Point(nDim);
FloatType fCCvalue = MiscUtils.computeMaxLocation(ivCCswapped,shift);
FloatType fCCvalue;
if(!bZeroX)
{
fCCvalue = MiscUtils.computeMaxLocation(ivCCswapped,shift);
}
else
{
//Point shiftZeroX =new Point(nDim-1);
long [] minX = ivCCswapped.minAsLongArray();
long [] maxX = ivCCswapped.maxAsLongArray();
minX[0]=0;
maxX[0]=0;
//minX[1]=-179;
//maxX[1]=180;
FinalInterval valX = new FinalInterval(minX,maxX);
//ImageJFunctions.show(Views.interval(ivCCswapped, valX)).setTitle( "XZero" );

fCCvalue = MiscUtils.computeMaxLocation(Views.interval(ivCCswapped, valX),shift);
/*
//ImageJFunctions.show(Views.hyperSlice(ivCCswapped, 0, 0)).setTitle( "XZero" );
//fCCvalue = MiscUtils.computeMaxLocation(Views.hyperSlice(ivCCswapped, 0, 0),shiftZeroX);
for(i=1;i<nDim;i++)
{
shift.setPosition(shiftZeroX.getLongPosition(i-1), i);
}
*/
}

if (bVerbose)
{
Expand Down
Loading

0 comments on commit 7307d5e

Please sign in to comment.