opencv-phaseCorrelate-response.patch

Robert Huitl, 2012-06-21 04:59 pm

Download (4.5 kB)

 
modules/imgproc/include/opencv2/imgproc/imgproc.hpp (working copy)
600 600
//! computes PSNR image/video quality metric
601 601
CV_EXPORTS_W double PSNR(InputArray src1, InputArray src2);
602 602

  
603
CV_EXPORTS_W Point2d phaseCorrelate(InputArray src1, InputArray src2, InputArray window = noArray());
603
CV_EXPORTS_W Point2d phaseCorrelate(InputArray src1, InputArray src2, InputArray window = noArray(), double* response=0);
604 604
CV_EXPORTS_W void createHanningWindow(OutputArray dst, Size winSize, int type);
605 605

  
606 606
//! type of the threshold operation
modules/imgproc/doc/motion_analysis_and_object_tracking.rst (working copy)
151 151

  
152 152
Calculates the cross-power spectrum of two supplied source arrays. The arrays are padded if needed with :ocv:func:`getOptimalDFTSize`.
153 153

  
154
.. ocv:function:: Point2d phaseCorrelate(InputArray src1, InputArray src2, InputArray window = noArray())
154
.. ocv:function:: Point2d phaseCorrelate(InputArray src1, InputArray src2, InputArray window = noArray(), double* response = 0)
155 155

  
156 156
    :param src1: Source floating point array (CV_32FC1 or CV_64FC1)
157 157
    :param src2: Source floating point array (CV_32FC1 or CV_64FC1)
158 158
    :param window: Floating point array with windowing coefficients to reduce edge effects (optional).
159
    :param response: Signal power within the 5x5 centroid around the peak, between 0 and 1 (optional).
159 160

  
160 161
Return value: detected phase shift (sub-pixel) between the two arrays.
161 162

  
......
165 166

  
166 167
* Next it computes the forward DFTs of each source array:
167 168

  
168
     .. math::
169
.. math::
169 170

  
170 171
        \mathbf{G}_a = \mathcal{F}\{src_1\}, \; \mathbf{G}_b = \mathcal{F}\{src_2\}
171 172

  
172 173
  where
173
  :math:`\mathcal{F}` is the forward DFT.
174
..  math::`\mathcal{F}` is the forward DFT.
174 175

  
175 176
* It then computes the cross-power spectrum of each frequency domain array:
176 177

  
177
    .. math::
178
.. math::
178 179

  
179 180
          R = \frac{ \mathbf{G}_a \mathbf{G}_b^*}{|\mathbf{G}_a \mathbf{G}_b^*|}
180 181

  
181 182
* Next the cross-correlation is converted back into the time domain via the inverse DFT:
182 183

  
183
    .. math::
184
.. math::
184 185

  
185 186
          r = \mathcal{F}^{-1}\{R\}
186 187

  
187 188
* Finally, it computes the peak location and computes a 5x5 weighted centroid around the peak to achieve sub-pixel accuracy.
188 189

  
189
    .. math::
190
.. math::
190 191

  
191 192
         (\Delta x, \Delta y) = \texttt{weightedCentroid} \{\arg \max_{(x, y)}\{r\}\}
192 193

  
194
* If non-zero, the response parameter is computed as the sum of the elements of r within the 5x5 centroid around the peak location. It is normalized to a maximum of 1 (meaning there is a single peak) and will be smaller when there are multiple peaks.
195

  
193 196
.. seealso::
194 197
    :ocv:func:`dft`,
195 198
    :ocv:func:`getOptimalDFTSize`,
modules/imgproc/src/phasecorr.cpp (working copy)
406 406
    merge(planes, out);
407 407
}
408 408

  
409
static Point2d weightedCentroid(InputArray _src, cv::Point peakLocation, cv::Size weightBoxSize)
409
static Point2d weightedCentroid(InputArray _src, cv::Point peakLocation, cv::Size weightBoxSize, double* response)
410 410
{
411 411
    Mat src = _src.getMat();
412 412

  
......
475 475
        }
476 476
    }
477 477

  
478
    if(response)
479
        *response = sumIntensity;
480

  
478 481
    sumIntensity += DBL_EPSILON; // prevent div0 problems...
479 482

  
480 483
    centroid.x /= sumIntensity;
......
485 488

  
486 489
}
487 490

  
488
cv::Point2d cv::phaseCorrelate(InputArray _src1, InputArray _src2, InputArray _window)
491
cv::Point2d cv::phaseCorrelate(InputArray _src1, InputArray _src2, InputArray _window, double* response)
489 492
{
490 493
    Mat src1 = _src1.getMat();
491 494
    Mat src2 = _src2.getMat();
......
553 556

  
554 557
    // get the phase shift with sub-pixel accuracy, 5x5 window seems about right here...
555 558
    Point2d t;
556
    t = weightedCentroid(C, peakLoc, Size(5, 5));
559
    t = weightedCentroid(C, peakLoc, Size(5, 5), response);
557 560

  
561
    // max response is M*N (not exactly, might be slightly larger due to rounding errors)
562
    if(response)
563
        *response /= M*N;
564

  
558 565
    // adjust shift relative to image center...
559 566
    Point2d center((double)padded1.cols / 2.0, (double)padded1.rows / 2.0);
560 567