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
+8
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_,
+102 -7
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;
@@ -227,12 +298,24 @@ cv::FeatureDetector * Settings::createFeaturesDetector()
case 7:
if(strategies.at(index).compare("SURF") == 0)
{
detector = new cv::SURF(
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(),
getFeature2D_SURF_nOctaves(),
getFeature2D_SURF_nOctaveLayers(),
getFeature2D_SURF_extended(),
getFeature2D_SURF_upright());
}
if(VERBOSE)printf("Settings::createFeaturesDetector() type=%s\n", "SURF");
}
break;
@@ -314,12 +397,24 @@ cv::DescriptorExtractor * Settings::createDescriptorsExtractor()
case 3:
if(strategies.at(index).compare("SURF") == 0)
{
extractor = new cv::SURF(
getFeature2D_SURF_hessianThreshold(),
getFeature2D_SURF_nOctaves(),
getFeature2D_SURF_nOctaveLayers(),
getFeature2D_SURF_extended(),
getFeature2D_SURF_upright());
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(),
getFeature2D_SURF_nOctaves(),
getFeature2D_SURF_nOctaveLayers(),
getFeature2D_SURF_extended(),
getFeature2D_SURF_upright());
}
if(VERBOSE)printf("Settings::createDescriptorsExtractor() type=%s\n", "SURF");
}
break;
+1
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.");