我正在尝试使用opencv注册两个相互旋转和翻译版本的图像。一般来说,程序是(伪代码):
一个。 IF1 = FFT2( I1 ); IF2 = FFT2( I2 )
湾 R_translation =( IF1 )。*( IF2_conjugate )
℃。 R_translation = R_translation ./ abs( R_translation )
d。 r_translation = IFFT2( R_translation )
r_translation 的最大值对应于翻译。继续计算旋转,abs值将删除平移部分,
即 IF1_abs = abs( IF1 ); IF2_abs = abs( IF2 )
转换为线性 - 极坐标
F。 IF1_abs_pol = LINPOL( IF1_abs ); IF2_abs_pol = LINPOL( IF2_abs )
F。 IFF1 = FFT2( IF1_abs_pol ); IFF2 = FFT2( IF2_abs_pol )
F。 R_rot =( IFF1 )。*( IFF2_conjugate )
℃。 R_rot = R_rot ./ abs( R_rot )
d。 r_rot = IFFT2( R_rot )
其中 r_rotationn 的最大值对应于旋转。而对于单独的翻译,cv2.phaseCorrelate函数返回预期结果,对于旋转,它返回奇数结果。所以我尝试了以下内容。
我拿了两个numpy.array-s 5x5,它们是彼此的旋转版本,如下所示:
a = numpy.array([[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]])
a = a.astype('float')/a.astype('float').max()
b = numpy.array([[5, 5, 5, 5, 5], [4, 4, 4, 4, 4], [3, 3, 3, 3, 3], [2, 2, 2, 2, 2], [1, 1, 1, 1, 1]])
b = b.astype('float') / b.astype('float').max()
首先我自己计算了相位相关性:
center_x = numpy.floor(a.shape[0] / 2.0)#the x center of rotation (= x center of image)
center_y = numpy.floor(a.shape[1] / 2.0)#the y center of rotation (= y center of image)
Mvalue = a.shape[1] / numpy.sqrt(
((a.shape[0] / 2.0) ** 2.0) + ((a.shape[1] / 2.0) ** 2.0)) # rotation radius
计算FFT,取绝对值(如果存在则丢失平移差异数据),并切换到线性极坐标并进行标准化:
a_polar = cv2.linearPolar(numpy.abs(numpy.fft.fft2(a)), (center_x, center_y), Mvalue, cv2.WARP_FILL_OUTLIERS)
b_polar = cv2.linearPolar(numpy.abs(numpy.fft.fft2(b)), (center_x, center_y), Mvalue, cv2.WARP_FILL_OUTLIERS)
a_polar = a_polar/a_polar.max()
b_polar = b_polar / b_polar.max()
另一个FFT步骤,逐点乘以IFFT:
aff = numpy.fft.fft2(a_polar)
bff = numpy.fft.fft2(b_polar)
R = aff * numpy.ma.conjugate(bff)
R = R / numpy.absolute(R)
r = numpy.fft.ifft2(R).real
r = r/r.max()
产量, Phase correlation for rotation, b with respect to a
根据cv2.linearPolar()行,跨越角度(在这种情况下,步长为360/5 = 72度),列跨越半径(从0到Mvalue中给出的最大半径。最大值为在最后一排显而易见(对应于大约-90度的转变)。到目前为止一直很好......
第二种方法是直接使用cv2.phaseCorrelate(),
r_direct = cv2.phaseCorrelate(a_polar, b_polar)
产生,
Phase correlation for rotation, b with respect to a direct method
第一个元组是X,Y相关系数(以像素为单位?),第三个数字是拟合等级。当它接近于1时,相关系数表示数据更好(最大值周围的斑点更明显)。
除了结果不够明显(为什么?)之外,结果令人困惑......
通常,此5x5示例中的第一个FFT过程不是必需的。如果旋转是唯一的干扰,可以立即切换到线性极坐标并使用cv2.phaseCorrelate。在这种情况下,结果也令人困惑。
任何帮助将不胜感激:)
谢谢!
大卫