Commit 68e59d61 authored by Olexa Bilaniuk's avatar Olexa Bilaniuk

[RHO] Initial commit of RHO algorithm for rapid homography estimation.

Implements the RHO algorithm as presented in

Paper: Bilaniuk, Olexa, Hamid Bazargani, and Robert Laganiere. "Fast
Target Recognition on Mobile Devices: Revisiting Gaussian Elimination
for the Estimation of Planar Homographies." In Computer Vision and
Pattern Recognition Workshops (CVPRW), 2014 IEEE Conference on, pp.
119-125. IEEE, 2014.

- Complete, heavily documented reference C implementation, as well as
temporarily disabled dirty SSE2 port.
- Enabled tests for RHO in test_homography; Currently these fail
presumably due to too-stringent accuracy requirements.
- Refinement and final refinement are not yet functional; Do not pass
their corresponding flags to RHO.
parent 32348604
......@@ -53,7 +53,8 @@ namespace cv
//! type of the robust estimation algorithm
enum { LMEDS = 4, //!< least-median algorithm
RANSAC = 8 //!< RANSAC algorithm
RANSAC = 8, //!< RANSAC algorithm
RHO = 16 //!< RHO algorithm
};
enum { SOLVEPNP_ITERATIVE = 0,
......
......@@ -41,6 +41,10 @@
//M*/
#include "precomp.hpp"
#include "rhorefc.h"
#if CV_SSE2
#include "rhosse2.h"
#endif
#include <iostream>
namespace cv
......@@ -273,6 +277,73 @@ public:
}
namespace cv{
static bool createAndRunRHORegistrator(double confidence, int maxIters, double ransacReprojThreshold, int npoints, InputArray _src, InputArray _dst, OutputArray _H, OutputArray _tempMask){
Mat src = _src.getMat();
Mat dst = _dst.getMat();
Mat tempMask = _tempMask.getMat();
bool result;
/* Run RHO. Needs cleanup or separate function to invoke. */
Mat tmpH = Mat(3, 3, CV_32FC1);
tempMask = Mat(npoints, 1, CV_8U);
double beta = 0.35;/* 0.35 is a value that often works. */
#if CV_SSE2 && 0
if(useOptimized()){
RHO_HEST_SSE2 p;
rhoSSE2Init(&p);
rhoSSE2EnsureCapacity(&p, npoints, beta);
result = !!rhoSSE2(&p,
(const float*)src.data,
(const float*)dst.data,
(char*) tempMask.data,
npoints,
ransacReprojThreshold,
maxIters,
maxIters,
confidence,
4,
beta,
RHO_FLAG_ENABLE_NR,
NULL,
(float*)tmpH.data);
rhoSSE2Fini(&p);
}else
#endif
{
RHO_HEST_REFC p;
rhoRefCInit(&p);
rhoRefCEnsureCapacity(&p, npoints, beta);
result = !!rhoRefC(&p,
(const float*)src.data,
(const float*)dst.data,
(char*) tempMask.data,
npoints,
ransacReprojThreshold,
maxIters,
maxIters,
confidence,
4,
beta,
RHO_FLAG_ENABLE_NR,
NULL,
(float*)tmpH.data);
rhoRefCFini(&p);
}
tmpH.convertTo(_H, CV_64FC1);
/* Maps non-zero maks elems to 1, for the sake of the testcase. */
for(int k=0;k<npoints;k++){
tempMask.data[k] = !!tempMask.data[k];
}
return result;
}
}
cv::Mat cv::findHomography( InputArray _points1, InputArray _points2,
int method, double ransacReprojThreshold, OutputArray _mask,
const int maxIters, const double confidence)
......@@ -317,10 +388,12 @@ cv::Mat cv::findHomography( InputArray _points1, InputArray _points2,
result = createRANSACPointSetRegistrator(cb, 4, ransacReprojThreshold, confidence, maxIters)->run(src, dst, H, tempMask);
else if( method == LMEDS )
result = createLMeDSPointSetRegistrator(cb, 4, confidence, maxIters)->run(src, dst, H, tempMask);
else
else if( method == RHO ){
result = createAndRunRHORegistrator(confidence, maxIters, ransacReprojThreshold, npoints, src, dst, H, tempMask);
}else
CV_Error(Error::StsBadArg, "Unknown estimation method");
if( result && npoints > 4 )
if( result && npoints > 4 && method != RHO)
{
compressPoints( src.ptr<Point2f>(), tempMask.ptr<uchar>(), 1, npoints );
npoints = compressPoints( dst.ptr<Point2f>(), tempMask.ptr<uchar>(), 1, npoints );
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -62,10 +62,10 @@
#define MAX_COUNT_OF_POINTS 303
#define COUNT_NORM_TYPES 3
#define METHODS_COUNT 3
#define METHODS_COUNT 4
int NORM_TYPE[COUNT_NORM_TYPES] = {cv::NORM_L1, cv::NORM_L2, cv::NORM_INF};
int METHOD[METHODS_COUNT] = {0, cv::RANSAC, cv::LMEDS};
int METHOD[METHODS_COUNT] = {0, cv::RANSAC, cv::LMEDS, cv::RHO};
using namespace cv;
using namespace std;
......@@ -144,7 +144,7 @@ void CV_HomographyTest::print_information_1(int j, int N, int _method, const Mat
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
cout << "Count of points: " << N << endl; cout << endl;
cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;
cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else if (_method == cv::RHO) cout << "RHO"; else cout << "LMEDS"; cout << endl;
cout << "Homography matrix:" << endl; cout << endl;
cout << H << endl; cout << endl;
cout << "Number of rows: " << H.rows << " Number of cols: " << H.cols << endl; cout << endl;
......@@ -156,7 +156,7 @@ void CV_HomographyTest::print_information_2(int j, int N, int _method, const Mat
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
cout << "Count of points: " << N << endl; cout << endl;
cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;
cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else if (_method == cv::RHO) cout << "RHO"; else cout << "LMEDS"; cout << endl;
cout << "Original matrix:" << endl; cout << endl;
cout << H << endl; cout << endl;
cout << "Found matrix:" << endl; cout << endl;
......@@ -339,14 +339,15 @@ void CV_HomographyTest::run(int)
continue;
}
case cv::RHO:
case RANSAC:
{
cv::Mat mask [4]; double diff;
Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, RANSAC, reproj_threshold, mask[0]),
cv::findHomography(src_mat_2f, dst_vec, RANSAC, reproj_threshold, mask[1]),
cv::findHomography(src_vec, dst_mat_2f, RANSAC, reproj_threshold, mask[2]),
cv::findHomography(src_vec, dst_vec, RANSAC, reproj_threshold, mask[3]) };
Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, method, reproj_threshold, mask[0]),
cv::findHomography(src_mat_2f, dst_vec, method, reproj_threshold, mask[1]),
cv::findHomography(src_vec, dst_mat_2f, method, reproj_threshold, mask[2]),
cv::findHomography(src_vec, dst_vec, method, reproj_threshold, mask[3]) };
for (int j = 0; j < 4; ++j)
{
......@@ -466,14 +467,15 @@ void CV_HomographyTest::run(int)
continue;
}
case cv::RHO:
case RANSAC:
{
cv::Mat mask_res [4];
Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, RANSAC, reproj_threshold, mask_res[0]),
cv::findHomography(src_mat_2f, dst_vec, RANSAC, reproj_threshold, mask_res[1]),
cv::findHomography(src_vec, dst_mat_2f, RANSAC, reproj_threshold, mask_res[2]),
cv::findHomography(src_vec, dst_vec, RANSAC, reproj_threshold, mask_res[3]) };
Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, method, reproj_threshold, mask_res[0]),
cv::findHomography(src_mat_2f, dst_vec, method, reproj_threshold, mask_res[1]),
cv::findHomography(src_vec, dst_mat_2f, method, reproj_threshold, mask_res[2]),
cv::findHomography(src_vec, dst_vec, method, reproj_threshold, mask_res[3]) };
for (int j = 0; j < 4; ++j)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment