mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
Try to remove features dependency from 3d module.
This commit is contained in:
@@ -6,7 +6,7 @@ set(debug_modules "")
|
||||
if(DEBUG_opencv_3d)
|
||||
list(APPEND debug_modules opencv_highgui)
|
||||
endif()
|
||||
ocv_define_module(3d opencv_imgproc opencv_features opencv_flann ${debug_modules}
|
||||
ocv_define_module(3d opencv_imgproc opencv_flann ${debug_modules}
|
||||
WRAP java objc python js
|
||||
)
|
||||
ocv_target_link_libraries(${the_module} ${LAPACK_LIBRARIES})
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
|
||||
#include "opencv2/3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/features.hpp"
|
||||
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
|
||||
@@ -611,6 +611,69 @@ float Utils::findMedian (std::vector<float> &array) {
|
||||
}
|
||||
}
|
||||
|
||||
// Flann radiusMatch
|
||||
struct FlannMatcher
|
||||
{
|
||||
Ptr<flann::IndexParams> indexParams;
|
||||
Ptr<flann::SearchParams> searchParams;
|
||||
Ptr<flann::Index> flannIndex;
|
||||
|
||||
FlannMatcher( const Ptr<flann::IndexParams>& _indexParams, const Ptr<flann::SearchParams>& _searchParams )
|
||||
: indexParams(_indexParams), searchParams(_searchParams)
|
||||
{
|
||||
CV_Assert( _indexParams );
|
||||
CV_Assert( _searchParams );
|
||||
}
|
||||
|
||||
void radiusMatch( const Mat& queryDescriptors, const Mat& trainDescriptors,
|
||||
std::vector<std::vector<DMatch> >& matches, float maxDistance)
|
||||
{
|
||||
CV_Assert( maxDistance > std::numeric_limits<float>::epsilon() );
|
||||
|
||||
if( trainDescriptors.empty() || queryDescriptors.empty() )
|
||||
return;
|
||||
|
||||
matches.clear();
|
||||
|
||||
flannIndex = makePtr<flann::Index>( trainDescriptors, *indexParams );
|
||||
|
||||
Mat indices( queryDescriptors.rows, 1, CV_32SC1, Scalar::all(-1) );
|
||||
Mat dists( queryDescriptors.rows, 1, CV_32FC1, Scalar::all(-1) );
|
||||
for( int qIdx = 0; qIdx < queryDescriptors.rows; qIdx++ )
|
||||
{
|
||||
Mat queryDescriptorsRow = queryDescriptors.row(qIdx);
|
||||
Mat indicesRow = indices.row(qIdx);
|
||||
Mat distsRow = dists.row(qIdx);
|
||||
flannIndex->radiusSearch( queryDescriptorsRow, indicesRow, distsRow, maxDistance*maxDistance, 1, *searchParams );
|
||||
}
|
||||
|
||||
convertToDMatches( indices, dists, matches );
|
||||
}
|
||||
|
||||
void convertToDMatches( const Mat& indices, const Mat& dists, std::vector<std::vector<DMatch> >& matches )
|
||||
{
|
||||
matches.resize( indices.rows );
|
||||
for( int i = 0; i < indices.rows; i++ )
|
||||
{
|
||||
for( int j = 0; j < indices.cols; j++ )
|
||||
{
|
||||
int idx = indices.at<int>(i, j);
|
||||
if( idx >= 0 )
|
||||
{
|
||||
int imgIdx = 0;
|
||||
int trainIdx = idx;
|
||||
float dist = 0;
|
||||
if (dists.type() == CV_32S)
|
||||
dist = static_cast<float>( dists.at<int>(i,j) );
|
||||
else
|
||||
dist = std::sqrt(dists.at<float>(i,j));
|
||||
matches[i].push_back( DMatch( i, trainIdx, imgIdx, dist ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////// Radius Search Graph /////////////////////////////////////////////
|
||||
class RadiusSearchNeighborhoodGraphImpl : public RadiusSearchNeighborhoodGraph {
|
||||
private:
|
||||
@@ -621,7 +684,7 @@ public:
|
||||
// Radius search OpenCV works only with float data
|
||||
CV_Assert(container_.type() == CV_32F);
|
||||
|
||||
FlannBasedMatcher flann(makePtr<flann::KDTreeIndexParams>(num_kd_trees), makePtr<flann::SearchParams>(flann_search_params));
|
||||
FlannMatcher flann(makePtr<flann::KDTreeIndexParams>(num_kd_trees), makePtr<flann::SearchParams>(flann_search_params));
|
||||
std::vector<std::vector<DMatch>> neighbours;
|
||||
flann.radiusMatch(container_, container_, neighbours, (float)radius);
|
||||
|
||||
|
||||
@@ -42,7 +42,12 @@
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include <opencv2/features.hpp>
|
||||
|
||||
// #define SAVE_FEATURES 1
|
||||
|
||||
#ifdef SAVE_FEATURES
|
||||
# include "opencv2/features.hpp"
|
||||
#endif
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
@@ -604,13 +609,39 @@ TEST(Calib3d_Homography, EKcase)
|
||||
ASSERT_LE(err, 0.01);
|
||||
}
|
||||
|
||||
#ifdef SAVE_FEATURES
|
||||
static void saveKeypoints(const std::string& fname, const std::vector<cv::Point2f> points)
|
||||
{
|
||||
FileStorage fs(fname, cv::FileStorage::WRITE);
|
||||
ASSERT_TRUE(fs.isOpened());
|
||||
fs << "keypoints" << points;
|
||||
fs.release();
|
||||
}
|
||||
#else
|
||||
static void loadKeypoints(const std::string& fname, std::vector<cv::Point2f>& points)
|
||||
{
|
||||
FileStorage fs(fname, cv::FileStorage::READ);
|
||||
ASSERT_TRUE(fs.isOpened());
|
||||
fs["keypoints"] >> points;
|
||||
fs.release();
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(Calib3d_Homography, fromImages)
|
||||
{
|
||||
const std::string points_file1 = cvtest::TS::ptr()->get_data_path() + "cv/optflow/image1.ORB.yaml.gz";
|
||||
const std::string points_file2 = cvtest::TS::ptr()->get_data_path() + "cv/optflow/image2.ORB.yaml.gz";
|
||||
|
||||
std::vector<Point2f> pointframe1;
|
||||
std::vector<Point2f> pointframe2;
|
||||
|
||||
#ifdef SAVE_FEATURES
|
||||
vector<KeyPoint> keypoints_1, keypoints_2;
|
||||
Mat descriptors_1, descriptors_2;
|
||||
|
||||
Mat img_1 = imread(cvtest::TS::ptr()->get_data_path() + "cv/optflow/image1.png", 0);
|
||||
Mat img_2 = imread(cvtest::TS::ptr()->get_data_path() + "cv/optflow/image2.png", 0);
|
||||
Ptr<ORB> orb = ORB::create();
|
||||
vector<KeyPoint> keypoints_1, keypoints_2;
|
||||
Mat descriptors_1, descriptors_2;
|
||||
orb->detectAndCompute( img_1, Mat(), keypoints_1, descriptors_1, false );
|
||||
orb->detectAndCompute( img_2, Mat(), keypoints_2, descriptors_2, false );
|
||||
|
||||
@@ -637,8 +668,6 @@ TEST(Calib3d_Homography, fromImages)
|
||||
}
|
||||
|
||||
//-- Localize the model
|
||||
std::vector<Point2f> pointframe1;
|
||||
std::vector<Point2f> pointframe2;
|
||||
for( int i = 0; i < (int)good_matches.size(); i++ )
|
||||
{
|
||||
//-- Get the keypoints from the good matches
|
||||
@@ -646,6 +675,15 @@ TEST(Calib3d_Homography, fromImages)
|
||||
pointframe2.push_back( keypoints_2[ good_matches[i].trainIdx ].pt );
|
||||
}
|
||||
|
||||
saveKeypoints(points_file1, pointframe1);
|
||||
saveKeypoints(points_file2, pointframe2);
|
||||
#else
|
||||
loadKeypoints(points_file1, pointframe1);
|
||||
loadKeypoints(points_file2, pointframe2);
|
||||
#endif
|
||||
ASSERT_FALSE(pointframe1.empty());
|
||||
ASSERT_FALSE(pointframe1.empty());
|
||||
|
||||
Mat H0, H1, inliers0, inliers1;
|
||||
double min_t0 = DBL_MAX, min_t1 = DBL_MAX;
|
||||
for( int i = 0; i < 10; i++ )
|
||||
@@ -664,11 +702,6 @@ TEST(Calib3d_Homography, fromImages)
|
||||
min_t1 = std::min(min_t1, t);
|
||||
}
|
||||
int ninliers1 = countNonZero(inliers1);
|
||||
double freq = getTickFrequency();
|
||||
printf("nfeatures1 = %d, nfeatures2=%d, matches=%d, ninliers(RANSAC)=%d, "
|
||||
"time(RANSAC)=%.2fmsec, ninliers(RHO)=%d, time(RHO)=%.2fmsec\n",
|
||||
(int)keypoints_1.size(), (int)keypoints_2.size(),
|
||||
(int)good_matches.size(), ninliers0, min_t0*1000./freq, ninliers1, min_t1*1000./freq);
|
||||
|
||||
ASSERT_TRUE(!H0.empty());
|
||||
ASSERT_GE(ninliers0, 80);
|
||||
|
||||
Reference in New Issue
Block a user