Added GPU-SURF support when OpenCV is built with CUDA.

git-svn-id: http://find-object.googlecode.com/svn/trunk/find_object@337 620bd6b2-0a58-f614-fd9a-1bd335dccda9
This commit is contained in:
matlabbe 2014-06-17 21:04:26 +00:00
parent c4ac09b750
commit 8dfe9622b0
4 changed files with 118 additions and 10 deletions

View File

@ -13,7 +13,7 @@ ENDIF(NOT WIN32)
#######################
# VERSION
#######################
SET(PROJECT_VERSION "0.4.4")
SET(PROJECT_VERSION "0.4.5")
ADD_DEFINITIONS(-DPROJECT_VERSION="${PROJECT_VERSION}")
STRING(REGEX MATCHALL "[0-9]" PROJECT_VERSION_PARTS "${PROJECT_VERSION}")
@ -105,8 +105,12 @@ set(CPACK_SOURCE_IGNORE_FILES
IF(WIN32)
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
SET(CPACK_GENERATOR "NSIS;ZIP")
IF(CMAKE_CL_64)
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
ELSE()
SET(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
ENDIF()
SET(CPACK_GENERATOR "ZIP;NSIS")
SET(CPACK_SOURCE_GENERATOR "ZIP")
SET(CPACK_NSIS_PACKAGE_NAME "${PROJECT_NAME}")
SET(ICON_PATH "${PROJECT_SOURCE_DIR}/app/${PROJECT_NAME}.ico")

View File

@ -21,6 +21,7 @@
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/gpu/gpu.hpp"
#include <QtCore/QTextStream>
#include <QtCore/QFile>
@ -105,6 +106,13 @@ MainWindow::MainWindow(Camera * camera, const QString & settings, QWidget * pare
ui_->actionLoad_scene_from_file->setVisible(false);
}
if(cv::gpu::getCudaEnabledDeviceCount() == 0)
{
Settings::setFeature2D_SURF_gpu(false);
ui_->toolBox->updateParameter(Settings::kFeature2D_SURF_gpu());
ui_->toolBox->getParameterWidget(Settings::kFeature2D_SURF_gpu())->setEnabled(false);
}
connect((QDoubleSpinBox*)ui_->toolBox->getParameterWidget(Settings::kCamera_4imageRate()),
SIGNAL(editingFinished()),
camera_,

View File

@ -10,6 +10,7 @@
#include <stdio.h>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/nonfree/gpu.hpp>
#define VERBOSE 0
@ -117,6 +118,76 @@ void Settings::saveSettings(const QString & fileName, const QByteArray & windowG
printf("Settings saved to %s\n", path.toStdString().c_str());
}
class GPUSURF : public cv::Feature2D
{
public:
GPUSURF(double hessianThreshold,
int nOctaves=4, int nOctaveLayers=2,
bool extended=true, bool upright=false) :
hessianThreshold_(hessianThreshold),
nOctaves_(nOctaves),
nOctaveLayers_(nOctaveLayers),
extended_(extended),
upright_(upright)
{
}
virtual ~GPUSURF() {}
void operator()(cv::InputArray img, cv::InputArray mask,
std::vector<cv::KeyPoint>& keypoints,
cv::OutputArray descriptors,
bool useProvidedKeypoints=false) const
{
printf("GPUSURF:operator() Don't call this directly!\n");
exit(-1);
}
int descriptorSize() const
{
return extended_ ? 128 : 64;
}
int descriptorType() const
{
return CV_32F;
}
protected:
void detectImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask=cv::Mat() ) const
{
cv::gpu::GpuMat imgGpu(image);
cv::gpu::GpuMat maskGpu(mask);
cv::gpu::GpuMat keypointsGpu;
cv::gpu::SURF_GPU surfGpu(hessianThreshold_, nOctaves_, nOctaveLayers_, extended_, 0.01f, upright_);
surfGpu(imgGpu, maskGpu, keypointsGpu);
surfGpu.downloadKeypoints(keypointsGpu, keypoints);
}
void computeImpl( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors ) const
{
std::vector<float> d;
cv::gpu::GpuMat imgGpu(image);
cv::gpu::GpuMat descriptorsGpu;
cv::gpu::GpuMat keypointsGpu;
cv::gpu::SURF_GPU surfGpu(hessianThreshold_, nOctaves_, nOctaveLayers_, extended_, 0.01f, upright_);
surfGpu.uploadKeypoints(keypoints, keypointsGpu);
surfGpu(imgGpu, cv::gpu::GpuMat(), keypointsGpu, descriptorsGpu, true);
surfGpu.downloadDescriptors(descriptorsGpu, d);
unsigned int dim = extended_?128:64;
descriptors = cv::Mat(d.size()/dim, dim, CV_32F);
for(int i=0; i<descriptors.rows; ++i)
{
float * rowFl = descriptors.ptr<float>(i);
memcpy(rowFl, &d[i*dim], dim*sizeof(float));
}
}
private:
double hessianThreshold_;
int nOctaves_;
int nOctaveLayers_;
bool extended_;
bool upright_;
};
cv::FeatureDetector * Settings::createFeaturesDetector()
{
cv::FeatureDetector * detector = 0;
@ -226,6 +297,17 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
break;
case 7:
if(strategies.at(index).compare("SURF") == 0)
{
if(getFeature2D_SURF_gpu() && cv::gpu::getCudaEnabledDeviceCount())
{
detector = new GPUSURF(
getFeature2D_SURF_hessianThreshold(),
getFeature2D_SURF_nOctaves(),
getFeature2D_SURF_nOctaveLayers(),
getFeature2D_SURF_extended(),
getFeature2D_SURF_upright());
}
else
{
detector = new cv::SURF(
getFeature2D_SURF_hessianThreshold(),
@ -233,6 +315,7 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
getFeature2D_SURF_nOctaveLayers(),
getFeature2D_SURF_extended(),
getFeature2D_SURF_upright());
}
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", "SURF");
}
break;
@ -313,6 +396,17 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
break;
case 3:
if(strategies.at(index).compare("SURF") == 0)
{
if(getFeature2D_SURF_gpu() && cv::gpu::getCudaEnabledDeviceCount())
{
extractor = new GPUSURF(
getFeature2D_SURF_hessianThreshold(),
getFeature2D_SURF_nOctaves(),
getFeature2D_SURF_nOctaveLayers(),
getFeature2D_SURF_extended(),
getFeature2D_SURF_upright());
}
else
{
extractor = new cv::SURF(
getFeature2D_SURF_hessianThreshold(),
@ -320,6 +414,7 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
getFeature2D_SURF_nOctaveLayers(),
getFeature2D_SURF_extended(),
getFeature2D_SURF_upright());
}
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", "SURF");
}
break;

View File

@ -125,6 +125,7 @@ class Settings
PARAMETER(Feature2D, SURF_nOctaveLayers, int, 2, "Number of octave layers within each octave.");
PARAMETER(Feature2D, SURF_extended, bool, true, "Extended descriptor flag (true - use extended 128-element descriptors; false - use 64-element descriptors).");
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, BRISK_thresh, int, 30, "FAST/AGAST detection threshold score.");
PARAMETER(Feature2D, BRISK_octaves, int, 3, "Detection octaves. Use 0 to do single scale.");