三维重建之条纹投影结构光(二)——四步相移+三频外差法

        接上文:

三维重建之条纹投影结构光(一)https://blog.csdn.net/beyond951/article/details/123361852?spm=1001.2014.3001.5501

        针对上文思路进行验证,本篇博客主要对相位进行求解,首先,对上面博客的理论进行复述,然后包括相位主值的计算和相位展开。

四步相移+三频外差理论推导

相位主值求取—四步相移法

        通过一帧变形条纹 图样是很难得到高精度的相位Φ(x,y),需要采用相移算法来准确测定相位。对条纹 图进行相移的方法有很多 ,比较常用的是N帧满周期等间距相移法 。投影 的正弦条纹每隔一个光栅周期的1/N 移动一次 ,并产生相应的光强函数 ,In(x,y),此时正弦条纹的相位对应移动2π/N。四步相移算法 ,每次的相移增量为 π/2,故可以得到相应的四幅变形条纹图,这里假设In(x,y)(n=1,2,3,4) 代表第n幅图像光强 ,则:

         由上面可以计算得到的相位函数Φ(x,y)为

         由于是通过反正切 函数计算相位信息,因此所得的相位值都是被截断在(-π,π]区间内的不连续相位。 为 了得到连续 的相位分布 ,需要进行相位展开。采用三频外差方法进行相位展开。

相位展开—三频外差法

        三频外差法是一种时间相位展开方法 ,它是在三频展开法的基础上改进而来。通过投射三种不同频率的条纹图到物体表面,拍摄得到一组受物体表面调制的条纹图序列 ,然后将每点的相位沿时间序列独立进行展开 ,可以从原理上避免误差的传播。

        投影三套条纹周期数t=s-√s,s,s+√s+1的条纹图,由四步相移得到三幅截断相位图。之后进行两次外差,可以看出,第一次外差得到数目为(√s,√ s+1)的条纹图,再进行一次外差得到条纹周期数为 1的条纹图,其中外差即对应像素点相位相减。

        首先定义展开运算符U[Φ1,Φ2]如下:

         其中NINT(·)为四舍五入取整运算。

        然后外差得到的条纹周期数为1的相位分布等同于Φw(1)等同于已展开的相位Φu(1),以它为起始相位逐级向上进行相位展开:

        其中v=√s表示不同外差级次的倍率,而k逐级去2、3。通过最小二乘法对展开相位进行拟合,计算得到的斜率表示为

        再将斜率乘以最大投影条纹数,即可得到最终的展开相位ΔΦ。

         综上上述,复述完毕,上代码。

代码实现

相位主值求取—四步相移法

//*****************四步相移法求解图像的相位主值******************//
//本次实验采用四步相移法+三频外差法
//输入输出:输入位十二张图片;输出为三张不同频率的主值图
vector<Mat> FringeStructuredLight::SolveThePhase(vector<Mat> srcVec)
{
	
}

相位展开—三频外差法

//*****************三频外差法对四步相移法求的相位进行展开******************//
//本次实验采用四步相移法+三频外差法
//输入输出:输入位三张主值相位图片;输出为相位的展开图
Mat FringeStructuredLight::UnwrappedPhase(vector<Mat> srcVec)
{
	
}

main函数

int main()
{
	//********声明一些变量存储相位图和高度**********//
	vector<Mat> heightPhase;
	vector<double> height;
	//********计算参考平面的相位**********//
	string filePath_h0 = "D:*.bmp";
	vector<Mat> imgVec_h0 = Api.ReadImg(filePath_h0);
	//********对文件路径下的十二副图计算三组主值相位**********//
	vector<Mat> mainPhaseVec_h0 = Api.SolveThePhase(imgVec_h0);
	//********相位展开**********//
	Mat unwrapPhase_h0 = Api.UnwrappedPhase(mainPhaseVec_h0);
	return 0;
}

ReadImg函数

//*****************读取文件夹里面的图片******************//
vector<Mat> FringeStructuredLight::ReadImg(std::string filepath)
{
	vector<Mat> tempVec;
	std::vector<cv::String> image_files;
	glob(filepath, image_files);
	//最后一张图不读
	for (int i = 0; i < image_files.size()-1; i++)
	{
		Mat temp = imread(image_files[i]);
		tempVec.push_back(temp);
	}
	return tempVec;
}

效果展示

        四步相移+三频外差一共十二副图,因此四步相移法相位主值求取后有三幅图,三频外差最后得到相位展开图。

主值求取结果

 

 相位展开结果

 

         上面将展开相位图通过halcon进行展示。下一步展开相高模型的标定。

猜你喜欢

转载自blog.csdn.net/beyond951/article/details/123769596