Python 图像处理:如何对齐已旋转和移位的图像?

问题描述

这里我有一些代码可以垂直和水平移动图像,以便特定功能可以对齐(归功于 https://stackoverflow.com/a/24769222/15016884):

def cross_image(im1,im2):
    im1_gray = np.sum(im1.astype('float'),axis=2)
    im2_gray = np.sum(im2.astype('float'),axis=2)

    im1_gray -= np.mean(im1_gray)
    im2_gray -= np.mean(im2_gray)

   
    return signal.fftconvolve(im1_gray,im2_gray[::-1,::-1],mode='same')

corr_img_null = cross_image(cloud1,cloud1)
corr_img = cross_image(cloud1,cloud2)

y0,x0 = np.unravel_index(np.argmax(corr_img_null),corr_img_null.shape)
y,x = np.unravel_index(np.argmax(corr_img),corr_img.shape)
  
ver_shift = y0-y
hor_shift = x0-x

print('horizontally shifted',hor_shift)
print('vertically shifted',ver_shift)

#defining the bounds of the part of the images I'm actually analyzing
xstart = 100
xstop = 310
ystart = 50
ystop = 200

crop_cloud1 = cloud1[ystart:ystop,xstart:xstop]
crop_cloud2 = cloud2[ystart:ystop,xstart:xstop]
crop_cloud2_shift = cloud2[ystart+ver_shift:ystop+ver_shift,xstart+hor_shift:xstop+hor_shift]

plot_pos = plt.figure(5)
plt.title('image 1')
plt.imshow(crop_cloud1)

plot_pos = plt.figure(6)
plt.title('image 2')
plt.imshow(crop_cloud2)

plot_pos = plt.figure(7)
plt.title('Shifted image 2 to align with image 1')
plt.imshow(crop_cloud2_shift)

结果如下:

image1

image2

shifted image 2 to align with image 1

现在,我想使用下面显示的示例,其中除了平移之外还需要旋转来对齐图像中的特征。

bolt1

bolt2

这是我的代码:想法是将图像 2 的每个可能配置从 -45 到 45 的每个角度进行卷积(对于我的应用程序,这个角度不太可能被超过)并找到坐标和旋转使卷积最大化的角度。

import cv2

def rotate(img,theta):
    (rows,cols) = img.shape[:2]

    M = cv2.getRotationMatrix2D((cols / 2,rows / 2),theta,1)
    res = cv2.warpAffine(img,M,(cols,rows))
    return res

#testing all rotations of image 2
corr_bucket = []
for i in range(-45,45):
    rot_img = rotate(bolt2,i)
    corr_img = cross_image(bolt1,rot_img)
    corr_bucket.append(corr_img)
corr_arr = np.asarray(corr_bucket)


corr_img_null = cross_image(bolt1,bolt1)


y0,corr_img_null.shape)
r_index,y1,x1 = np.unravel_index(np.argmax(corr_arr),corr_arr.shape)

r = -45+r_index
ver_shift = y0-y
hor_shift = x0-x
ver_shift_r = y0-y1
hor_shift_r = x0-x1

#What parts of the image do you want to analyze
xstart = 200
xstop = 300
ystart = 100
ystop = 200

crop_bolt1 = bolt1[ystart:ystop,xstart:xstop]
crop_bolt2 = bolt2[ystart:ystop,xstart:xstop]
rot_bolt2 = rotate(bolt2,r)
shift_rot_bolt2 = rot_bolt2[ystart+ver_shift_r:ystop+ver_shift_r,xstart+hor_shift_r:xstop+hor_shift_r]

plot_1 = plt.figure(9)
plt.title('image 1')
plt.imshow(crop_bolt1)

plot_2 = plt.figure(10)
plt.title('image 2')
plt.imshow(crop_bolt2)

plot_3 = plt.figure(11)
plt.title('Shifted and rotated image 2 to align with image 1')
plt.imshow(shift_rot_bolt2)

不幸的是,从最后一行开始,我收到错误 ValueError: zero-size array to reduction operation minimum which has no identity。我对 python 有点陌生,所以我真的不知道这意味着什么,或者为什么我的方法不起作用。我有一种感觉,我的错误是在解开 corr_arr 的某个地方,因为它返回的 x、y 和 r 值我已经可以看到,仅通过估计,不会使闪电对齐。有什么建议吗?

解决方法

问题来自将整个旋转图像输入 scipy.signal.fftconvolve。旋转后裁剪 image2 的一部分以用作“探测图像”(以相同的方式裁剪未旋转的图像 1),并且我在问题中编写的代码工作正常。