opencv-phaseCorrelate-response.patch
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 |