四步相移法求主值
计算相位函数:
代码:
void MultifrequencyHeterodyeMethod::fourStepPhaseShifting(cv::Mat grating_img[])//四步相移法
{
cv::Mat PhasePrincipalValuePicture_temp[3] =
{
cv::Mat::zeros(grating_rows, grating_cols, CV_8UC1),
cv::Mat::zeros(grating_rows, grating_cols, CV_8UC1),
cv::Mat::zeros(grating_rows, grating_cols, CV_8UC1)
};
uchar* p[12] = { NULL };
for (int y = 0; y < grating_rows; ++y)//图像行遍历
{
for (int img_num = 0; img_num < 12; ++img_num)
{
p[img_num] = grating_img[img_num].ptr<uchar>(y);
}//遍历12幅图
for (int x = 0; x < grating_cols; ++x)//图像列遍历
{
double phaseValue1_temp = atan2((double)(p[3][x] - p[1][x]), (double)(p[0][x] - p[2][x]));//3-1 0-2
if (phaseValue1_temp >= 0)
PhasePrincipalValuePicture[0].at<double>(y, x) = phaseValue1_temp;
else
PhasePrincipalValuePicture[0].at<double>(y, x) = phaseValue1_temp + CV_PI * 2;
double phaseValue2_temp = atan2((double)(p[7][x] - p[5][x]), (double)(p[4][x] - p[6][x]));//7-5 4-6
if (phaseValue2_temp >= 0)
PhasePrincipalValuePicture[1].at<double>(y, x) = phaseValue2_temp;
else
PhasePrincipalValuePicture[1].at<double>(y, x) = phaseValue2_temp + CV_PI * 2;
double phaseValue3_temp = atan2((double)(p[11][x] - p[9][x]), (double)(p[8][x] - p[10][x]));//11-0 8-10
if (phaseValue3_temp >= 0)
PhasePrincipalValuePicture[2].at<double>(y, x) = phaseValue3_temp;
else
PhasePrincipalValuePicture[2].at<double>(y, x) = phaseValue3_temp + CV_PI * 2;
PhasePrincipalValuePicture_temp[0].at<uchar>(y, x) = PhasePrincipalValuePicture[0].at<double>(y, x) / (2 * CV_PI) * 255;
PhasePrincipalValuePicture_temp[1].at<uchar>(y, x) = PhasePrincipalValuePicture[1].at<double>(y, x) / (2 * CV_PI) * 255;
PhasePrincipalValuePicture_temp[2].at<uchar>(y, x) = PhasePrincipalValuePicture[2].at<double>(y, x) / (2 * CV_PI) * 255;
}
}
//三张不同频率的主值图
cv::namedWindow("PhasePrincipalValuePicture[0]", 0);
cv::resizeWindow("PhasePrincipalValuePicture[0]", cv::Size(800, 600));
cv::imshow("PhasePrincipalValuePicture[0]", PhasePrincipalValuePicture_temp[0]);
cv::namedWindow("PhasePrincipalValuePicture[1]", 0);
cv::resizeWindow("PhasePrincipalValuePicture[1]", cv::Size(800, 600));
cv::imshow("PhasePrincipalValuePicture[1]", PhasePrincipalValuePicture_temp[1]);
cv::namedWindow("PhasePrincipalValuePicture[2]", 0);
cv::resizeWindow("PhasePrincipalValuePicture[2]", cv::Size(800, 600));
cv::imshow("PhasePrincipalValuePicture[2]", PhasePrincipalValuePicture_temp[2]);
cv::waitKey(500);
}
atan2的含义:
C 语言里 double atan2(double y,double x) 返回的是原点至点(x,y)的方位角,即与 x 轴的夹角。返回值的单位为弧度,取值范围为(-π, π]。结果为正表示从 X 轴逆时针旋转的角度,结果为负表示从 X 轴顺时针旋转的角度。若要用度表示反正切值,请将结果再乘以 180/π。另外要注意的是, 函数atan2(y,x)中参数的顺序是倒置的,atan2(y,x)计算的值相当于点(x,y)的角度值。
运行结果:
频率1主值图:
频率2主值图:
频率3主值图:
参考博客: