Skip to main content

Image correlation


I have two images from motor scan, Image1 is shifted by MxN pixels from Image2. How can I find the shift between Image1 and Image2 ?


Image -1 1 Image -2 2


If we compare the shift between the images in terms of {X,Y} I will be able to tell how many steps of the motor scan corresponds to the pixel shift on the image array sensor.




Answer



There are many different image registration algorithms, all with different advantages and disadvantages. But I usually try the simplest choice first: I simply pass the two images to ImageCorrelate.


img1 = Import["http://i.stack.imgur.com/laZeT.png"];
img2 = Import["http://i.stack.imgur.com/LAHyF.png"];
corr = ImageAdjust[ImageCorrelate[img1, img2, EuclideanDistance]]

enter image description here


Intuitively, ImageCorrelate shifts img2 by every possible offset, calculates the difference with img1 with that offset, and stores the difference in the output image. So the pixel location with the lowest value in this image corresponds to the offset that minimizes the difference:


minOffset = PixelValuePositions[corr, Min[ImageData[corr]]][[1]] - 
ImageDimensions[img1]/2;

FlipView[{ImageTransformation[img1, TranslationTransform[minOffset ],
PlotRange -> Full], img2}]

enter image description here


If you look at the result of ImageCorrelate, you can see that there's one global minimum. That's the offset where the "U" shapes in the two images are aligned. There's a second local minimum left of it; That's probably where the left "leg" of one U is aligned with the right leg of the other. The shape of the correlation function around the global minimum and the relative correlation values at the local minima give a qualitative impression of the accuracy and reliability of the alignment.


EuclideanDistance compares brightness values. So the different overall brightness in the two images can "move" the minimum. If you don't want that, you can apply a filter to the images that basically removes the low-frequency background lighting changes:


filter = LaplacianGaussianFilter[#, 25] &;
corr = ImageAdjust[
ImageCorrelate[filter[img1], filter[img2], CosineDistance]]


enter image description here


(where 25 is roughly the width of the U-shape. Details smaller than that and low-frequency changes larger than that are removed by the LoG filter.)


Comments

Popular posts from this blog

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Mathematica: 3D plot based on combined 2D graphs

I have several sigmoidal fits to 3 different datasets, with mean fit predictions plus the 95% confidence limits (not symmetrical around the mean) and the actual data. I would now like to show these different 2D plots projected in 3D as in but then using proper perspective. In the link here they give some solutions to combine the plots using isometric perspective, but I would like to use proper 3 point perspective. Any thoughts? Also any way to show the mean points per time point for each series plus or minus the standard error on the mean would be cool too, either using points+vertical bars, or using spheres plus tubes. Below are some test data and the fit function I am using. Note that I am working on a logit(proportion) scale and that the final vertical scale is Log10(percentage). (* some test data *) data = Table[Null, {i, 4}]; data[[1]] = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 1.0}, {1, -6.8}, {2, -4.7}, {3, -1....