Added BruteForce nearest neighbor (with GPU option), which is now the default for binary descriptors
CMake: Detecting if openCV is built with nonfree module, if yes, SIFT and SURF can be used git-svn-id: http://find-object.googlecode.com/svn/trunk/find_object@411 620bd6b2-0a58-f614-fd9a-1bd335dccda9
This commit is contained in:
parent
783173bf43
commit
4d3b9e88b2
@ -84,6 +84,10 @@ FIND_PACKAGE(OpenCV REQUIRED) # tested on 2.3.1
|
||||
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED) # tested on Qt4.8
|
||||
ADD_DEFINITIONS(-DQT_NO_KEYWORDS) # To avoid conflicts with boost signals used in ROS
|
||||
|
||||
IF(OPENCV_NONFREE_FOUND)
|
||||
ADD_DEFINITIONS(-DWITH_NONFREE)
|
||||
ENDIF(OPENCV_NONFREE_FOUND)
|
||||
|
||||
####### OSX BUNDLE CMAKE_INSTALL_PREFIX #######
|
||||
IF(APPLE)
|
||||
OPTION(BUILD_AS_BUNDLE "Set to ON to build as bundle (DragNDrop)" OFF)
|
||||
@ -218,6 +222,11 @@ MESSAGE(STATUS "--------------------------------------------")
|
||||
MESSAGE(STATUS "Info :")
|
||||
MESSAGE(STATUS " CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")
|
||||
MESSAGE(STATUS " CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
|
||||
IF(OPENCV_NONFREE_FOUND)
|
||||
MESSAGE(STATUS " With OpenCV nonfree module (SIFT/SURF) = YES")
|
||||
ELSE()
|
||||
MESSAGE(STATUS " With OpenCV nonfree module (SIFT/SURF) = NO (not found)")
|
||||
ENDIF()
|
||||
IF(APPLE)
|
||||
MESSAGE(STATUS " BUILD_AS_BUNDLE = ${BUILD_AS_BUNDLE}")
|
||||
ENDIF(APPLE)
|
||||
|
||||
@ -94,8 +94,13 @@ class FINDOBJECT_EXP Settings
|
||||
PARAMETER(Camera, 9queueSize, int, 1, "Maximum images buffered from TCP. If 0, all images are buffered.");
|
||||
|
||||
//List format : [Index:item0;item1;item3;...]
|
||||
#ifdef WITH_NONFREE
|
||||
PARAMETER(Feature2D, 1Detector, QString, "7:Dense;Fast;GFTT;MSER;ORB;SIFT;Star;SURF;BRISK" , "Keypoint detector.");
|
||||
PARAMETER(Feature2D, 2Descriptor, QString, "3:Brief;ORB;SIFT;SURF;BRISK;FREAK", "Keypoint descriptor.");
|
||||
#else
|
||||
PARAMETER(Feature2D, 1Detector, QString, "1:Dense;Fast;GFTT;MSER;ORB;Star;BRISK" , "Keypoint detector.");
|
||||
PARAMETER(Feature2D, 2Descriptor, QString, "0:Brief;ORB;BRISK;FREAK", "Keypoint descriptor.");
|
||||
#endif
|
||||
PARAMETER(Feature2D, 3MaxFeatures, int, 0, "Maximum features per image. If the number of features extracted is over this threshold, only X features with the highest response are kept. 0 means all features are kept.");
|
||||
PARAMETER(Feature2D, 4Affine, bool, false, "(ASIFT) Extract features on multiple affine transformations of the image.");
|
||||
PARAMETER(Feature2D, 5AffineCount, int, 6, "(ASIFT) Higher the value, more affine transformations will be done.");
|
||||
@ -142,18 +147,13 @@ class FINDOBJECT_EXP Settings
|
||||
PARAMETER(Feature2D, MSER_minMargin, double, 0.003, "");
|
||||
PARAMETER(Feature2D, MSER_edgeBlurSize, int, 5, "");
|
||||
|
||||
#ifdef WITH_NONFREE
|
||||
PARAMETER(Feature2D, SIFT_nfeatures, int, 0, "The number of best features to retain. The features are ranked by their scores (measured in SIFT algorithm as the local contrast).");
|
||||
PARAMETER(Feature2D, SIFT_nOctaveLayers, int, 3, "The number of layers in each octave. 3 is the value used in D. Lowe paper. The number of octaves is computed automatically from the image resolution.");
|
||||
PARAMETER(Feature2D, SIFT_contrastThreshold, double, 0.04, "The contrast threshold used to filter out weak features in semi-uniform (low-contrast) regions. The larger the threshold, the less features are produced by the detector.");
|
||||
PARAMETER(Feature2D, SIFT_edgeThreshold, double, 10, "The threshold used to filter out edge-like features. Note that the its meaning is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are filtered out (more features are retained).");
|
||||
PARAMETER(Feature2D, SIFT_sigma, double, 1.6, "The sigma of the Gaussian applied to the input image at the octave #0. If your image is captured with a weak camera with soft lenses, you might want to reduce the number.");
|
||||
|
||||
PARAMETER(Feature2D, Star_maxSize, int, 45, "");
|
||||
PARAMETER(Feature2D, Star_responseThreshold, int, 30, "");
|
||||
PARAMETER(Feature2D, Star_lineThresholdProjected, int, 10, "");
|
||||
PARAMETER(Feature2D, Star_lineThresholdBinarized, int, 8, "");
|
||||
PARAMETER(Feature2D, Star_suppressNonmaxSize, int, 5, "");
|
||||
|
||||
PARAMETER(Feature2D, SURF_hessianThreshold, double, 600.0, "Threshold for hessian keypoint detector used in SURF.");
|
||||
PARAMETER(Feature2D, SURF_nOctaves, int, 4, "Number of pyramid octaves the keypoint detector will use.");
|
||||
PARAMETER(Feature2D, SURF_nOctaveLayers, int, 2, "Number of octave layers within each octave.");
|
||||
@ -161,6 +161,13 @@ class FINDOBJECT_EXP Settings
|
||||
PARAMETER(Feature2D, SURF_upright, bool, false, "Up-right or rotated features flag (true - do not compute orientation of features; false - compute orientation).");
|
||||
PARAMETER(Feature2D, SURF_gpu, bool, false, "GPU-SURF: Use GPU version of SURF. This option is enabled only if OpenCV is built with CUDA and GPUs are detected.");
|
||||
PARAMETER(Feature2D, SURF_keypointsRatio, float, 0.01f, "Used with SURF GPU.");
|
||||
#endif
|
||||
|
||||
PARAMETER(Feature2D, Star_maxSize, int, 45, "");
|
||||
PARAMETER(Feature2D, Star_responseThreshold, int, 30, "");
|
||||
PARAMETER(Feature2D, Star_lineThresholdProjected, int, 10, "");
|
||||
PARAMETER(Feature2D, Star_lineThresholdBinarized, int, 8, "");
|
||||
PARAMETER(Feature2D, Star_suppressNonmaxSize, int, 5, "");
|
||||
|
||||
PARAMETER(Feature2D, BRISK_thresh, int, 30, "FAST/AGAST detection threshold score.");
|
||||
PARAMETER(Feature2D, BRISK_octaves, int, 3, "Detection octaves. Use 0 to do single scale.");
|
||||
@ -171,16 +178,23 @@ class FINDOBJECT_EXP Settings
|
||||
PARAMETER(Feature2D, FREAK_patternScale, float, 22.0f, "Scaling of the description pattern.");
|
||||
PARAMETER(Feature2D, FREAK_nOctaves, int, 4, "Number of octaves covered by the detected keypoints.");
|
||||
|
||||
PARAMETER(NearestNeighbor, 1Strategy, QString, "1:Linear;KDTree;KMeans;Composite;Autotuned;Lsh", "Nearest neighbor strategy.");
|
||||
#ifdef WITH_NONFREE
|
||||
PARAMETER(NearestNeighbor, 1Strategy, QString, "1:Linear;KDTree;KMeans;Composite;Autotuned;Lsh;BruteForce", "Nearest neighbor strategy.");
|
||||
PARAMETER(NearestNeighbor, 2Distance_type, QString, "0:EUCLIDEAN_L2;MANHATTAN_L1;MINKOWSKI;MAX;HIST_INTERSECT;HELLINGER;CHI_SQUARE_CS;KULLBACK_LEIBLER_KL;HAMMING", "Distance type.");
|
||||
#else
|
||||
PARAMETER(NearestNeighbor, 1Strategy, QString, "6:Linear;KDTree;KMeans;Composite;Autotuned;Lsh;BruteForce", "Nearest neighbor strategy.");
|
||||
PARAMETER(NearestNeighbor, 2Distance_type, QString, "1:EUCLIDEAN_L2;MANHATTAN_L1;MINKOWSKI;MAX;HIST_INTERSECT;HELLINGER;CHI_SQUARE_CS;KULLBACK_LEIBLER_KL;HAMMING", "Distance type.");
|
||||
#endif
|
||||
PARAMETER(NearestNeighbor, 3nndrRatioUsed, bool, true, "Nearest neighbor distance ratio approach to accept the best match.");
|
||||
PARAMETER(NearestNeighbor, 4nndrRatio, float, 0.8f, "Nearest neighbor distance ratio.");
|
||||
PARAMETER(NearestNeighbor, 5minDistanceUsed, bool, false, "Minimum distance with the nearest descriptor to accept a match.");
|
||||
PARAMETER(NearestNeighbor, 6minDistance, float, 1.6f, "Minimum distance. You can look at top of this panel where minimum and maximum distances are shown to properly set this parameter depending of the descriptor used.");
|
||||
|
||||
PARAMETER(NearestNeighbor, 7search_checks, int, 32, "The number of times the tree(s) in the index should be recursively traversed. A higher value for this parameter would give better search precision, but also take more time. If automatic configuration was used when the index was created, the number of checks required to achieve the specified precision was also computed, in which case this parameter is ignored.");
|
||||
PARAMETER(NearestNeighbor, 8search_eps, float, 0, "");
|
||||
PARAMETER(NearestNeighbor, 9search_sorted, bool, true, "");
|
||||
PARAMETER(NearestNeighbor, BruteForce_gpu, bool, false, "Brute force GPU");
|
||||
|
||||
PARAMETER(NearestNeighbor, search_checks, int, 32, "The number of times the tree(s) in the index should be recursively traversed. A higher value for this parameter would give better search precision, but also take more time. If automatic configuration was used when the index was created, the number of checks required to achieve the specified precision was also computed, in which case this parameter is ignored.");
|
||||
PARAMETER(NearestNeighbor, search_eps, float, 0, "");
|
||||
PARAMETER(NearestNeighbor, search_sorted, bool, true, "");
|
||||
|
||||
PARAMETER(NearestNeighbor, KDTree_trees, int, 4, "The number of parallel kd-trees to use. Good values are in the range [1..16].");
|
||||
|
||||
@ -261,6 +275,7 @@ public:
|
||||
static QString currentDetectorType();
|
||||
static QString currentNearestNeighborType();
|
||||
|
||||
static bool isBruteForceNearestNeighbor();
|
||||
static cv::flann::IndexParams * createFlannIndexParams();
|
||||
static cvflann::flann_distance_t getFlannDistanceType();
|
||||
static cv::flann::SearchParams getFlannSearchParams();
|
||||
|
||||
@ -135,14 +135,18 @@ MainWindow::MainWindow(FindObject * findObject, Camera * camera, QWidget * paren
|
||||
|
||||
if(cv::gpu::getCudaEnabledDeviceCount() == 0)
|
||||
{
|
||||
#ifdef WITH_NONFREE
|
||||
ui_->toolBox->updateParameter(Settings::kFeature2D_SURF_gpu());
|
||||
ui_->toolBox->updateParameter(Settings::kFeature2D_Fast_gpu());
|
||||
ui_->toolBox->updateParameter(Settings::kFeature2D_ORB_gpu());
|
||||
ui_->toolBox->getParameterWidget(Settings::kFeature2D_SURF_gpu())->setEnabled(false);
|
||||
ui_->toolBox->getParameterWidget(Settings::kFeature2D_SURF_keypointsRatio())->setEnabled(false);
|
||||
#endif
|
||||
ui_->toolBox->updateParameter(Settings::kFeature2D_Fast_gpu());
|
||||
ui_->toolBox->updateParameter(Settings::kFeature2D_ORB_gpu());
|
||||
ui_->toolBox->updateParameter(Settings::kNearestNeighbor_BruteForce_gpu());
|
||||
ui_->toolBox->getParameterWidget(Settings::kFeature2D_Fast_gpu())->setEnabled(false);
|
||||
ui_->toolBox->getParameterWidget(Settings::kFeature2D_Fast_keypointsRatio())->setEnabled(false);
|
||||
ui_->toolBox->getParameterWidget(Settings::kFeature2D_ORB_gpu())->setEnabled(false);
|
||||
ui_->toolBox->getParameterWidget(Settings::kNearestNeighbor_BruteForce_gpu())->setEnabled(false);
|
||||
}
|
||||
|
||||
connect((QDoubleSpinBox*)ui_->toolBox->getParameterWidget(Settings::kCamera_4imageRate()),
|
||||
|
||||
@ -204,6 +204,16 @@ void ParametersToolBox::updateParametersVisibility()
|
||||
else if(!objects[i]->objectName().split('/').at(1).at(0).isDigit())
|
||||
{
|
||||
((QWidget*)objects[i])->setVisible(false);
|
||||
if(nnBox->currentIndex() < 6 && objects[i]->objectName().split('/').at(1).contains("search"))
|
||||
{
|
||||
//show flann search parameters
|
||||
((QWidget*)objects[i])->setVisible(true);
|
||||
}
|
||||
}
|
||||
else if(objects[i]->objectName().split('/').at(1).contains("Distance_type"))
|
||||
{
|
||||
// don't show distance when bruteforce is selected
|
||||
((QWidget*)objects[i])->setVisible(nnBox->currentIndex() != 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -494,16 +504,16 @@ void ParametersToolBox::changeParameter(const int & value)
|
||||
descriptorBox->currentText().compare("Brief") == 0 ||
|
||||
descriptorBox->currentText().compare("BRISK") == 0 ||
|
||||
descriptorBox->currentText().compare("FREAK") == 0;
|
||||
if(isBinaryDescriptor && nnBox->currentText().compare("Lsh") != 0)
|
||||
if(isBinaryDescriptor && nnBox->currentText().compare("Lsh") != 0 && nnBox->currentText().compare("BruteForce") != 0)
|
||||
{
|
||||
QMessageBox::warning(this,
|
||||
tr("Warning"),
|
||||
tr("Current selected descriptor type (\"%1\") is binary while nearest neighbor strategy is not (\"%2\").\n"
|
||||
"Falling back to \"Lsh\" nearest neighbor strategy with Hamming distance (by default).")
|
||||
"Falling back to \"BruteForce\" nearest neighbor strategy with Hamming distance (by default).")
|
||||
.arg(descriptorBox->currentText())
|
||||
.arg(nnBox->currentText()));
|
||||
QString tmp = Settings::getNearestNeighbor_1Strategy();
|
||||
*tmp.begin() = '5'; // set LSH
|
||||
*tmp.begin() = '6'; // set BruteForce
|
||||
Settings::setNearestNeighbor_1Strategy(tmp);
|
||||
tmp = Settings::getNearestNeighbor_2Distance_type();
|
||||
*tmp.begin() = '8'; // set HAMMING
|
||||
@ -561,7 +571,7 @@ void ParametersToolBox::changeParameter(const int & value)
|
||||
{
|
||||
QComboBox * nnBox = (QComboBox*)this->getParameterWidget(Settings::kNearestNeighbor_1Strategy());
|
||||
QComboBox * distBox = (QComboBox*)this->getParameterWidget(Settings::kNearestNeighbor_2Distance_type());
|
||||
if(nnBox->currentText().compare("Lsh") != 0 && distBox->currentIndex() > 1)
|
||||
if(nnBox->currentText().compare("BruteForce") != 0 && nnBox->currentText().compare("Lsh") != 0 && distBox->currentIndex() > 1)
|
||||
{
|
||||
QMessageBox::warning(this,
|
||||
tr("Warning"),
|
||||
|
||||
496
src/Settings.cpp
496
src/Settings.cpp
@ -33,9 +33,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QDir>
|
||||
#include <stdio.h>
|
||||
#include <opencv2/nonfree/features2d.hpp>
|
||||
#include <opencv2/calib3d/calib3d.hpp>
|
||||
#ifdef WITH_NONFREE
|
||||
#include <opencv2/nonfree/features2d.hpp>
|
||||
#include <opencv2/nonfree/gpu.hpp>
|
||||
#endif
|
||||
#include <opencv2/gpu/gpu.hpp>
|
||||
|
||||
namespace find_object {
|
||||
@ -120,9 +122,12 @@ void Settings::loadSettings(const QString & fileName)
|
||||
|
||||
if(cv::gpu::getCudaEnabledDeviceCount() == 0)
|
||||
{
|
||||
#ifdef WITH_NONFREE
|
||||
Settings::setFeature2D_SURF_gpu(false);
|
||||
#endif
|
||||
Settings::setFeature2D_Fast_gpu(false);
|
||||
Settings::setFeature2D_ORB_gpu(false);
|
||||
Settings::setNearestNeighbor_BruteForce_gpu(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,6 +222,7 @@ public:
|
||||
cv::Mat & descriptors) = 0;
|
||||
};
|
||||
|
||||
#ifdef WITH_NONFREE
|
||||
class GPUSURF : public GPUFeature2D
|
||||
{
|
||||
public:
|
||||
@ -291,6 +297,7 @@ public:
|
||||
private:
|
||||
cv::gpu::SURF_GPU surf_; // HACK: static because detectImpl() is const!
|
||||
};
|
||||
#endif
|
||||
|
||||
class GPUFAST : public GPUFeature2D
|
||||
{
|
||||
@ -416,168 +423,151 @@ KeypointDetector * Settings::createKeypointDetector()
|
||||
if(ok)
|
||||
{
|
||||
QStringList strategies = split.last().split(';');
|
||||
#ifdef WITH_NONFREE
|
||||
if(strategies.size() == 9 && index>=0 && index<9)
|
||||
#else
|
||||
if(strategies.size() == 7 && index>=0 && index<7)
|
||||
#endif
|
||||
{
|
||||
switch(index)
|
||||
if(strategies.at(index).compare("Dense") == 0)
|
||||
{
|
||||
case 0:
|
||||
if(strategies.at(index).compare("Dense") == 0)
|
||||
detector = new cv::DenseFeatureDetector(
|
||||
getFeature2D_Dense_initFeatureScale(),
|
||||
getFeature2D_Dense_featureScaleLevels(),
|
||||
getFeature2D_Dense_featureScaleMul(),
|
||||
getFeature2D_Dense_initXyStep(),
|
||||
getFeature2D_Dense_initImgBound(),
|
||||
getFeature2D_Dense_varyXyStepWithScale(),
|
||||
getFeature2D_Dense_varyImgBoundWithScale());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else if(strategies.at(index).compare("Fast") == 0)
|
||||
{
|
||||
if(getFeature2D_Fast_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||
{
|
||||
detector = new cv::DenseFeatureDetector(
|
||||
getFeature2D_Dense_initFeatureScale(),
|
||||
getFeature2D_Dense_featureScaleLevels(),
|
||||
getFeature2D_Dense_featureScaleMul(),
|
||||
getFeature2D_Dense_initXyStep(),
|
||||
getFeature2D_Dense_initImgBound(),
|
||||
getFeature2D_Dense_varyXyStepWithScale(),
|
||||
getFeature2D_Dense_varyImgBoundWithScale());
|
||||
detectorGPU = new GPUFAST(
|
||||
getFeature2D_Fast_threshold(),
|
||||
getFeature2D_Fast_nonmaxSuppression());
|
||||
UDEBUG("type=%s GPU", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
detector = new cv::FastFeatureDetector(
|
||||
getFeature2D_Fast_threshold(),
|
||||
getFeature2D_Fast_nonmaxSuppression());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if(strategies.at(index).compare("Fast") == 0)
|
||||
}
|
||||
else if(strategies.at(index).compare("GFTT") == 0)
|
||||
{
|
||||
detector = new cv::GFTTDetector(
|
||||
getFeature2D_GFTT_maxCorners(),
|
||||
getFeature2D_GFTT_qualityLevel(),
|
||||
getFeature2D_GFTT_minDistance(),
|
||||
getFeature2D_GFTT_blockSize(),
|
||||
getFeature2D_GFTT_useHarrisDetector(),
|
||||
getFeature2D_GFTT_k());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else if(strategies.at(index).compare("MSER") == 0)
|
||||
{
|
||||
detector = new cv::MSER(
|
||||
getFeature2D_MSER_delta(),
|
||||
getFeature2D_MSER_minArea(),
|
||||
getFeature2D_MSER_maxArea(),
|
||||
getFeature2D_MSER_maxVariation(),
|
||||
getFeature2D_MSER_minDiversity(),
|
||||
getFeature2D_MSER_maxEvolution(),
|
||||
getFeature2D_MSER_areaThreshold(),
|
||||
getFeature2D_MSER_minMargin(),
|
||||
getFeature2D_MSER_edgeBlurSize());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else if(strategies.at(index).compare("ORB") == 0)
|
||||
{
|
||||
if(getFeature2D_ORB_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||
{
|
||||
if(getFeature2D_Fast_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||
{
|
||||
detectorGPU = new GPUFAST(
|
||||
getFeature2D_Fast_threshold(),
|
||||
getFeature2D_Fast_nonmaxSuppression());
|
||||
UDEBUG("type=%s GPU", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
detector = new cv::FastFeatureDetector(
|
||||
getFeature2D_Fast_threshold(),
|
||||
getFeature2D_Fast_nonmaxSuppression());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
detectorGPU = new GPUORB(
|
||||
getFeature2D_ORB_nFeatures(),
|
||||
getFeature2D_ORB_scaleFactor(),
|
||||
getFeature2D_ORB_nLevels(),
|
||||
getFeature2D_ORB_edgeThreshold(),
|
||||
getFeature2D_ORB_firstLevel(),
|
||||
getFeature2D_ORB_WTA_K(),
|
||||
getFeature2D_ORB_scoreType(),
|
||||
getFeature2D_ORB_patchSize(),
|
||||
getFeature2D_Fast_threshold(),
|
||||
getFeature2D_Fast_nonmaxSuppression());
|
||||
UDEBUG("type=%s (GPU)", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(strategies.at(index).compare("GFTT") == 0)
|
||||
else
|
||||
{
|
||||
detector = new cv::GFTTDetector(
|
||||
getFeature2D_GFTT_maxCorners(),
|
||||
getFeature2D_GFTT_qualityLevel(),
|
||||
getFeature2D_GFTT_minDistance(),
|
||||
getFeature2D_GFTT_blockSize(),
|
||||
getFeature2D_GFTT_useHarrisDetector(),
|
||||
getFeature2D_GFTT_k());
|
||||
detector = new cv::ORB(
|
||||
getFeature2D_ORB_nFeatures(),
|
||||
getFeature2D_ORB_scaleFactor(),
|
||||
getFeature2D_ORB_nLevels(),
|
||||
getFeature2D_ORB_edgeThreshold(),
|
||||
getFeature2D_ORB_firstLevel(),
|
||||
getFeature2D_ORB_WTA_K(),
|
||||
getFeature2D_ORB_scoreType(),
|
||||
getFeature2D_ORB_patchSize());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if(strategies.at(index).compare("MSER") == 0)
|
||||
}
|
||||
else if(strategies.at(index).compare("Star") == 0)
|
||||
{
|
||||
detector = new cv::StarFeatureDetector(
|
||||
getFeature2D_Star_maxSize(),
|
||||
getFeature2D_Star_responseThreshold(),
|
||||
getFeature2D_Star_lineThresholdProjected(),
|
||||
getFeature2D_Star_lineThresholdBinarized(),
|
||||
getFeature2D_Star_suppressNonmaxSize());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else if(strategies.at(index).compare("BRISK") == 0)
|
||||
{
|
||||
detector = new cv::BRISK(
|
||||
getFeature2D_BRISK_thresh(),
|
||||
getFeature2D_BRISK_octaves(),
|
||||
getFeature2D_BRISK_patternScale());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
#ifdef WITH_NONFREE
|
||||
else if(strategies.at(index).compare("SIFT") == 0)
|
||||
{
|
||||
detector = new cv::SIFT(
|
||||
getFeature2D_SIFT_nfeatures(),
|
||||
getFeature2D_SIFT_nOctaveLayers(),
|
||||
getFeature2D_SIFT_contrastThreshold(),
|
||||
getFeature2D_SIFT_edgeThreshold(),
|
||||
getFeature2D_SIFT_sigma());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else if(strategies.at(index).compare("SURF") == 0)
|
||||
{
|
||||
if(getFeature2D_SURF_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||
{
|
||||
detector = new cv::MSER(
|
||||
getFeature2D_MSER_delta(),
|
||||
getFeature2D_MSER_minArea(),
|
||||
getFeature2D_MSER_maxArea(),
|
||||
getFeature2D_MSER_maxVariation(),
|
||||
getFeature2D_MSER_minDiversity(),
|
||||
getFeature2D_MSER_maxEvolution(),
|
||||
getFeature2D_MSER_areaThreshold(),
|
||||
getFeature2D_MSER_minMargin(),
|
||||
getFeature2D_MSER_edgeBlurSize());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if(strategies.at(index).compare("ORB") == 0)
|
||||
{
|
||||
if(getFeature2D_ORB_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||
{
|
||||
detectorGPU = new GPUORB(
|
||||
getFeature2D_ORB_nFeatures(),
|
||||
getFeature2D_ORB_scaleFactor(),
|
||||
getFeature2D_ORB_nLevels(),
|
||||
getFeature2D_ORB_edgeThreshold(),
|
||||
getFeature2D_ORB_firstLevel(),
|
||||
getFeature2D_ORB_WTA_K(),
|
||||
getFeature2D_ORB_scoreType(),
|
||||
getFeature2D_ORB_patchSize(),
|
||||
getFeature2D_Fast_threshold(),
|
||||
getFeature2D_Fast_nonmaxSuppression());
|
||||
UDEBUG("type=%s (GPU)", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
detector = new cv::ORB(
|
||||
getFeature2D_ORB_nFeatures(),
|
||||
getFeature2D_ORB_scaleFactor(),
|
||||
getFeature2D_ORB_nLevels(),
|
||||
getFeature2D_ORB_edgeThreshold(),
|
||||
getFeature2D_ORB_firstLevel(),
|
||||
getFeature2D_ORB_WTA_K(),
|
||||
getFeature2D_ORB_scoreType(),
|
||||
getFeature2D_ORB_patchSize());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if(strategies.at(index).compare("SIFT") == 0)
|
||||
{
|
||||
detector = new cv::SIFT(
|
||||
getFeature2D_SIFT_nfeatures(),
|
||||
getFeature2D_SIFT_nOctaveLayers(),
|
||||
getFeature2D_SIFT_contrastThreshold(),
|
||||
getFeature2D_SIFT_edgeThreshold(),
|
||||
getFeature2D_SIFT_sigma());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if(strategies.at(index).compare("Star") == 0)
|
||||
{
|
||||
detector = new cv::StarFeatureDetector(
|
||||
getFeature2D_Star_maxSize(),
|
||||
getFeature2D_Star_responseThreshold(),
|
||||
getFeature2D_Star_lineThresholdProjected(),
|
||||
getFeature2D_Star_lineThresholdBinarized(),
|
||||
getFeature2D_Star_suppressNonmaxSize());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if(strategies.at(index).compare("SURF") == 0)
|
||||
{
|
||||
if(getFeature2D_SURF_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||
{
|
||||
detectorGPU = new GPUSURF(
|
||||
getFeature2D_SURF_hessianThreshold(),
|
||||
getFeature2D_SURF_nOctaves(),
|
||||
getFeature2D_SURF_nOctaveLayers(),
|
||||
getFeature2D_SURF_extended(),
|
||||
getFeature2D_SURF_keypointsRatio(),
|
||||
getFeature2D_SURF_upright());
|
||||
UDEBUG("type=%s (GPU)", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
detector = new cv::SURF(
|
||||
detectorGPU = new GPUSURF(
|
||||
getFeature2D_SURF_hessianThreshold(),
|
||||
getFeature2D_SURF_nOctaves(),
|
||||
getFeature2D_SURF_nOctaveLayers(),
|
||||
getFeature2D_SURF_extended(),
|
||||
getFeature2D_SURF_keypointsRatio(),
|
||||
getFeature2D_SURF_upright());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
UDEBUG("type=%s (GPU)", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if(strategies.at(index).compare("BRISK") == 0)
|
||||
else
|
||||
{
|
||||
detector = new cv::BRISK(
|
||||
getFeature2D_BRISK_thresh(),
|
||||
getFeature2D_BRISK_octaves(),
|
||||
getFeature2D_BRISK_patternScale());
|
||||
detector = new cv::SURF(
|
||||
getFeature2D_SURF_hessianThreshold(),
|
||||
getFeature2D_SURF_nOctaves(),
|
||||
getFeature2D_SURF_nOctaveLayers(),
|
||||
getFeature2D_SURF_extended(),
|
||||
getFeature2D_SURF_upright());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -606,113 +596,102 @@ DescriptorExtractor * Settings::createDescriptorExtractor()
|
||||
if(ok)
|
||||
{
|
||||
QStringList strategies = split.last().split(';');
|
||||
#ifdef WITH_NONFREE
|
||||
if(strategies.size() == 6 && index>=0 && index<6)
|
||||
#else
|
||||
if(strategies.size() == 4 && index>=0 && index<4)
|
||||
#endif
|
||||
{
|
||||
switch(index)
|
||||
if(strategies.at(index).compare("Brief") == 0)
|
||||
{
|
||||
case 0:
|
||||
if(strategies.at(index).compare("Brief") == 0)
|
||||
{
|
||||
extractor = new cv::BriefDescriptorExtractor(
|
||||
getFeature2D_Brief_bytes());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if(strategies.at(index).compare("ORB") == 0)
|
||||
{
|
||||
if(getFeature2D_ORB_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||
{
|
||||
extractorGPU = new GPUORB(
|
||||
getFeature2D_ORB_nFeatures(),
|
||||
getFeature2D_ORB_scaleFactor(),
|
||||
getFeature2D_ORB_nLevels(),
|
||||
getFeature2D_ORB_edgeThreshold(),
|
||||
getFeature2D_ORB_firstLevel(),
|
||||
getFeature2D_ORB_WTA_K(),
|
||||
getFeature2D_ORB_scoreType(),
|
||||
getFeature2D_ORB_patchSize(),
|
||||
getFeature2D_Fast_threshold(),
|
||||
getFeature2D_Fast_nonmaxSuppression());
|
||||
UDEBUG("type=%s (GPU)", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
extractor = new cv::ORB(
|
||||
getFeature2D_ORB_nFeatures(),
|
||||
getFeature2D_ORB_scaleFactor(),
|
||||
getFeature2D_ORB_nLevels(),
|
||||
getFeature2D_ORB_edgeThreshold(),
|
||||
getFeature2D_ORB_firstLevel(),
|
||||
getFeature2D_ORB_WTA_K(),
|
||||
getFeature2D_ORB_scoreType(),
|
||||
getFeature2D_ORB_patchSize());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(strategies.at(index).compare("SIFT") == 0)
|
||||
{
|
||||
extractor = new cv::SIFT(
|
||||
getFeature2D_SIFT_nfeatures(),
|
||||
getFeature2D_SIFT_nOctaveLayers(),
|
||||
getFeature2D_SIFT_contrastThreshold(),
|
||||
getFeature2D_SIFT_edgeThreshold(),
|
||||
getFeature2D_SIFT_sigma());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if(strategies.at(index).compare("SURF") == 0)
|
||||
{
|
||||
if(getFeature2D_SURF_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||
{
|
||||
extractorGPU = new GPUSURF(
|
||||
getFeature2D_SURF_hessianThreshold(),
|
||||
getFeature2D_SURF_nOctaves(),
|
||||
getFeature2D_SURF_nOctaveLayers(),
|
||||
getFeature2D_SURF_extended(),
|
||||
getFeature2D_SURF_keypointsRatio(),
|
||||
getFeature2D_SURF_upright());
|
||||
UDEBUG("type=%s (GPU)", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
extractor = new cv::SURF(
|
||||
getFeature2D_SURF_hessianThreshold(),
|
||||
getFeature2D_SURF_nOctaves(),
|
||||
getFeature2D_SURF_nOctaveLayers(),
|
||||
getFeature2D_SURF_extended(),
|
||||
getFeature2D_SURF_upright());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if(strategies.at(index).compare("BRISK") == 0)
|
||||
{
|
||||
extractor = new cv::BRISK(
|
||||
getFeature2D_BRISK_thresh(),
|
||||
getFeature2D_BRISK_octaves(),
|
||||
getFeature2D_BRISK_patternScale());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if(strategies.at(index).compare("FREAK") == 0)
|
||||
{
|
||||
extractor = new cv::FREAK(
|
||||
getFeature2D_FREAK_orientationNormalized(),
|
||||
getFeature2D_FREAK_scaleNormalized(),
|
||||
getFeature2D_FREAK_patternScale(),
|
||||
getFeature2D_FREAK_nOctaves());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
extractor = new cv::BriefDescriptorExtractor(
|
||||
getFeature2D_Brief_bytes());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else if(strategies.at(index).compare("ORB") == 0)
|
||||
{
|
||||
if(getFeature2D_ORB_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||
{
|
||||
extractorGPU = new GPUORB(
|
||||
getFeature2D_ORB_nFeatures(),
|
||||
getFeature2D_ORB_scaleFactor(),
|
||||
getFeature2D_ORB_nLevels(),
|
||||
getFeature2D_ORB_edgeThreshold(),
|
||||
getFeature2D_ORB_firstLevel(),
|
||||
getFeature2D_ORB_WTA_K(),
|
||||
getFeature2D_ORB_scoreType(),
|
||||
getFeature2D_ORB_patchSize(),
|
||||
getFeature2D_Fast_threshold(),
|
||||
getFeature2D_Fast_nonmaxSuppression());
|
||||
UDEBUG("type=%s (GPU)", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
extractor = new cv::ORB(
|
||||
getFeature2D_ORB_nFeatures(),
|
||||
getFeature2D_ORB_scaleFactor(),
|
||||
getFeature2D_ORB_nLevels(),
|
||||
getFeature2D_ORB_edgeThreshold(),
|
||||
getFeature2D_ORB_firstLevel(),
|
||||
getFeature2D_ORB_WTA_K(),
|
||||
getFeature2D_ORB_scoreType(),
|
||||
getFeature2D_ORB_patchSize());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
}
|
||||
else if(strategies.at(index).compare("BRISK") == 0)
|
||||
{
|
||||
extractor = new cv::BRISK(
|
||||
getFeature2D_BRISK_thresh(),
|
||||
getFeature2D_BRISK_octaves(),
|
||||
getFeature2D_BRISK_patternScale());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else if(strategies.at(index).compare("FREAK") == 0)
|
||||
{
|
||||
extractor = new cv::FREAK(
|
||||
getFeature2D_FREAK_orientationNormalized(),
|
||||
getFeature2D_FREAK_scaleNormalized(),
|
||||
getFeature2D_FREAK_patternScale(),
|
||||
getFeature2D_FREAK_nOctaves());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
#ifdef WITH_NONFREE
|
||||
else if(strategies.at(index).compare("SIFT") == 0)
|
||||
{
|
||||
extractor = new cv::SIFT(
|
||||
getFeature2D_SIFT_nfeatures(),
|
||||
getFeature2D_SIFT_nOctaveLayers(),
|
||||
getFeature2D_SIFT_contrastThreshold(),
|
||||
getFeature2D_SIFT_edgeThreshold(),
|
||||
getFeature2D_SIFT_sigma());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else if(strategies.at(index).compare("SURF") == 0)
|
||||
{
|
||||
if(getFeature2D_SURF_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||
{
|
||||
extractorGPU = new GPUSURF(
|
||||
getFeature2D_SURF_hessianThreshold(),
|
||||
getFeature2D_SURF_nOctaves(),
|
||||
getFeature2D_SURF_nOctaveLayers(),
|
||||
getFeature2D_SURF_extended(),
|
||||
getFeature2D_SURF_keypointsRatio(),
|
||||
getFeature2D_SURF_upright());
|
||||
UDEBUG("type=%s (GPU)", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
extractor = new cv::SURF(
|
||||
getFeature2D_SURF_hessianThreshold(),
|
||||
getFeature2D_SURF_nOctaves(),
|
||||
getFeature2D_SURF_nOctaveLayers(),
|
||||
getFeature2D_SURF_extended(),
|
||||
getFeature2D_SURF_upright());
|
||||
UDEBUG("type=%s", strategies.at(index).toStdString().c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -746,6 +725,27 @@ QString Settings::currentNearestNeighborType()
|
||||
return getNearestNeighbor_1Strategy().split(':').last().split(';').at(index);
|
||||
}
|
||||
|
||||
bool Settings::isBruteForceNearestNeighbor()
|
||||
{
|
||||
bool bruteForce = false;
|
||||
QString str = getNearestNeighbor_1Strategy();
|
||||
QStringList split = str.split(':');
|
||||
if(split.size()==2)
|
||||
{
|
||||
bool ok = false;
|
||||
int index = split.first().toInt(&ok);
|
||||
if(ok)
|
||||
{
|
||||
QStringList strategies = split.last().split(';');
|
||||
if(strategies.size() >= 7 && index == 6)
|
||||
{
|
||||
bruteForce = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bruteForce;
|
||||
}
|
||||
|
||||
cv::flann::IndexParams * Settings::createFlannIndexParams()
|
||||
{
|
||||
cv::flann::IndexParams * params = 0;
|
||||
@ -758,7 +758,7 @@ cv::flann::IndexParams * Settings::createFlannIndexParams()
|
||||
if(ok)
|
||||
{
|
||||
QStringList strategies = split.last().split(';');
|
||||
if(strategies.size() == 6 && index>=0 && index<6)
|
||||
if(strategies.size() >= 6 && index>=0 && index<6)
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
@ -884,9 +884,9 @@ cvflann::flann_distance_t Settings::getFlannDistanceType()
|
||||
cv::flann::SearchParams Settings::getFlannSearchParams()
|
||||
{
|
||||
return cv::flann::SearchParams(
|
||||
getNearestNeighbor_7search_checks(),
|
||||
getNearestNeighbor_8search_eps(),
|
||||
getNearestNeighbor_9search_sorted());
|
||||
getNearestNeighbor_search_checks(),
|
||||
getNearestNeighbor_search_eps(),
|
||||
getNearestNeighbor_search_sorted());
|
||||
}
|
||||
|
||||
int Settings::getHomographyMethod()
|
||||
|
||||
@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "Vocabulary.h"
|
||||
#include <QtCore/QVector>
|
||||
#include <stdio.h>
|
||||
#include <opencv2/gpu/gpu.hpp>
|
||||
|
||||
namespace find_object {
|
||||
|
||||
@ -67,7 +68,7 @@ QMultiMap<int, int> Vocabulary::addWords(const cv::Mat & descriptors, int object
|
||||
if(!indexedDescriptors_.empty() && indexedDescriptors_.rows >= (int)k)
|
||||
{
|
||||
Q_ASSERT(indexedDescriptors_.type() == descriptors.type() && indexedDescriptors_.cols == descriptors.cols);
|
||||
flannIndex_.knnSearch(descriptors, results, dists, k, Settings::getFlannSearchParams() );
|
||||
this->search(descriptors, results, dists, k);
|
||||
|
||||
if( dists.type() == CV_32S )
|
||||
{
|
||||
@ -207,7 +208,7 @@ void Vocabulary::update()
|
||||
notIndexedWordIds_.clear();
|
||||
}
|
||||
|
||||
if(!indexedDescriptors_.empty())
|
||||
if(!indexedDescriptors_.empty() && !Settings::isBruteForceNearestNeighbor())
|
||||
{
|
||||
cv::flann::IndexParams * params = Settings::createFlannIndexParams();
|
||||
flannIndex_.build(indexedDescriptors_, *params, Settings::getFlannDistanceType());
|
||||
@ -223,7 +224,46 @@ void Vocabulary::search(const cv::Mat & descriptors, cv::Mat & results, cv::Mat
|
||||
{
|
||||
Q_ASSERT(descriptors.type() == indexedDescriptors_.type() && descriptors.cols == indexedDescriptors_.cols);
|
||||
|
||||
flannIndex_.knnSearch(descriptors, results, dists, k, Settings::getFlannSearchParams());
|
||||
if(Settings::isBruteForceNearestNeighbor())
|
||||
{
|
||||
std::vector<std::vector<cv::DMatch> > matches;
|
||||
if(Settings::getNearestNeighbor_BruteForce_gpu() && cv::gpu::getCudaEnabledDeviceCount())
|
||||
{
|
||||
cv::gpu::GpuMat newDescriptorsGpu(descriptors);
|
||||
cv::gpu::GpuMat lastDescriptorsGpu(indexedDescriptors_);
|
||||
if(indexedDescriptors_.type()==CV_8U)
|
||||
{
|
||||
cv::gpu::BruteForceMatcher_GPU<cv::Hamming> gpuMatcher;
|
||||
gpuMatcher.knnMatch(newDescriptorsGpu, lastDescriptorsGpu, matches, k);
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::gpu::BruteForceMatcher_GPU<cv::L2<float> > gpuMatcher;
|
||||
gpuMatcher.knnMatch(newDescriptorsGpu, lastDescriptorsGpu, matches, k);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::BFMatcher matcher(indexedDescriptors_.type()==CV_8U?cv::NORM_HAMMING:cv::NORM_L2);
|
||||
matcher.knnMatch(descriptors, indexedDescriptors_, matches, k);
|
||||
}
|
||||
|
||||
//convert back to matrix style
|
||||
results = cv::Mat(matches.size(), k, CV_32SC1);
|
||||
dists = cv::Mat(matches.size(), k, CV_32FC1);
|
||||
for(unsigned int i=0; i<matches.size(); ++i)
|
||||
{
|
||||
for(int j=0; j<k; ++j)
|
||||
{
|
||||
results.at<int>(i, j) = matches[i].at(j).trainIdx;
|
||||
dists.at<float>(i, j) = matches[i].at(j).distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flannIndex_.knnSearch(descriptors, results, dists, k, Settings::getFlannSearchParams());
|
||||
}
|
||||
|
||||
if( dists.type() == CV_32S )
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user