python - How to estimate a sub-pixel shift between images with non uniform translation/rotation
问题描述
I have several images which are fully overlapping the same scene. But there is a small shift between all the images, something like 1px or less, so a sub-pixel shift. Let's say it's the problem (1): how can I estimate this sub-pixel shift between 2 images (actually, I know how and I write the code about this below). I used python here.
In addition to problem (1), there is the problem (2) which is about a non uniform shift on the full image. Let's give image A and image B, on the top left, image A is shifted about 1px from image B in x and y axis but, on the center, image A is shifted in 0.5px from image B also in x and y axis. The shift between image A and B is not uniform among the total surface of the image. The problem is how can I estimate this non-uniform shift, let's nammed it a shifted surface, for all the pixels for all images (taking one as reference) (I have a solution also for this question, I will explain it below).
Finally, problem (3) is about to shift the image with the estimated shift surface (calculated on (2)). I know how to shift an image to 0.5 px on X-axis and 1.2 px on Y-axis for example. But I don't know how to shift an array with a specific shift for each pixel.
My solutions:
Problem (1): This problem can be solved using a cross-correlation in fourrier space. A function already existe in the scipy library : register_translation
reference here, I just need to give two images as parameters and the float precision I want.
Problem (2): Remember, the shift is not uniform among all the surface of the image. What I did, is basically, on window of 500x500 px, the shift is uniform and can be easily estimated from problem (1). So, I calculated the shift among all the surface of the image with window of 500x500px and a step of 100px. I have thus now, the non uniform shift estimated as shown below . I can then, interpolate a surface from this ponctual estimated shift, which will give me an estimated shift for each pixel of the image. To do that, I have to interpolate a surface with the same resolution of the image. I did it, using numpy.griddata
. Here is the result for both components (x and y) . I have thus, estimated the non uniform shift among all the surface of the image.
Problem (3): I now want to apply this shift to all the image. I don't know how to do that. To shift an image at sub-pixel, you can use a function from scipy.ndimage
nammed fourier_shift
that you can find here but you can only give a single shift for all the image. Here, I want to give a shift for each pixel of the image.
Do you guys have any ideas to solve the problem (3) ? Also, if you think that there is a simpliest way to solve Problem 1 and 3, it can still be usefull ! For information, I have 7 images of 16000x26000px, so it take some time to solve Problem (2) as I do.
解决方案
您现在需要在位置插入原始图像(x + x_shift(x,y), y + y_shift(x,y))
。可能scipy.interpolate.interpn是最有效的方法。
我认为您的代码看起来像这样(未经测试):
import numpy as np
import spicy
# ... (load data, find shifts, etc.)
input_coords = (np.arange(x_size), np.arange(y_size))
output_coords = np.column_stack((
( x_shift + input_coords[0] ).ravel(),
( y_shift + input_coords[1][None,:] ).ravel() ))
output_image = scipy.interpolate.interpn(input_coords, original_image, output_coords,
method='linear', bounds_error=False)
推荐阅读
- javascript - 如何增加属性的值(整数)并在猫鼬中使用一些限制进行更新?
- haskell - 在 haskell 标准输入上处理箭头键 ANSI 转义序列
- python - 可以在 Python ctypes 中需要 Windows 句柄的地方传递整数吗
- wordpress - Wordpress:为没有管理员用户隐藏“每页的项目数”选项
- android - 如何将 ImageView 从一个活动更改为另一个活动?
- regex - 正则表达式 - 压缩空格并删除名称中的点
- c# - 有没有办法在代码隐藏中设置容器的第 n 个孩子的样式?
- azure-web-app-service - 使用 ARM 模板添加插槽
- c++ - 管理每个对象的静态计数器变量
- automation - 使用 AppleScript 或 JAX 从 macOS Finder 复制 iPhone 文件