Stackreg affine transformation issue

I am trying to use stackreg to essentially shear hundreds of SEM FIB images at 52 degrees but I am having trouble getting it to work right. I load the image, click on stackreg in the plugin menu and select affine transformation. Every time I run it nothing seems to be happening and it won’t let me enter in specific values for how I want to alter the image it just cycles through the whole stack without altering the images.

I don’t think its an issue of the software but more of me not using it correctly. Anyone have any ideas of what I should be doing or other programs that can perform a simple y image shear at 52 degrees? If this problem has already been solved I apologize.

Apologies for the long delay in reply to your question, @polo729.

Unfortunately, the author of StackReg does not frequent this forum, nor answer questions about it on the mailing list. You could try writing him a private mail. Though for several reasons, I would suggest finding a different tool to accomplish your task.

Do you just need to shear planewise? If so, I started working on a script to do that which uses ImgLib2. But I ran into some trouble so I made another forum post about it. Also, in the relatively near future, the ImageJ Ops library will provide the ability to do shearing in an easier way.

My mistake in the other thread was kindly pointed out by @hanslovsky, so here is a working Groovy script that shears an image by a given factor:

// @DatasetService datasetService
// @Img image
// @double(label="Shearing factor", value=1) factor
// @OUTPUT Dataset result

import net.imglib2.interpolation.randomaccess.NLinearInterpolatorFactory
import net.imglib2.realtransform.AffineTransform2D
import net.imglib2.realtransform.RealViews
import net.imglib2.view.Views

// extend the image with zeroes
extended = Views.extendZero(image)

// decide how we want the image to be interpolated
field = Views.interpolate(extended, new NLinearInterpolatorFactory())

// shear the image
affine = new AffineTransform2D()
affine.set([[1, factor, 0], [0, 1, 0], [0, 0, 1]] as double[][])
sheared = RealViews.affine(field, affine)

// apply the original bounding box to the sheared image
bounded = Views.interval(sheared, image)

// convert the result to an ImageJ dataset
result = datasetService.create(bounded)

Of course, you could:

A) Replace the affine matrix with whatever you need; and
B) Change the bounded = to whatever bounds you want.

Regarding (B), off the top of my head, I am not sure the easiest way to select the minimum bounding box such that no samples are lost, but no zero-padding is present. I guess since it’s affine, you could multiply the four corner coordinates by the transform and then use the min and max x and y values. We should probably add something like that to ImgLib2 and/or ImageJ Ops if it is not already present somewhere.

1 Like