Merge pull request #3919 from cbalint13:brisk
This commit is contained in:
commit
a31b29308f
@ -625,6 +625,14 @@
|
|||||||
pages = {430--443},
|
pages = {430--443},
|
||||||
publisher = {Springer}
|
publisher = {Springer}
|
||||||
}
|
}
|
||||||
|
@inproceedings{mair2010_agast,
|
||||||
|
title={Adaptive and Generic Corner Detection Based on the Accelerated Segment Test"},
|
||||||
|
author={"Elmar Mair and Gregory D. Hager and Darius Burschka and Michael Suppa and Gerhard Hirzinger"},
|
||||||
|
year={"2010"},
|
||||||
|
month={"September"},
|
||||||
|
booktitle={"European Conference on Computer Vision (ECCV'10)"},
|
||||||
|
url={"http://www6.in.tum.de/Main/ResearchAgast"
|
||||||
|
}
|
||||||
@ARTICLE{Rubner2000,
|
@ARTICLE{Rubner2000,
|
||||||
author = {Rubner, Yossi and Tomasi, Carlo and Guibas, Leonidas J},
|
author = {Rubner, Yossi and Tomasi, Carlo and Guibas, Leonidas J},
|
||||||
title = {The earth mover's distance as a metric for image retrieval},
|
title = {The earth mover's distance as a metric for image retrieval},
|
||||||
|
@ -222,7 +222,7 @@ class CV_EXPORTS_W BRISK : public Feature2D
|
|||||||
public:
|
public:
|
||||||
/** @brief The BRISK constructor
|
/** @brief The BRISK constructor
|
||||||
|
|
||||||
@param thresh FAST/AGAST detection threshold score.
|
@param thresh AGAST detection threshold score.
|
||||||
@param octaves detection octaves. Use 0 to do single scale.
|
@param octaves detection octaves. Use 0 to do single scale.
|
||||||
@param patternScale apply this scale to the pattern used for sampling the neighbourhood of a
|
@param patternScale apply this scale to the pattern used for sampling the neighbourhood of a
|
||||||
keypoint.
|
keypoint.
|
||||||
@ -408,6 +408,57 @@ public:
|
|||||||
CV_WRAP virtual int getType() const = 0;
|
CV_WRAP virtual int getType() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @overload */
|
||||||
|
CV_EXPORTS void AGAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints,
|
||||||
|
int threshold, bool nonmaxSuppression=true );
|
||||||
|
|
||||||
|
/** @brief Detects corners using the AGAST algorithm
|
||||||
|
|
||||||
|
@param image grayscale image where keypoints (corners) are detected.
|
||||||
|
@param keypoints keypoints detected on the image.
|
||||||
|
@param threshold threshold on difference between intensity of the central pixel and pixels of a
|
||||||
|
circle around this pixel.
|
||||||
|
@param nonmaxSuppression if true, non-maximum suppression is applied to detected corners
|
||||||
|
(keypoints).
|
||||||
|
@param type one of the four neighborhoods as defined in the paper:
|
||||||
|
AgastFeatureDetector::AGAST_5_8, AgastFeatureDetector::AGAST_7_12d,
|
||||||
|
AgastFeatureDetector::AGAST_7_12s, AgastFeatureDetector::OAST_9_16
|
||||||
|
|
||||||
|
Detects corners using the AGAST algorithm by @cite mair2010_agast .
|
||||||
|
|
||||||
|
*/
|
||||||
|
CV_EXPORTS void AGAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints,
|
||||||
|
int threshold, bool nonmaxSuppression, int type );
|
||||||
|
//! @} features2d_main
|
||||||
|
|
||||||
|
//! @addtogroup features2d_main
|
||||||
|
//! @{
|
||||||
|
|
||||||
|
/** @brief Wrapping class for feature detection using the AGAST method. :
|
||||||
|
*/
|
||||||
|
class CV_EXPORTS_W AgastFeatureDetector : public Feature2D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
AGAST_5_8 = 0, AGAST_7_12d = 1, AGAST_7_12s = 2, OAST_9_16 = 3,
|
||||||
|
THRESHOLD = 10000, NONMAX_SUPPRESSION = 10001,
|
||||||
|
};
|
||||||
|
|
||||||
|
CV_WRAP static Ptr<AgastFeatureDetector> create( int threshold=10,
|
||||||
|
bool nonmaxSuppression=true,
|
||||||
|
int type=AgastFeatureDetector::OAST_9_16 );
|
||||||
|
|
||||||
|
CV_WRAP virtual void setThreshold(int threshold) = 0;
|
||||||
|
CV_WRAP virtual int getThreshold() const = 0;
|
||||||
|
|
||||||
|
CV_WRAP virtual void setNonmaxSuppression(bool f) = 0;
|
||||||
|
CV_WRAP virtual bool getNonmaxSuppression() const = 0;
|
||||||
|
|
||||||
|
CV_WRAP virtual void setType(int type) = 0;
|
||||||
|
CV_WRAP virtual int getType() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/** @brief Wrapping class for feature detection using the goodFeaturesToTrack function. :
|
/** @brief Wrapping class for feature detection using the goodFeaturesToTrack function. :
|
||||||
*/
|
*/
|
||||||
class CV_EXPORTS_W GFTTDetector : public Feature2D
|
class CV_EXPORTS_W GFTTDetector : public Feature2D
|
||||||
|
42
modules/features2d/perf/perf_agast.cpp
Normal file
42
modules/features2d/perf/perf_agast.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include "perf_precomp.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
using namespace perf;
|
||||||
|
using std::tr1::make_tuple;
|
||||||
|
using std::tr1::get;
|
||||||
|
|
||||||
|
enum { AGAST_5_8 = AgastFeatureDetector::AGAST_5_8, AGAST_7_12d = AgastFeatureDetector::AGAST_7_12d,
|
||||||
|
AGAST_7_12s = AgastFeatureDetector::AGAST_7_12s, OAST_9_16 = AgastFeatureDetector::OAST_9_16 };
|
||||||
|
CV_ENUM(AgastType, AGAST_5_8, AGAST_7_12d,
|
||||||
|
AGAST_7_12s, OAST_9_16)
|
||||||
|
|
||||||
|
typedef std::tr1::tuple<string, AgastType> File_Type_t;
|
||||||
|
typedef perf::TestBaseWithParam<File_Type_t> agast;
|
||||||
|
|
||||||
|
#define AGAST_IMAGES \
|
||||||
|
"cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\
|
||||||
|
"stitching/a3.png"
|
||||||
|
|
||||||
|
PERF_TEST_P(agast, detect, testing::Combine(
|
||||||
|
testing::Values(AGAST_IMAGES),
|
||||||
|
AgastType::all()
|
||||||
|
))
|
||||||
|
{
|
||||||
|
string filename = getDataPath(get<0>(GetParam()));
|
||||||
|
int type = get<1>(GetParam());
|
||||||
|
Mat frame = imread(filename, IMREAD_GRAYSCALE);
|
||||||
|
|
||||||
|
if (frame.empty())
|
||||||
|
FAIL() << "Unable to load source image " << filename;
|
||||||
|
|
||||||
|
declare.in(frame);
|
||||||
|
|
||||||
|
Ptr<FeatureDetector> fd = AgastFeatureDetector::create(70, true, type);
|
||||||
|
ASSERT_FALSE( fd.empty() );
|
||||||
|
vector<KeyPoint> points;
|
||||||
|
|
||||||
|
TEST_CYCLE() fd->detect(frame, points);
|
||||||
|
|
||||||
|
SANITY_CHECK_KEYPOINTS(points);
|
||||||
|
}
|
7671
modules/features2d/src/agast.cpp
Normal file
7671
modules/features2d/src/agast.cpp
Normal file
File diff suppressed because it is too large
Load Diff
9375
modules/features2d/src/agast_score.cpp
Normal file
9375
modules/features2d/src/agast_score.cpp
Normal file
File diff suppressed because it is too large
Load Diff
62
modules/features2d/src/agast_score.hpp
Normal file
62
modules/features2d/src/agast_score.hpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/* This is AGAST and OAST, an optimal and accelerated corner detector
|
||||||
|
based on the accelerated segment tests
|
||||||
|
Below is the original copyright and the references */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (C) 2010 Elmar Mair
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
*Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
*Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
*Neither the name of the University of Cambridge nor the names of
|
||||||
|
its contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The references are:
|
||||||
|
* Adaptive and Generic Corner Detection Based on the Accelerated Segment Test,
|
||||||
|
Elmar Mair and Gregory D. Hager and Darius Burschka
|
||||||
|
and Michael Suppa and Gerhard Hirzinger ECCV 2010
|
||||||
|
URL: http://www6.in.tum.de/Main/ResearchAgast
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __OPENCV_FEATURES_2D_AGAST_HPP__
|
||||||
|
#define __OPENCV_FEATURES_2D_AGAST_HPP__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "precomp.hpp"
|
||||||
|
namespace cv
|
||||||
|
{
|
||||||
|
|
||||||
|
void makeAgastOffsets(int pixel[16], int row_stride, int type);
|
||||||
|
|
||||||
|
template<int type>
|
||||||
|
int agast_cornerScore(const uchar* ptr, const int pixel[], int threshold);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
@ -46,7 +46,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "fast_score.hpp"
|
#include "agast_score.hpp"
|
||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
@ -157,7 +157,7 @@ public:
|
|||||||
// derive a layer
|
// derive a layer
|
||||||
BriskLayer(const BriskLayer& layer, int mode);
|
BriskLayer(const BriskLayer& layer, int mode);
|
||||||
|
|
||||||
// Fast/Agast without non-max suppression
|
// Agast without non-max suppression
|
||||||
void
|
void
|
||||||
getAgastPoints(int threshold, std::vector<cv::KeyPoint>& keypoints);
|
getAgastPoints(int threshold, std::vector<cv::KeyPoint>& keypoints);
|
||||||
|
|
||||||
@ -204,13 +204,13 @@ private:
|
|||||||
value(const cv::Mat& mat, float xf, float yf, float scale) const;
|
value(const cv::Mat& mat, float xf, float yf, float scale) const;
|
||||||
// the image
|
// the image
|
||||||
cv::Mat img_;
|
cv::Mat img_;
|
||||||
// its Fast scores
|
// its Agast scores
|
||||||
cv::Mat_<uchar> scores_;
|
cv::Mat_<uchar> scores_;
|
||||||
// coordinate transformation
|
// coordinate transformation
|
||||||
float scale_;
|
float scale_;
|
||||||
float offset_;
|
float offset_;
|
||||||
// agast
|
// agast
|
||||||
cv::Ptr<cv::FastFeatureDetector> fast_9_16_;
|
cv::Ptr<cv::AgastFeatureDetector> oast_9_16_;
|
||||||
int pixel_5_8_[25];
|
int pixel_5_8_[25];
|
||||||
int pixel_9_16_[25];
|
int pixel_9_16_[25];
|
||||||
};
|
};
|
||||||
@ -618,8 +618,6 @@ BRISK_Impl::detectAndCompute( InputArray _image, InputArray _mask, std::vector<K
|
|||||||
OutputArray _descriptors, bool useProvidedKeypoints)
|
OutputArray _descriptors, bool useProvidedKeypoints)
|
||||||
{
|
{
|
||||||
bool doOrientation=true;
|
bool doOrientation=true;
|
||||||
if (useProvidedKeypoints)
|
|
||||||
doOrientation = false;
|
|
||||||
|
|
||||||
// If the user specified cv::noArray(), this will yield false. Otherwise it will return true.
|
// If the user specified cv::noArray(), this will yield false. Otherwise it will return true.
|
||||||
bool doDescriptors = _descriptors.needed();
|
bool doDescriptors = _descriptors.needed();
|
||||||
@ -733,8 +731,12 @@ BRISK_Impl::computeDescriptorsAndOrOrientation(InputArray _image, InputArray _ma
|
|||||||
direction1 += tmp1;
|
direction1 += tmp1;
|
||||||
}
|
}
|
||||||
kp.angle = (float)(atan2((float) direction1, (float) direction0) / CV_PI * 180.0);
|
kp.angle = (float)(atan2((float) direction1, (float) direction0) / CV_PI * 180.0);
|
||||||
if (kp.angle < 0)
|
|
||||||
kp.angle += 360.f;
|
if (!doDescriptors)
|
||||||
|
{
|
||||||
|
if (kp.angle < 0)
|
||||||
|
kp.angle += 360.f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!doDescriptors)
|
if (!doDescriptors)
|
||||||
@ -755,6 +757,9 @@ BRISK_Impl::computeDescriptorsAndOrOrientation(InputArray _image, InputArray _ma
|
|||||||
theta -= n_rot_;
|
theta -= n_rot_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (kp.angle < 0)
|
||||||
|
kp.angle += 360.f;
|
||||||
|
|
||||||
// now also extract the stuff for the actual direction:
|
// now also extract the stuff for the actual direction:
|
||||||
// let us compute the smoothed values
|
// let us compute the smoothed values
|
||||||
int shifter = 0;
|
int shifter = 0;
|
||||||
@ -867,7 +872,7 @@ BriskScaleSpace::getKeypoints(const int threshold_, std::vector<cv::KeyPoint>& k
|
|||||||
std::vector<std::vector<cv::KeyPoint> > agastPoints;
|
std::vector<std::vector<cv::KeyPoint> > agastPoints;
|
||||||
agastPoints.resize(layers_);
|
agastPoints.resize(layers_);
|
||||||
|
|
||||||
// go through the octaves and intra layers and calculate fast corner scores:
|
// go through the octaves and intra layers and calculate agast corner scores:
|
||||||
for (int i = 0; i < layers_; i++)
|
for (int i = 0; i < layers_; i++)
|
||||||
{
|
{
|
||||||
// call OAST16_9 without nms
|
// call OAST16_9 without nms
|
||||||
@ -2067,9 +2072,9 @@ BriskLayer::BriskLayer(const cv::Mat& img_in, float scale_in, float offset_in)
|
|||||||
scale_ = scale_in;
|
scale_ = scale_in;
|
||||||
offset_ = offset_in;
|
offset_ = offset_in;
|
||||||
// create an agast detector
|
// create an agast detector
|
||||||
fast_9_16_ = FastFeatureDetector::create(1, true, FastFeatureDetector::TYPE_9_16);
|
oast_9_16_ = AgastFeatureDetector::create(1, false, AgastFeatureDetector::OAST_9_16);
|
||||||
makeOffsets(pixel_5_8_, (int)img_.step, 8);
|
makeAgastOffsets(pixel_5_8_, (int)img_.step, AgastFeatureDetector::AGAST_5_8);
|
||||||
makeOffsets(pixel_9_16_, (int)img_.step, 16);
|
makeAgastOffsets(pixel_9_16_, (int)img_.step, AgastFeatureDetector::OAST_9_16);
|
||||||
}
|
}
|
||||||
// derive a layer
|
// derive a layer
|
||||||
BriskLayer::BriskLayer(const BriskLayer& layer, int mode)
|
BriskLayer::BriskLayer(const BriskLayer& layer, int mode)
|
||||||
@ -2089,18 +2094,18 @@ BriskLayer::BriskLayer(const BriskLayer& layer, int mode)
|
|||||||
offset_ = 0.5f * scale_ - 0.5f;
|
offset_ = 0.5f * scale_ - 0.5f;
|
||||||
}
|
}
|
||||||
scores_ = cv::Mat::zeros(img_.rows, img_.cols, CV_8U);
|
scores_ = cv::Mat::zeros(img_.rows, img_.cols, CV_8U);
|
||||||
fast_9_16_ = FastFeatureDetector::create(1, false, FastFeatureDetector::TYPE_9_16);
|
oast_9_16_ = AgastFeatureDetector::create(1, false, AgastFeatureDetector::OAST_9_16);
|
||||||
makeOffsets(pixel_5_8_, (int)img_.step, 8);
|
makeAgastOffsets(pixel_5_8_, (int)img_.step, AgastFeatureDetector::AGAST_5_8);
|
||||||
makeOffsets(pixel_9_16_, (int)img_.step, 16);
|
makeAgastOffsets(pixel_9_16_, (int)img_.step, AgastFeatureDetector::OAST_9_16);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fast/Agast
|
// Agast
|
||||||
// wraps the agast class
|
// wraps the agast class
|
||||||
void
|
void
|
||||||
BriskLayer::getAgastPoints(int threshold, std::vector<KeyPoint>& keypoints)
|
BriskLayer::getAgastPoints(int threshold, std::vector<KeyPoint>& keypoints)
|
||||||
{
|
{
|
||||||
fast_9_16_->setThreshold(threshold);
|
oast_9_16_->setThreshold(threshold);
|
||||||
fast_9_16_->detect(img_, keypoints);
|
oast_9_16_->detect(img_, keypoints);
|
||||||
|
|
||||||
// also write scores
|
// also write scores
|
||||||
const size_t num = keypoints.size();
|
const size_t num = keypoints.size();
|
||||||
@ -2121,7 +2126,7 @@ BriskLayer::getAgastScore(int x, int y, int threshold) const
|
|||||||
{
|
{
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
score = (uchar)cornerScore<16>(&img_.at<uchar>(y, x), pixel_9_16_, threshold - 1);
|
score = (uchar)agast_cornerScore<AgastFeatureDetector::OAST_9_16>(&img_.at<uchar>(y, x), pixel_9_16_, threshold - 1);
|
||||||
if (score < threshold)
|
if (score < threshold)
|
||||||
score = 0;
|
score = 0;
|
||||||
return score;
|
return score;
|
||||||
@ -2134,7 +2139,7 @@ BriskLayer::getAgastScore_5_8(int x, int y, int threshold) const
|
|||||||
return 0;
|
return 0;
|
||||||
if (x >= img_.cols - 2 || y >= img_.rows - 2)
|
if (x >= img_.cols - 2 || y >= img_.rows - 2)
|
||||||
return 0;
|
return 0;
|
||||||
int score = cornerScore<8>(&img_.at<uchar>(y, x), pixel_5_8_, threshold - 1);
|
int score = agast_cornerScore<AgastFeatureDetector::AGAST_5_8>(&img_.at<uchar>(y, x), pixel_5_8_, threshold - 1);
|
||||||
if (score < threshold)
|
if (score < threshold)
|
||||||
score = 0;
|
score = 0;
|
||||||
return score;
|
return score;
|
||||||
|
137
modules/features2d/test/test_agast.cpp
Normal file
137
modules/features2d/test/test_agast.cpp
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||||
|
//
|
||||||
|
// By downloading, copying, installing or using the software you agree to this license.
|
||||||
|
// If you do not agree to this license, do not download, install,
|
||||||
|
// copy or use the software.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// License Agreement
|
||||||
|
// For Open Source Computer Vision Library
|
||||||
|
//
|
||||||
|
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||||
|
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||||
|
// Third party copyrights are property of their respective owners.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistribution's of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// * The name of the copyright holders may not be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// This software is provided by the copyright holders and contributors "as is" and
|
||||||
|
// any express or implied warranties, including, but not limited to, the implied
|
||||||
|
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||||
|
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||||
|
// indirect, incidental, special, exemplary, or consequential damages
|
||||||
|
// (including, but not limited to, procurement of substitute goods or services;
|
||||||
|
// loss of use, data, or profits; or business interruption) however caused
|
||||||
|
// and on any theory of liability, whether in contract, strict liability,
|
||||||
|
// or tort (including negligence or otherwise) arising in any way out of
|
||||||
|
// the use of this software, even if advised of the possibility of such damage.
|
||||||
|
//
|
||||||
|
//M*/
|
||||||
|
|
||||||
|
#include "test_precomp.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
class CV_AgastTest : public cvtest::BaseTest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CV_AgastTest();
|
||||||
|
~CV_AgastTest();
|
||||||
|
protected:
|
||||||
|
void run(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
CV_AgastTest::CV_AgastTest() {}
|
||||||
|
CV_AgastTest::~CV_AgastTest() {}
|
||||||
|
|
||||||
|
void CV_AgastTest::run( int )
|
||||||
|
{
|
||||||
|
for(int type=0; type <= 2; ++type) {
|
||||||
|
Mat image1 = imread(string(ts->get_data_path()) + "inpaint/orig.png");
|
||||||
|
Mat image2 = imread(string(ts->get_data_path()) + "cameracalibration/chess9.png");
|
||||||
|
string xml = string(ts->get_data_path()) + format("agast/result%d.xml", type);
|
||||||
|
|
||||||
|
if (image1.empty() || image2.empty())
|
||||||
|
{
|
||||||
|
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mat gray1, gray2;
|
||||||
|
cvtColor(image1, gray1, COLOR_BGR2GRAY);
|
||||||
|
cvtColor(image2, gray2, COLOR_BGR2GRAY);
|
||||||
|
|
||||||
|
vector<KeyPoint> keypoints1;
|
||||||
|
vector<KeyPoint> keypoints2;
|
||||||
|
AGAST(gray1, keypoints1, 30, true, type);
|
||||||
|
AGAST(gray2, keypoints2, (type > 0 ? 30 : 20), true, type);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < keypoints1.size(); ++i)
|
||||||
|
{
|
||||||
|
const KeyPoint& kp = keypoints1[i];
|
||||||
|
cv::circle(image1, kp.pt, cvRound(kp.size/2), Scalar(255, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i = 0; i < keypoints2.size(); ++i)
|
||||||
|
{
|
||||||
|
const KeyPoint& kp = keypoints2[i];
|
||||||
|
cv::circle(image2, kp.pt, cvRound(kp.size/2), Scalar(255, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
Mat kps1(1, (int)(keypoints1.size() * sizeof(KeyPoint)), CV_8U, &keypoints1[0]);
|
||||||
|
Mat kps2(1, (int)(keypoints2.size() * sizeof(KeyPoint)), CV_8U, &keypoints2[0]);
|
||||||
|
|
||||||
|
FileStorage fs(xml, FileStorage::READ);
|
||||||
|
if (!fs.isOpened())
|
||||||
|
{
|
||||||
|
fs.open(xml, FileStorage::WRITE);
|
||||||
|
if (!fs.isOpened())
|
||||||
|
{
|
||||||
|
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fs << "exp_kps1" << kps1;
|
||||||
|
fs << "exp_kps2" << kps2;
|
||||||
|
fs.release();
|
||||||
|
fs.open(xml, FileStorage::READ);
|
||||||
|
if (!fs.isOpened())
|
||||||
|
{
|
||||||
|
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mat exp_kps1, exp_kps2;
|
||||||
|
read( fs["exp_kps1"], exp_kps1, Mat() );
|
||||||
|
read( fs["exp_kps2"], exp_kps2, Mat() );
|
||||||
|
fs.release();
|
||||||
|
|
||||||
|
if ( exp_kps1.size != kps1.size || 0 != cvtest::norm(exp_kps1, kps1, NORM_L2) ||
|
||||||
|
exp_kps2.size != kps2.size || 0 != cvtest::norm(exp_kps2, kps2, NORM_L2))
|
||||||
|
{
|
||||||
|
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*cv::namedWindow("Img1"); cv::imshow("Img1", image1);
|
||||||
|
cv::namedWindow("Img2"); cv::imshow("Img2", image2);
|
||||||
|
cv::waitKey(0);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
ts->set_failed_test_info(cvtest::TS::OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Features2d_AGAST, regression) { CV_AgastTest test; test.safe_run(); }
|
@ -259,6 +259,12 @@ TEST( Features2d_Detector_FAST, regression )
|
|||||||
test.safe_run();
|
test.safe_run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST( Features2d_Detector_AGAST, regression )
|
||||||
|
{
|
||||||
|
CV_FeatureDetectorTest test( "detector-agast", AgastFeatureDetector::create() );
|
||||||
|
test.safe_run();
|
||||||
|
}
|
||||||
|
|
||||||
TEST( Features2d_Detector_GFTT, regression )
|
TEST( Features2d_Detector_GFTT, regression )
|
||||||
{
|
{
|
||||||
CV_FeatureDetectorTest test( "detector-gftt", GFTTDetector::create() );
|
CV_FeatureDetectorTest test( "detector-gftt", GFTTDetector::create() );
|
||||||
|
@ -131,6 +131,12 @@ TEST(Features2d_Detector_Keypoints_FAST, validation)
|
|||||||
test.safe_run();
|
test.safe_run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Features2d_Detector_Keypoints_AGAST, validation)
|
||||||
|
{
|
||||||
|
CV_FeatureDetectorKeypointsTest test(AgastFeatureDetector::create());
|
||||||
|
test.safe_run();
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Features2d_Detector_Keypoints_HARRIS, validation)
|
TEST(Features2d_Detector_Keypoints_HARRIS, validation)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user