mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
Merge pull request #8869 from hrnr:akaze_part1
[GSOC] Speeding-up AKAZE, part #1 (#8869)
* ts: expand arguments before stringifications in CV_ENUM and CV_FLAGS
added protective macros to always force macro expansion of arguments. This allows using CV_ENUM and CV_FLAGS with macro arguments.
* feature2d: unify perf test
use the same test for all detectors/descriptors we have.
* added AKAZE tests
* features2d: extend perf tests
* add BRISK, KAZE, MSER
* run all extract tests on AKAZE keypoints, so that the test si more comparable for the speed of extraction
* feature2d: rework opencl perf tests
use the same configuration as cpu tests
* feature2d: fix descriptors allocation for AKAZE and KAZE
fix crash when descriptors are UMat
* feature2d: name enum to fix build with older gcc
* Revert "ts: expand arguments before stringifications in CV_ENUM and CV_FLAGS"
This reverts commit 19538cac1e.
This wasn't a great idea after all. There is a lot of flags implemented as #define, that we don't want to expand.
* feature2d: fix expansion problems with CV_ENUM in perf
* expand arguments before passing them to CV_ENUM. This does not need modifications of CV_ENUM.
* added include guards to `perf_feature2d.hpp`
* feature2d: fix crash in AKAZE when using KAZE descriptors
* out-of-bound access in Get_MSURF_Descriptor_64
* this happened reliably when running on provided keypoints (not computed by the same instance)
* feature2d: added regression tests for AKAZE
* test with both MLDB and KAZE keypoints
* feature2d: do not compute keypoints orientation twice
* always compute keypoints orientation, when computing keypoints
* do not recompute keypoint orientation when computing descriptors
this allows to test detection and extraction separately
* features2d: fix crash in AKAZE
* out-of-bound reads near the image edge
* same as the bug in KAZE descriptors
* feature2d: refactor invariance testing
* split detectors and descriptors tests
* rewrite to google test to simplify debugging
* add tests for AKAZE and one test for ORB
* stitching: add tests with AKAZE feature finder
* added basic stitching cpu and ocl tests
* fix bug in AKAZE wrapper for stitching pipeline causing lots of
! OPENCV warning: getUMat()/getMat() call chain possible problem.
! Base object is dead, while nested/derived object is still alive or processed.
! Please check lifetime of UMat/Mat objects!
This commit is contained in:
committed by
Alexander Alekhin
parent
437ca0b62a
commit
5f20e802d2
@@ -200,8 +200,7 @@ namespace cv
|
||||
if (!useProvidedKeypoints)
|
||||
{
|
||||
impl.Feature_Detection(keypoints);
|
||||
if( !descriptors.needed() )
|
||||
impl.Compute_Keypoints_Orientation(keypoints);
|
||||
impl.Compute_Keypoints_Orientation(keypoints);
|
||||
}
|
||||
|
||||
if (!mask.empty())
|
||||
@@ -211,8 +210,10 @@ namespace cv
|
||||
|
||||
if( descriptors.needed() )
|
||||
{
|
||||
Mat& desc = descriptors.getMatRef();
|
||||
Mat desc;
|
||||
impl.Compute_Descriptors(keypoints, desc);
|
||||
// TODO optimize this copy
|
||||
desc.copyTo(descriptors);
|
||||
|
||||
CV_Assert((!desc.rows || desc.cols == descriptorSize()));
|
||||
CV_Assert((!desc.rows || (desc.type() == descriptorType())));
|
||||
|
||||
@@ -151,8 +151,9 @@ namespace cv
|
||||
|
||||
if( descriptors.needed() )
|
||||
{
|
||||
Mat& desc = descriptors.getMatRef();
|
||||
Mat desc;
|
||||
impl.Feature_Description(keypoints, desc);
|
||||
desc.copyTo(descriptors);
|
||||
|
||||
CV_Assert((!desc.rows || desc.cols == descriptorSize()));
|
||||
CV_Assert((!desc.rows || (desc.type() == descriptorType())));
|
||||
|
||||
@@ -549,7 +549,6 @@ public:
|
||||
{
|
||||
for (int i = range.start; i < range.end; i++)
|
||||
{
|
||||
AKAZEFeatures::Compute_Main_Orientation((*keypoints_)[i], *evolution_);
|
||||
Get_MSURF_Descriptor_64((*keypoints_)[i], descriptors_->ptr<float>(i));
|
||||
}
|
||||
}
|
||||
@@ -643,7 +642,6 @@ public:
|
||||
{
|
||||
for (int i = range.start; i < range.end; i++)
|
||||
{
|
||||
AKAZEFeatures::Compute_Main_Orientation((*keypoints_)[i], *evolution_);
|
||||
Get_MLDB_Full_Descriptor((*keypoints_)[i], descriptors_->ptr<unsigned char>(i));
|
||||
}
|
||||
}
|
||||
@@ -1055,19 +1053,28 @@ void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, f
|
||||
y2 = fRound(sample_y + 0.5f);
|
||||
x2 = fRound(sample_x + 0.5f);
|
||||
|
||||
// fix crash: indexing with out-of-bounds index, this might happen near the edges of image
|
||||
// clip values so they fit into the image
|
||||
const MatSize& size = evolution[level].Lx.size;
|
||||
y1 = min(max(0, y1), size[0] - 1);
|
||||
x1 = min(max(0, x1), size[1] - 1);
|
||||
y2 = min(max(0, y2), size[0] - 1);
|
||||
x2 = min(max(0, x2), size[1] - 1);
|
||||
CV_DbgAssert(evolution[level].Lx.size == evolution[level].Ly.size);
|
||||
|
||||
fx = sample_x - x1;
|
||||
fy = sample_y - y1;
|
||||
|
||||
res1 = *(evolution[level].Lx.ptr<float>(y1)+x1);
|
||||
res2 = *(evolution[level].Lx.ptr<float>(y1)+x2);
|
||||
res3 = *(evolution[level].Lx.ptr<float>(y2)+x1);
|
||||
res4 = *(evolution[level].Lx.ptr<float>(y2)+x2);
|
||||
res1 = *(evolution[level].Lx.ptr<float>(y1, x1));
|
||||
res2 = *(evolution[level].Lx.ptr<float>(y1, x2));
|
||||
res3 = *(evolution[level].Lx.ptr<float>(y2, x1));
|
||||
res4 = *(evolution[level].Lx.ptr<float>(y2, x2));
|
||||
rx = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4;
|
||||
|
||||
res1 = *(evolution[level].Ly.ptr<float>(y1)+x1);
|
||||
res2 = *(evolution[level].Ly.ptr<float>(y1)+x2);
|
||||
res3 = *(evolution[level].Ly.ptr<float>(y2)+x1);
|
||||
res4 = *(evolution[level].Ly.ptr<float>(y2)+x2);
|
||||
res1 = *(evolution[level].Ly.ptr<float>(y1, x1));
|
||||
res2 = *(evolution[level].Ly.ptr<float>(y1, x2));
|
||||
res3 = *(evolution[level].Ly.ptr<float>(y2, x1));
|
||||
res4 = *(evolution[level].Ly.ptr<float>(y2, x2));
|
||||
ry = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4;
|
||||
|
||||
// Get the x and y derivatives on the rotated axis
|
||||
@@ -1228,12 +1235,20 @@ void MLDB_Full_Descriptor_Invoker::MLDB_Fill_Values(float* values, int sample_st
|
||||
int y1 = fRound(sample_y);
|
||||
int x1 = fRound(sample_x);
|
||||
|
||||
float ri = *(evolution[level].Lt.ptr<float>(y1)+x1);
|
||||
// fix crash: indexing with out-of-bounds index, this might happen near the edges of image
|
||||
// clip values so they fit into the image
|
||||
const MatSize& size = evolution[level].Lt.size;
|
||||
CV_DbgAssert(size == evolution[level].Lx.size &&
|
||||
size == evolution[level].Ly.size);
|
||||
y1 = min(max(0, y1), size[0] - 1);
|
||||
x1 = min(max(0, x1), size[1] - 1);
|
||||
|
||||
float ri = *(evolution[level].Lt.ptr<float>(y1, x1));
|
||||
di += ri;
|
||||
|
||||
if(chan > 1) {
|
||||
float rx = *(evolution[level].Lx.ptr<float>(y1)+x1);
|
||||
float ry = *(evolution[level].Ly.ptr<float>(y1)+x1);
|
||||
float rx = *(evolution[level].Lx.ptr<float>(y1, x1));
|
||||
float ry = *(evolution[level].Ly.ptr<float>(y1, x1));
|
||||
if (chan == 2) {
|
||||
dx += sqrtf(rx*rx + ry*ry);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user