OrientationJ or similar for Python

Dear all,

in our Lab we use OrientationJ to determine the rotation angle of microscope images that exhibit a periodic structure in order to align them.
An example ImageJ macro is this:

// REGISTER TO FIRST FRAME AND FIRST CHANNEL
print("Computing angle...");
setBatchMode(false); // OrientationJ fails in Batch mode (process ultimately gets killed)
Stack.setFrame(1);
Stack.setChannel(1);
run("Duplicate...", "title=first");
run("OrientationJ Analysis", "log=0.0 tensor=10.0 gradient=0 hsb=off orientation=on radian=off ");

close(); // close HSB color-survey
// find the mode of this orientation image
getHistogram(values, counts, 10000);
close(); // close orientation image
rks = Array.reverse( Array.rankPositions(counts) );
angle = values[ rks[1] ];

I am in the process of implementing our analysis in Python and looking to achieve something similar.
Is there a port of OrientationJ for Python?

Below is an example image showing the periodic structure that I want to align (microfluidic channels; this is a rather extreme example of misalignment). Note that I have also tried alternative methods (Fourier transform based), but I was unabel not reached the accuracy achieve by OrientationJ, which I why I am looking for something similar under Python.

1 Like

Hi Michael,

You could checkout the optical flow algorithms in the skimage registration module:

scikit-image registraton
skimage registration example

~Chris

Hi Michael,

you can achieve a very similar output, as OrientationJ, using the skimage structure tensor implementation:

def dominant_direction(img, sigma):
    """OrientationsJ's dominant direction"""
    axx, axy, ayy = feature.structure_tensor(
        img.astype(numpy.float32), sigma=sigma, mode="reflect"
    )
    dom_ori = numpy.arctan2(2 * axy.mean(), (ayy.mean() - axx.mean())) / 2
    return numpy.rad2deg(dom_ori)


def orientation_analysis(img, sigma):
    """OrientationJ's output for
    * orientation
    * coherence
    * energy
    """
    eps = 1e-20

    axx, axy, ayy = feature.structure_tensor(
        img.astype(numpy.float32), sigma=sigma, mode="reflect"
    )
    l1, l2 = feature.structure_tensor_eigvals(axx, axy, ayy)
    ori = numpy.arctan2(2 * axy, (ayy - axx)) / 2

    coh = ((l2 - l1) / (l2 + l1 + eps)) ** 2
    ene = numpy.sqrt(axx + ayy)
    ene /= ene.max()

    return ori, coh, ene

You could use the histogram of ori to find the maximum orientation, similar to your imageJ script.

Chris

4 Likes

Thank you Chris. :ok_hand: :+1: