Correct 3D drift artifact

Dear all,

I am having an interesting issue when using Correct 3D drift. It seems to do its job fine, however, it is filling the frame with what straight lines radiating from the original image. An example below:

On the right of the image is my sample. Radiating from it in straight lines to the left of the image is the artifact.
It only happens if I have the option “Sub pixel drift correction (possibly needed for slow drifts)?” selected.
I am running Correct 3D drift as a script. I am using the script found at:

Is there a way for me to avoid this artifact? Is there something wrong with Correct 3D Drift?

Thank you all in advance,


This artifact is caused by the use of Views.extendBorder() here:

You can use any Out-of-bounds strategy (see the javadoc for the Views class) for the undefined regions of your image when translating. Replacing that line by:

extended = Views.extendZero(img)

gets rid of the artifact and fills the “empty” space with zero-value pixels.

I opened a pull request to change this:

Note that if you observe jumps or unexpected large drifts, there might also be a problem in calculating the phase correlation between subsequent images.


Thanks for the fast answer!
I replaced the line with:

extended = Views.extendZero(img)

The artifact is gone, but it does not do a good job of correcting the drift anymore. The end image ends up with bigger drift than what it had before processing. I don’t have big jumps in my stack, just a somewhat constant drift going towards the right of the image. Can I change something else to get the zero fill and still get a good correction?



The zero fill is fully independent from your correction.

That’s what I meant: if you’d had a good correction in the first place, you probably wouldn’t even have spotted the border artifacts, because your images wouldn’t have moved that far.

You can try to do some preprocessing (e.g. smoothing) to avoid that the algorithm tries to align the noise in your movie.

Also have a look at this other thread:

In particular, I’d like to quote @Christian_Tischer:

1 Like

@imagejan: I merged your changes; thanks for that!

@Buono: Indeed, It would be great to see your data.

In general, the algorithm is very noise sensitive!

To fight this, I added a new option called:

Only consider pixels with values larger than: 0

If you find a value in your images that clearly distinguishes background noise from the actual structures, you should put it here. It can help a lot!

Let me know how it goes!


@imagejan and @Christian_Tischer
Thank you for the help.

I have tried the new version and it worked fine.

I think I misunderstood your comment before. I apologize. I have a sample that always moves away from the field of view. So I have a good few microns of movement between each frame. What I generally don’t have are big sudden jumps. In a normal post drift correction situation I end up with a much bigger image than the one I started simply because my sample steadily moved away from my field of view.

Thank you for this. It did help, and it will help a lot in the future.

I had problems attaching an example stack here, so I have sent you a message with a download link.

1 Like

I tried your image and the drift correction worked well, using a value of 7000 gray values in terms of distinguishing background from foreground. Also, to speed up the computation I put a ROI onto the image as shown below (you have to put the ROI, before you start the script):

What I will do if I find the time is to also add an option to restrict the z-slices from which to compute the drift as this will massively speed up the processing!


OK; if you update Fiji you should now have the possibility to select a subset of the z-planes.

This has two advantages:

  • you can more precisely say which part of the image you actually want to stabilize (in case different parts of the image move differently)
  • it will speed up the registration, because the correlation will be computed on less data

I tried it and it did a great job! Faster and better correction.
Thank you so much for these changes.

Since my samples tend to grown away of the field of view, is it possible to add rotation correction?


Please send me an example data set, where you also experience rotation.

In fact, I am already working on 3-D time-lapse registration including rotation correction, so chances are quite good that I can help you.



That is great!
I sent you a links to a couple of datasets.

Why do I not see these new options in my Correct 3d drift plugin? I have updated Imagej.

Hi @David,

As Christian said, you must update your FIJI, rather than ImageJ (Help > Update…, not Help > Update ImageJ). Is this what you did?



Yes, that’s what I always do to update plugins. I have Correct_3D_Drift-1.0.1.jar in my plugins catalogue. Can’t really tell if this the latest one or not. Either way, the options don’t show up.

Hi All,

My current understanding is that Correct 3D Drift is not updated (see issue below):

I think the only way right now would be to copy and paste the actual code into your script editor and save it locally on your computer:

@ctrueden: is it correct what I am saying here?

Ok, thanks for the info. Doesn’t work for me though, it throws an error:

at org.scijava.minimaven.MavenProject$XMLHandler.endElement(
at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.scijava.minimaven.MavenProject.parse(
at org.scijava.minimaven.BuildEnvironment.parse(
at org.scijava.thread.DefaultThreadService$
at java.util.concurrent.ThreadPoolExecutor.runWorker(
at java.util.concurrent.ThreadPoolExecutor$

I used Plugins->New->Plugin, pasted the code and saved as .java. Installed the plugin and restarted. Maybe not the correct way?

you have to save it as “python”.
does that work?

Cant chose filetype. Should I just name it .py and then install it?

Edit: Didn’t work. Am I in the wrong editor?
Edit2: Was using the wrong editor. Works to run the plugin manually now. Thanks!

I would really like if Correct 3D drift could also compesate for rotation, like someone mentioned above! Also, what is the idea behind the option to only save vectors? There does seem to be an option to load vectors.

1 Like

Hi @David
I hope I am not confusing things here, but take a look at this topic. @Christian_Tischer seems to be already brewing something nice that can take care of rotations.


That’s right. However might take some time.

@David: For now you could try this for correcting rotations:

This worked for @Buono, did it?

1 Like