如何检测图像之间的转换

SFB*_*A26 12 python image image-processing scipy

我正在分析多个图像,并且需要能够判断它们是否与参考图像相比发生了偏移.目的是告知相机在拍摄图像之间是否完全移动.理想情况下,我希望能够纠正移位以便仍然进行分析,但至少我需要能够确定图像是否被移位并且如果超出某个阈值则丢弃它.

以下是我想要检测的图像变化的一些示例:

参考图像转移图像1转移图像2

我将使用第一个图像作为参考,然后比较所有以下图像,以确定它们是否被移位.图像是灰度的(它们仅使用热图以彩色显示)并存储在2-D numpy阵列中.我有什么想法可以做到这一点?我更喜欢使用我已安装的软件包(scipy,numpy,PIL,matplotlib).

DrV*_*DrV 12

作为Lukas Graf提示,您正在寻找互相关.它运作良好,如果:

  1. 图像的比例不会发生很大变化.
  2. 图像中没有旋转变化.
  3. 图像中没有明显的光照变化.

对于普通翻译,互相关非常好.

最简单的互相关工具是scipy.signal.correlate.然而,它使用平凡的互相关方法,对于边长为n的二维图像,它是O(n ^ 4).在实践中,使用您的图像需要很长时间.

更好的太是scipy.signal.fftconvolve卷积和相关性是密切相关的.

像这样的东西:

import numpy as np
import scipy.signal

def cross_image(im1, im2):
   # get rid of the color channels by performing a grayscale transform
   # the type cast into 'float' is to avoid overflows
   im1_gray = np.sum(im1.astype('float'), axis=2)
   im2_gray = np.sum(im2.astype('float'), axis=2)

   # get rid of the averages, otherwise the results are not good
   im1_gray -= np.mean(im1_gray)
   im2_gray -= np.mean(im2_gray)

   # calculate the correlation image; note the flipping of onw of the images
   return scipy.signal.fftconvolve(im1_gray, im2_gray[::-1,::-1], mode='same')
Run Code Online (Sandbox Code Playgroud)

有趣的索引im2_gray[::-1,::-1]旋转180°(水平和垂直镜像).这是卷积和相关之间的差异,相关是与镜像的第二信号的卷积.

现在,如果我们只关联第一个(最顶层)图像与自身,我们得到:

在此输入图像描述

这给出了图像的自相似性的度量.最亮点位于(201,200),它位于(402,400)图像的中心.

可以找到最亮的点坐标:

np.unravel_index(np.argmax(corr_img), corr_img.shape)
Run Code Online (Sandbox Code Playgroud)

返回最亮像素的线性位置argmax,但必须将其转换回2D坐标unravel_index.

接下来,我们通过将第一个图像与第二个图像相关联来尝试相同的操作:

在此输入图像描述

相关图像看起来相似,但最佳相关性已移至(149,200),即图像中向上52像素.这是两个图像之间的偏移.


这似乎适用于这些简单的图像.但是,也可能存在错误的相关峰值,并且在本答案开头所述的任何问题都可能破坏结果.

无论如何,您应该考虑使用窗口函数.只要使用某些东西,功能的选择就不那么重要了.此外,如果您在旋转或缩放较小时遇到问题,请尝试将周围图像再次关联几个小区域.这将在图像的不同位置为您提供不同的位移.