Python implementation of the ImageJ/FIJI Plugin TurboReg/StackReg
Project description
Summary
Python/C++ port of the ImageJ extension TurboReg/StackReg written by Philippe Thevenaz/EPFL.
A python extension for the automatic alignment of a source image or a stack (movie) to a target image/reference frame.
Description
pyStackReg is used to align (register) one or more images to a common reference image, as is required usually in time-resolved fluorescence or wide-field microscopy. It is directly ported from the source code of the ImageJ plugin TurboReg and provides additionally the functionality of the ImageJ plugin StackReg, both of which were written by Philippe Thevenaz/EPFL (available at http://bigwww.epfl.ch/thevenaz/turboreg/).
pyStackReg provides the following four types of distortion:
translation
rigid body (translation + rotation)
scaled rotation (translation + rotation + scaling)
affine (translation + rotation + scaling + shearing)
pyStackReg supports the full functionality of StackReg plus some additional options, e.g., using different reference images and having access to the actual transformation matrices (please see the examples below).
As in StackReg, bilinear transformation is not supported as bilinear transformation matrices cannot be propagated. For technical details, please refer to http://bigwww.epfl.ch/thevenaz/turboreg/.
Installation
The package is available on PyPi. Install it using:
pip install pystackreg
Documentation
The documentation can be found on readthedocs:
Usage
The following example opens two different files and registers them using all different possible transformations
from pystackreg import StackReg
from skimage import io
#load reference and "moved" image
ref = io.imread('some_original_image.tif')
mov = io.imread('some_changed_image.tif')
#Translational transformation
sr = StackReg(StackReg.TRANSLATION)
out_tra = sr.register_transform(ref, mov)
#Rigid Body transformation
sr = StackReg(StackReg.RIGID_BODY)
out_rot = sr.register_transform(ref, mov)
#Scaled Rotation transformation
sr = StackReg(StackReg.SCALED_ROTATION)
out_sca = sr.register_transform(ref, mov)
#Affine transformation
sr = StackReg(StackReg.AFFINE)
out_aff = sr.register_transform(ref, mov)
The next example shows how to separate registration from transformation (e.g., to register in one color channel and then use that information to transform another color channel):
from pystackreg import StackReg
from skimage import io
img0 = io.imread('some_multiframe_image.tif')
img1 = io.imread('another_multiframe_image.tif')
# img0.shape: frames x width x height (3D)
sr = StackReg(StackReg.RIGID_BODY)
# register 2nd image to 1st
sr.register(img0[0, :, :], img0[1,:,:])
# use the transformation from the above registration to register another frame
out = sr.transform(img1[1,:,:])
The next examples shows how to register and transform a whole stack:
from pystackreg import StackReg
from skimage import io
img0 = io.imread('some_multiframe_image.tif') # 3 dimensions : frames x width x height
sr = StackReg(StackReg.RIGID_BODY)
# register each frame to the previous (already registered) one
# this is what the original StackReg ImageJ plugin uses
out_previous = sr.register_transform_stack(img0, reference='previous')
# register to first image
out_first = sr.register_transform_stack(img0, reference='first')
# register to mean image
out_mean = sr.register_transform_stack(img0, reference='mean')
# register to mean of first 10 images
out_first10 = sr.register_transform_stack(img0, reference='first', n_frames=10)
# calculate a moving average of 10 images, then register the moving average to the mean of
# the first 10 images and transform the original image (not the moving average)
out_moving10 = sr.register_transform_stack(img0, reference='first', n_frames=10, moving_average = 10)
The next example shows how to separate registration from transformation for a stack (e.g., to register in one color channel and then use that information to transform another color channel):
from pystackreg import StackReg
from skimage import io
img0 = io.imread('some_multiframe_image.tif') # 3 dimensions : frames x width x height
img1 = io.imread('another_multiframe_image.tif') # same shape as img0
# both stacks must have the same shape
assert img0.shape == img1.shape
sr = StackReg(StackReg.RIGID_BODY)
# register each frame to the previous (already registered) one
# this is what the original StackReg ImageJ plugin uses
tmats = sr.register_stack(img0, reference='previous')
out = sr.transform_stack(img1)
# tmats contains the transformation matrices -> they can be saved
# and loaded at another time
import numpy as np
np.save('transformation_matrices.npy', tmats)
tmats_loaded = np.load('transformation_matrices.npy')
# make sure you use the correct transformation here!
sr = StackReg(StackReg.RIGID_BODY)
# transform stack using the tmats loaded from file
sr.transform_stack(img1, tmats=tmats_loaded)
# with the transformation matrices at hand you can also
# use the transformation algorithms from other packages:
from skimage import transform as tf
out = np.zeros(img0.shape).astype(np.float)
for i in range(tmats.shape[0]):
tform = tf.AffineTransform(matrix=tmats[i, :, :])
out[i, :, :] = tf.warp(img1[i, :, :], tform)
License
Below is the license of TurboReg/StackReg:
/*==================================================================== | Additional help available at http://bigwww.epfl.ch/thevenaz/turboreg/ | | You'll be free to use this software for research purposes, but you | should not redistribute it without our consent. In addition, we expect | you to include a citation or acknowledgment whenever you present or | publish results that are based on it. \===================================================================*/
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for pystackreg-0.1.1-cp36-cp36m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ab452b8ef7b371f8ec1bd0a2fa7802b978a4b8c827b1c9f36184c10333299adb |
|
MD5 | 011f315384f87aee355b392d1b4aa665 |
|
BLAKE2b-256 | 717b5c68a5b02f6bb25d83f162707ac9d8f876f82e4368625d772232366a375f |
Hashes for pystackreg-0.1.1-cp36-cp36m-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 297db135ce5df44bae918eb6dd149db3ef598dd784e1e34534a88e6134d990ed |
|
MD5 | 8379a0a6bdf55ea01f10c55dcaabf3d2 |
|
BLAKE2b-256 | 884aca8d36523f6309a64665c74223fe1e75c082f9ab9bd807390bf51f23128f |
Hashes for pystackreg-0.1.1-cp27-cp27m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f325232ed131713f64b50f84c11aa893eb0acf9c765e01699556991776f13813 |
|
MD5 | e7a591f7839f2f2f028ca26f9e4e492f |
|
BLAKE2b-256 | e6d4dbd35d7fb030ade00d8ad8b9b1c97739d601c72ba3f5563db4072c0a63d6 |
Hashes for pystackreg-0.1.1-cp27-cp27m-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0e497a4a0a8b98ebd2437c51b5f0ff086e46347394645e87d46cf2c7f87730eb |
|
MD5 | 118ae41c722804e97954ce212e17fb3d |
|
BLAKE2b-256 | 57a22b2ad84c880b3d1b386662b8fc974fe0158ffe169dbfba2ab5803bcbe601 |