SubpixelRegistration.jl

Code Build Status PkgEval Coverage License

Image registration with subpixel precision using an upsampled discrete Fourier transform cross-correlation. This uses an efficient matrix-multiplication algorithm for upsampling the cross-correlation following Guizar-Sicairos, Thurman, and Fienup (2008).[1]

Installation

julia>] add SubpixelRegistration

Usage

using ColorTypes
using ImageIO
using ImageShow
using SubpixelRegistration
using TestImages

image = testimage("cameraman")
Pixel Convention

The pixel convention adopted here is that the bottom-left pixel center is (1, 1). The column-major memory layout of julia puts the x axis as the rows of a matrix and the y axis as the columns. In other words, the shifts are described by (dx, dy). This is the same pixel convention as FITS, WCS, DS9, IRAF, and SourceExtractor.

shift = (22.4, -13.32)
source = Float64.(image)
shifted = fourier_shift(source, shift)
Gray.(shifted)
phase_offset(source, shifted; upsample_factor=1)
(shift = (-22.0, 13.0), error = 0.0015731721779352892, phasediff = 0.0)
phase_offset(source, shifted; upsample_factor=100)
(shift = (-22.4, 13.32), error = -6.8719210830796844e10, phasediff = 0.0)
registered = register(source, shifted; upsample_factor=100)
Gray.(registered)

Benchmarks

This code has been benchmarked against the scikit-image implementation. This benchmark is a measure of the time it takes to measure the offset between two images with various sizes and with various upsample factors. The number of pixels scales with the square of the size, describing the non-linear power law.

System Information

julia> versioninfo()
Julia Version 1.8.0-beta2
Commit b655b2c008 (2022-03-21 12:50 UTC)
Platform Info:
  OS: macOS (arm64-apple-darwin21.3.0)
  CPU: 10 × Apple M1 Max
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, apple-m1)
  Threads: 8 on 8 virtual cores

Benchmark Results

Contributing and Support

If you would like to contribute, feel free to open a pull request. If you want to discuss something before contributing, head over to discussions and join or open a new topic. If you're having problems with something, please open an issue.