OpenCV phase()函数在这种边缘情况下是否正常工作?

OpenCV phase()函数在这种边缘情况下是否正常工作?,opencv,fft,Opencv,Fft,我正在使用OpenCV 3.2.0进行一些傅立叶空间计算。为了在逆DFT后获得相位图像,我尝试使用cv::phase(),但我注意到在某些情况下,它返回的值接近2*Pi,在我看来,它应该返回接近于零的值。我想知道这个函数是不是实现得很糟糕,还是我用错了 这是我的示例数据,一个7x8 FFT,其中虚部为零,或者由于舍入误差,非常接近零(值对的形式为real,imag): 然后我像这样应用了cv::phase(): Mat planes[2]; split(output,planes); Mat p

我正在使用OpenCV 3.2.0进行一些傅立叶空间计算。为了在逆DFT后获得相位图像,我尝试使用
cv::phase()
,但我注意到在某些情况下,它返回的值接近2*Pi,在我看来,它应该返回接近于零的值。我想知道这个函数是不是实现得很糟糕,还是我用错了

这是我的示例数据,一个7x8 FFT,其中虚部为零,或者由于舍入误差,非常接近零(值对的形式为
real,imag
):

然后我像这样应用了
cv::phase()

Mat planes[2];
split(output,planes);
Mat ph;
phase(planes[0],planes[1],ph);
然后,
cout注意

2*pi - 6.479350716073673e-19 == 6.28318530717959
你的两个结果是相等的

C++在范围(-π,+π)中返回一个值,所以对于任何接近零的角度,无论是正的还是负的,都得到接近零的值。 OpenCV被记录为使用

atan2
,但它似乎返回一个范围为[0,2π)的值

如果需要输出在(-π,+π)范围内,可以执行()操作:


谢谢,对于每个像素,它比使用atan2的for循环快得多!
 0, 6.2831855, 6.2831855, 6.2831855, 0, 6.2831855, 6.6180405e-19, 2.8908079e-18;
 0, 6.2831855, 6.2831855, 6.2831855, 0, 6.2831855, 6.7087144e-18, 1.2309944e-17;
 0, 6.2831855, 6.2831855, 6.2831855, 0, 6.2831855, 1.096805e-17, 1.451942e-17;
 0, 6.2831855, 6.2831855, 6.2831855, 0, 6.2831855, 2.0301558e-17, 2.6067677e-17;
 0, 6.2831855, 6.2831855, 6.2831855, 0, 6.2831855, 2.3497438e-17, 2.3532349e-17;
 0, 6.2831855, 6.2831855, 6.2831855, 0, 6.2831855, 1.1550381e-17, 1.2903592e-17;
 0, 9.4909814e-19, 6.2831855, 6.2831855, 0, 9.7169579e-19, 3.4281555e-18, 4.8463495e-18
Mat_<double> myPhase = Mat_<double>(8,7);
for(int i = 0; i < fftReal.rows; i++) {
  for(int j = 0; j < fftReal.cols; j++) {
      float fftRealVal = planes[0].at<float>(i,j);
      float fftImagVal = planes[1].at<float>(i,j);
      double angle = atan2(fftImagVal, fftRealVal);
      myPhase(i,j) = angle;
  }
 0, -4.833945789050036e-19, -6.479350716073673e-19, -1.735906137457605e-18, 0, -4.833945789050036e-19, 6.619444609555068e-19;
 0, -9.904875721669217e-19, -5.503821154321125e-18, -7.246633215917781e-18, 0, -1.00828074413082e-18, 6.710137932686301e-18;
 0, -2.740232027682232e-18, -8.076351618590122e-18, -5.13479354918468e-18, 0, -3.126180439429062e-18, 1.097037782204674e-17;
 0, -1.130084743690479e-18, -1.220843476128649e-17, -1.249016668765776e-17, 0, -1.451574279023501e-18, 2.030586625060691e-17;
 0, -1.541024556489219e-18, -1.329565697018843e-17, -1.101749982000204e-17, 0, -1.979419217601631e-18, 2.350242300975683e-17;
 0, -1.063021695913201e-18, -8.387671795472417e-18, -7.216393147084068e-18, 0, -1.417362295683461e-18, 1.155283208729227e-17;
 0, 9.492995611309157e-19, -3.083527284733071e-18, -5.78045227144509e-18, 0, 9.719018577786209e-19, 3.428882635099473e-18;
 4.847377651234249e-18, 6.937607420147441e-310, 6.937607420153765e-310, 6.93760742011582e-310, 6.93760742011503e-310, 6.937607420163251e-310, 6.937607420188547e-310
2*pi - 6.479350716073673e-19 == 6.28318530717959
float pi = 3.14159265358979;
cv::subtract(ph, 2*pi, ph, (ph > pi));