sthoduka / imreg_fmt

Image registration based on the Fourier-Mellin transform
https://sthoduka.github.io/imreg_fmt/
GNU General Public License v3.0
96 stars 22 forks source link

Better performance with OpenCV phaseCorrelate #15

Open brht0 opened 2 months ago

brht0 commented 2 months ago

Please use OpenCV's provided phaseCorrelate function to improve performance.

With minor changes I improved the running time of registerImage from 316ms to 93ms, or ~3.4x improvement. (1280x720, 100 runs, averaged.) Changes in image_registration.cpp:

auto[rs_col, rs_row] = cv::phaseCorrelate(im1_logpolar_, im0_logpolar_);
image_transforms_.getScaleRotation(-rs_row, -rs_col, scale, rotation);

, and:

auto[t_col, t_row] = cv::phaseCorrelate(im1_gray_, im0_rotated_);
image_transforms_.translate(im0_rotated_, registered_image, -t_col, -t_row);

I see no reason to implement phase correlation here. The implementation in OpenCV is different (see link), but the difference of the output transformation parameters is marginal.

As a side note, using OpenCV would also allow for outputting the confidence of the transform with the signal power around the peak 5x5:

double response;
auto[t_col, t_row] = cv::phaseCorrelate(im1_gray_, im0_rotated_, cv::noArray(), &response);
transform_params[4] = response;

OpenCV documentation for phaseCorrelate: https://docs.opencv.org/4.x/d7/df3/groupimgprocmotion.html#ga552420a2ace9ef3fb053cd630fdb4952

Implementation of OpenCV phaseCorrelate: https://github.com/opencv/opencv/blob/d7a237aefc76f841dba64544d09ab6df53097206/modules/imgproc/src/phasecorr.cpp#L518

Edit: Code highlight

sthoduka commented 2 months ago

Thanks! I will look into that. There was another issue (#4) about how to get the value of the peak, so it's definitely useful that OpenCV also returns that.

Were you running with the Release build type btw?

brht0 commented 2 months ago

Yes, I built it in Release mode, as per your instructions in the README. However, it might have been that the OpenCV build I have is just using acceleration options to make it faster, so I would recommend benchmarking against a standard OpenCV CPU build to see if it is (actually) faster.

Nevertheless, using native OpenCV functions will be faster by default.

PS, I made my own Fourier-Mellin implementation using OpenCV with python bindings, and have linked your project as one of the alternatives. Is this alright with you?