使用opencv进行轮换注册的相位相关

时间:2017-09-27 20:39:23

标签: python opencv rotation

我正在尝试使用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。在这种情况下,结果也令人困惑。

任何帮助将不胜感激:)

谢谢!

大卫

0 个答案:

没有答案