图像配准之相位配准

基本原理

图像配准是图像处理的基本任务之一,用于将不同时间、不同传感器、不同视角及不同拍摄条件下获取的关于同一目标或场景的两幅或多幅图像进行主要是几何意义上的匹配套和的过程。图像配准的基本问题是找出一种图像转换方法,用以纠正图像的形变。造成图像形变的原因多种多样,例如对于遥感图像而言,传感器噪声、由传感器视点变化或平台不稳定造成的透视变化、被拍摄物体的移动、变形或生长等变化、闪电和大气变化,以及阴影和云层遮盖都使图像产生不同形式的形变。正是图像形变原因和形式的不同决定了多种多样的图像配准技术。
图像配准方法主要有互相关法、傅立叶变换法、点映射法口脚外和弹性模型法。其中傅立叶变换法基于傅立叶变换的相位匹配是利用傅立叶变换的性质而出现的一种图像配准方法。图像经过傅立叶变换,由空域变换到频率缘则两组数据在空何上的相关运算可以变为频谱的复数乘法运算,同时图像在变换域中还能获得在空域中很难获得的特征。原理如下图,利用了傅里叶变换的位移特性。
在这里插入图片描述

通过求取互功率谱的傅立叶反变换,得到一个狄拉克函数(脉冲函数),再寻找函数峰值点对应的坐标,即可得到我们所要求得的配准点。
该方法只适用图像发生平移的情况。当图像间仅存在平移时,正确的配准图像如图a所示(中心平移化了),最大峰的位置就是两图像的相对平移量,反之若不存在单纯的平移,则会出现如b所示的情况(多脉冲林立)
在这里插入图片描述

算法实现

算法流程如下
在这里插入图片描述

核心函数如下

void PhaseCorrelation2D(const BYTE *signal,//原信号
	const BYTE *pattern,//带配准信号
	int &height_offset,//高的偏移量
	int &width_offset)//宽的偏移量
{
    
    

	fftw_complex *signal_img = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nRow*nCol);
	fftw_complex *pattern_img = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nRow*nCol);

	for (int i = 0; i < nRow*nCol; i++)
	{
    
    
		signal_img[i][0] = signal[i];
		signal_img[i][1] = 0;
	}
	for (int j = 0; j < nRow*nCol; j++)
	{
    
    
		pattern_img[j][0] = pattern[j];
		pattern_img[j][1] = 0;
	}

	// 对两幅图像傅里叶变换
	fftw_plan signal_forward_plan = fftw_plan_dft_2d(nRow, nCol, signal_img, signal_img,
		FFTW_FORWARD, FFTW_ESTIMATE);
	fftw_plan pattern_forward_plan = fftw_plan_dft_2d(nRow, nCol, pattern_img, pattern_img,
		FFTW_FORWARD, FFTW_ESTIMATE);
	fftw_execute(signal_forward_plan);
	fftw_execute(pattern_forward_plan);

	// 求互功率谱
	fftw_complex *cross_img = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nRow*nCol);
	double temp;
	for (int i = 0; i < nRow*nCol; i++)
	{
    
    
		cross_img[i][0] = (signal_img[i][0] * pattern_img[i][0]) - 
			(signal_img[i][1] * (-1.0*pattern_img[i][1]));
		cross_img[i][1] = (signal_img[i][0] * (-1.0*pattern_img[i][1])) + 
			(signal_img[i][1] * pattern_img[i][0]);
		temp = sqrt(cross_img[i][0] * cross_img[i][0] + cross_img[i][1] * cross_img[i][1]) + 0.001;
		cross_img[i][0] /= temp;
		cross_img[i][1] /= temp;
	}

	//对互功率谱求反变换
	fftw_plan cross_backward_plan = fftw_plan_dft_2d(nRow, nCol, cross_img, cross_img,
		FFTW_BACKWARD, FFTW_ESTIMATE);
	fftw_execute(cross_backward_plan);

	// 释放内存
	fftw_destroy_plan(signal_forward_plan);
	fftw_destroy_plan(pattern_forward_plan);
	fftw_destroy_plan(cross_backward_plan);
	fftw_free(signal_img);
	fftw_free(pattern_img);

	double *cross_real=new double[nRow*nCol];
	for (int i = 0; i < nRow*nCol; i++)
		cross_real[i] = cross_img[i][0];

	int max_loc = 0;//准备存放最大值的位置坐标(注意,只有一个值)
	double max_vlaue = 0.0;
	for (int i = 0; i < nRow*nCol; i++)
	{
    
    
		if (max_vlaue<cross_real[i])
		{
    
    
			max_vlaue = cross_real[i];
			max_loc = i;
		}
	}

	height_offset = floor(((int)max_loc) / nCol);
	width_offset = (int)max_loc - nCol*height_offset;

	if (height_offset > 0.5*nRow)
		height_offset = height_offset - nRow;
	if (width_offset > 0.5*nCol)
		width_offset = width_offset - nCol;

	delete[] cross_real;
	cross_real = NULL;
}

参考资料

  • 相位相关图像配准算法的C++实现

猜你喜欢

转载自blog.csdn.net/webzhuce/article/details/115277171