diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ef6a6c0..127b4cc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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") diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index b386ebd3..5ac0ef5b 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -21,6 +21,7 @@ #include "opencv2/calib3d/calib3d.hpp" #include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/gpu/gpu.hpp" #include #include @@ -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_, diff --git a/src/Settings.cpp b/src/Settings.cpp index 39f296c0..2560c83c 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #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& 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& 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& keypoints, cv::Mat& descriptors ) const + { + std::vector 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(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; diff --git a/src/Settings.h b/src/Settings.h index 250740c3..cde76a12 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -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.");