数字图像处理,相位相关算法解决一维信号的偏移问题

时间:2022-03-10 05:57:58


基本原理的实现其实和二维差不多,该文章链接为:http://blog.csdn.net/ebowtang/article/details/51287309

下图展示了该算法对指定偏移量的准确估计:

数字图像处理,相位相关算法解决一维信号的偏移问题

参考代码:

#include <iostream>
#include <fftw3.h>
#include <vector>
#include <math.h>

using namespace std;
/** \brief PhaseCorrelation1D compute the offset between two input vectors
* based on POMF (Phase Only Matched Filter)
* -->> Q(k) = conjugate(S(k))/|S(k)| * R(k)/|R(k)|
* -->> q(x) = ifft(Q(k))
* -->> (xs,ys) = argmax(q(x))
* Note that the storage order of FFTW is row-order, while the storage
* order of Eigen is DEFAULT column-order.
*/
void PhaseCorrelation1D(vector<double> &signal,
	const vector<double> &pattern,
	const int size,
	int &offset)
{
	// 错误
	if (signal.size() != size ||
		pattern.size() != size)
	{
		std::cout << "The size of vector input for PhaseCorrelation wrong!" << std::endl;
		return;
	}

	fftw_complex *signal_vector = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*size);
	fftw_complex *pattern_vector = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*size);

	for (unsigned int i = 0; i < signal.size(); i++)
	{
		signal_vector[i][0] = *(signal.data() + i);
		signal_vector[i][1] = 0;
		pattern_vector[i][0] = *(pattern.data() + i);
		pattern_vector[i][1] = 0;
	}

	// 傅里叶变换
	fftw_plan signal_forward_plan = fftw_plan_dft_1d(size, signal_vector, signal_vector,
		FFTW_FORWARD, FFTW_ESTIMATE);
	fftw_plan pattern_forward_plan = fftw_plan_dft_1d(size, pattern_vector, pattern_vector,
		FFTW_FORWARD, FFTW_ESTIMATE);
	fftw_execute(signal_forward_plan);
	fftw_execute(pattern_forward_plan);

	// 求取互功率谱
	fftw_complex *cross_vector = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*size);
	double temp;
	for (int i = 0; i<size; i++)
	{
		cross_vector[i][0] = (pattern_vector[i][0] * signal_vector[i][0]) -
			(pattern_vector[i][1] * (-signal_vector[i][1]));
		cross_vector[i][1] = (pattern_vector[i][0] * (-signal_vector[i][1])) +
			(pattern_vector[i][1] * signal_vector[i][0]);
		temp = sqrt(cross_vector[i][0] * cross_vector[i][0] + cross_vector[i][1] * cross_vector[i][1]);
		cross_vector[i][0] /= temp;
		cross_vector[i][1] /= temp;
	}

	// 傅里叶反变换
	// FFTW computes an unnormalized transform,
	// in that there is no coefficient in front of
	// the summation in the DFT.
	// In other words, applying the forward and then
	// the backward transform will multiply the input by n.

	// BUT, we only care about the maximum of the inverse DFT,
	// so we don't need to normalize the inverse result.

	// the storage order in FFTW is row-order
	fftw_plan cross_backward_plan = fftw_plan_dft_1d(size, cross_vector, cross_vector,
		FFTW_FORWARD, FFTW_ESTIMATE);
	fftw_execute(cross_backward_plan);

	// 释放资源
	fftw_destroy_plan(signal_forward_plan);
	fftw_destroy_plan(pattern_forward_plan);
	fftw_free(signal_vector);
	fftw_free(pattern_vector);

	vector<double> cross_real(size,0.0);
	for (int i = 0; i < size; i++)
		cross_real[i] = cross_vector[i][0];
	//求取偏移量
	int max_loc = 0;
	float unuse = 0.0;
	double maxcoeff = INT_MIN;
	for (unsigned int i = 0; i<cross_real.size(); i++)
	{
		if (maxcoeff < cross_real[i])
		{
			maxcoeff = cross_real[i];
			max_loc = i;
			unuse = cross_real[i];
		}
	}
	offset = (int)max_loc;

	if (offset > 0.5*size)
		offset = offset - size;

}

void offsetArr(vector<double> &signal,vector<double> &pattern,int offset)
{
	int nsize = signal.size();
	for (int i = offset; i < nsize; i++)
		pattern[i - offset] = signal[i];
	for (int i = 0; i < offset; i++)
		pattern[nsize-i-1] = signal[i];
}



int main()
{
	int nsize = 32;
	vector<double> signal(nsize, 0), pattern(nsize, 0);
	for (int i = 0; i < nsize; i++)
		signal[i] = rand() % nsize;
	int myoffset = 10;
	offsetArr(signal,pattern,myoffset);
	int offset = 0;
	PhaseCorrelation1D(signal,pattern,nsize,offset);


	cout << "原信号(随机生成)为:  "<< endl;
	for (int i = 0; i < nsize; i++)
		cout<<signal[i]<<" ";
	cout << endl;
	cout << "对原信号指定的偏移量为:" << myoffset << endl;

	cout<< "偏移信号为:  " << endl;
	for (int i = 0; i < nsize; i++)
		cout << pattern[i] << " ";
	cout << endl;
	cout <<"相位相关法求取的偏移量为:" <<offset << endl;
	getchar();
	return 0;
}


参考资源:

【1】MIT,FFTW库

【2】Joseph L. Horner and Peter D. Gianino. Phase-only matched ltering. Applied Optics, 23(6):812-816, 1984.

【3】中国科学技术大学信号统计处理研究院,郑志彬,叶中付,《基于相位相关的图像配准算法》,2006,12