Register pixel shift in 2 channel images of beads

I have a 2 channel z-stack of beads that show some shift between them and am looking for the best way to (i) register the two images in 3D and (ii) save and apply this transformation to any other images that suffer from the same pixel shift.

I have tried descriptor based registration, but am not able to find the proper settings. I tested Rigid and Affine with a high number of neighbors and redundancy, but always received:

Not enough candidates 0 - No inliers found Tipp: You could increase the number of neighbors, redundancy or use a model that has more degrees of freedom.

Does somebody have a tip how to make the plugin work, or maybe an alternative solution to the problem?

Did you check that you find enough canditates in the interactive mode of the plugin (for finding minima and maxima in one of the input images)? I.e. what’s the count reported in the log line:

Found XXX candidates for C1-tetrabeads_100nm_power_100_exp_150ms_1_w1confmCherry-2.tif [0] (XXX maxima, 0 minima)

One drawback of the Descriptor-based registration plugin is that it assumes the same threshold for detecting descriptors in both channels, so it usually fails when the channels are too different in intensity/contrast.

For these cases, I took the different parts of the plugin and wrapped each of them as #knime nodes available from the FMI KNIME Plugins update site:

  • Spot Detection (Subpixel localization) (actually from #trackmate)
  • Measure 3D Transformation Between Spots
  • Apply 3D Affine Transform

This allows you to run spot detection with different parameters on both channels, while still having a handy way to apply channel correction.

I can try to put together an example workflow when I find the time.


amazing as per usual @imagejan, thank you! :slight_smile:

I found candidates, but the numbers were never the same, e.g. 36 and 42, depending on how I set the thresholds. So indeed as you say the two channels are not of equal quality, and that could be what throws the plugin off.

That would be absolutely fantastic! Thank you very much! :star_struck:

I finally got around to put together a small illustrative #knime workflow as a side-product of my work at #fmi-basel, using the bead images you shared.

Here it is:

Channel correction.knwf (79.7 KB)

You’ll need to add the FMI KNIME Plugins update site:

… and if you’d like to see the R plots (using ggplot2), you need to point your KNIME to an up-to-date R installation with the required packages (ggplot2, tidyr, dplyr) installed.

Here are the orthogonal (xy, xz, zy) plots of the bead coordinates (only inliers), as produced by the R View nodes in the workflow:

  • before correction:

  • and after correction:

Hope that helps.

The workflow is now available from NodePit Space as well:


Dear Jan,

Thanks a lot for your help. I managed to run your workflow and I got good results. Then cellKai and I tried to apply the same affine transformation to another image. The idea is to use the bead images to correct the shift between two cells images. Therefore we modifed the workflow as shown in the screenshot attached

. Unluckily this is not working proeperly. Indeed when I try to join my channel 2 image with the affine transformation I get the warning

“Node created an empty data table.”

I believe it is a matter of matrix sizes, but this is the first time I use KNIME so I cannot make it work by myself. The Joiner node has the same settings of the one joining the bead image with the 3D transformation, since it should be doing the same task.

Does anyone have any suggestion?

From your screenshot, I conclude that it’s the Joiner node that issues this warning, right?

Please note that the Joiner in my original workflow is configured to join the rows by RowID, in order to join the correct transformation to the correct input images (in case you ever want to analyze multiple bead images and measure transformations in each pair of corresponding images).

In order to apply a single affine transformation matrix to any number of independent images, you should use the Cross Joiner to make sure that the affine matrix shows up in every row of the table.

(See here for some documentation of the concepts behind the Joiner and Cross Joiner nodes:

Hope that helps.

1 Like

Hi @imagejan

@jlacoste, @stelfrich and myself have been having discussions regarding a similar project. Our intention is to wrap some of the functionality in MetroloJ into Image2 commands which can be then be imported as KNIME nodes. An example is here.

Do you have a java repository where you keep your wrappers?? I didn’t see a link to that in the previous posts. I’m interested in looking at the code you’ve used to wrap parts of trackmate.

1 Like

Sure, sorry I hadn’t linked to it here yet.

The (headless-enabled) IJ2 plugins are here:

You can build this with mvn and install the jar file in KNIME’s ImageJ2 integration, but this requires that you also install all required dependencies manually as well.

To facilitate this process, @dietzc and @gab1one helped me at the time to set up a KNIME update site that bundles the fmi-ij2-plugins.jar and its dependencies, and gets built by KNIME’s Jenkins CI infrastructure:

NB: As you can see, this component only contains a DummyClass and otherwise specifies its dependencies in the .classpath:

1 Like