From cbb6ac0c34f68a9a9c8688174f8f4fc89c352f98 Mon Sep 17 00:00:00 2001 From: Alexey Spizhevoy Date: Wed, 7 Sep 2011 12:48:48 +0000 Subject: [PATCH] refactored features finders in stitching module --- .../opencv2/stitching/detail/matchers.hpp | 35 +++- .../include/opencv2/stitching/warpers.hpp | 2 - modules/stitching/src/matchers.cpp | 162 ++++++------------ modules/stitching/src/stitcher.cpp | 20 ++- samples/cpp/stitching_detailed.cpp | 17 +- 5 files changed, 106 insertions(+), 130 deletions(-) diff --git a/modules/stitching/include/opencv2/stitching/detail/matchers.hpp b/modules/stitching/include/opencv2/stitching/detail/matchers.hpp index 6350f13215..fa430a2a0e 100644 --- a/modules/stitching/include/opencv2/stitching/detail/matchers.hpp +++ b/modules/stitching/include/opencv2/stitching/detail/matchers.hpp @@ -46,6 +46,10 @@ #include "opencv2/core/core.hpp" #include "opencv2/features2d/features2d.hpp" +#ifndef ANDROID +#include "opencv2/gpu/gpu.hpp" +#endif + namespace cv { namespace detail { @@ -63,8 +67,6 @@ class CV_EXPORTS FeaturesFinder public: virtual ~FeaturesFinder() {} void operator ()(const Mat &image, ImageFeatures &features); - - // TODO put it into operator () virtual void collectGarbage() {} protected: @@ -75,17 +77,38 @@ protected: class CV_EXPORTS SurfFeaturesFinder : public FeaturesFinder { public: - SurfFeaturesFinder(bool try_use_gpu = true, double hess_thresh = 300.0, - int num_octaves = 3, int num_layers = 4, + SurfFeaturesFinder(double hess_thresh = 300., int num_octaves = 3, int num_layers = 4, int num_octaves_descr = 4, int num_layers_descr = 2); +private: + void find(const Mat &image, ImageFeatures &features); + + Ptr detector_; + Ptr extractor_; +}; + + +#ifndef ANDROID +class SurfFeaturesFinderGpu : public FeaturesFinder +{ +public: + SurfFeaturesFinderGpu(double hess_thresh = 300., int num_octaves = 3, int num_layers = 4, + int num_octaves_descr = 4, int num_layers_descr = 2); + void collectGarbage(); -protected: +private: void find(const Mat &image, ImageFeatures &features); - Ptr impl_; + gpu::GpuMat image_; + gpu::GpuMat gray_image_; + gpu::SURF_GPU surf_; + gpu::GpuMat keypoints_; + gpu::GpuMat descriptors_; + int num_octaves_, num_layers_; + int num_octaves_descr_, num_layers_descr_; }; +#endif struct CV_EXPORTS MatchesInfo diff --git a/modules/stitching/include/opencv2/stitching/warpers.hpp b/modules/stitching/include/opencv2/stitching/warpers.hpp index 2f326018bf..a98a499d7f 100644 --- a/modules/stitching/include/opencv2/stitching/warpers.hpp +++ b/modules/stitching/include/opencv2/stitching/warpers.hpp @@ -77,7 +77,6 @@ public: #ifndef ANDROID - class PlaneWarperGpu: public WarperCreator { public: @@ -97,7 +96,6 @@ class SphericalWarperGpu: public WarperCreator public: Ptr createByFocalLength(double f) const { return new detail::SphericalWarperGpu(f); } }; - #endif } // namespace cv diff --git a/modules/stitching/src/matchers.cpp b/modules/stitching/src/matchers.cpp index 4d9e16e691..af60b8d68f 100644 --- a/modules/stitching/src/matchers.cpp +++ b/modules/stitching/src/matchers.cpp @@ -51,104 +51,6 @@ using namespace cv::gpu; namespace { -class CpuSurfFeaturesFinder : public FeaturesFinder -{ -public: - CpuSurfFeaturesFinder(double hess_thresh, int num_octaves, int num_layers, - int num_octaves_descr, int num_layers_descr) - { - detector_ = new SurfFeatureDetector(hess_thresh, num_octaves, num_layers); - extractor_ = new SurfDescriptorExtractor(num_octaves_descr, num_layers_descr); - } - -protected: - void find(const Mat &image, ImageFeatures &features); - -private: - Ptr detector_; - Ptr extractor_; -}; - -#ifndef ANDROID -class GpuSurfFeaturesFinder : public FeaturesFinder -{ -public: - GpuSurfFeaturesFinder(double hess_thresh, int num_octaves, int num_layers, - int num_octaves_descr, int num_layers_descr) - { - surf_.keypointsRatio = 0.1f; - surf_.hessianThreshold = hess_thresh; - surf_.extended = false; - num_octaves_ = num_octaves; - num_layers_ = num_layers; - num_octaves_descr_ = num_octaves_descr; - num_layers_descr_ = num_layers_descr; - } - - void collectGarbage(); - -protected: - void find(const Mat &image, ImageFeatures &features); - -private: - GpuMat image_; - GpuMat gray_image_; - SURF_GPU surf_; - GpuMat keypoints_; - GpuMat descriptors_; - int num_octaves_, num_layers_; - int num_octaves_descr_, num_layers_descr_; -}; -#endif - - -void CpuSurfFeaturesFinder::find(const Mat &image, ImageFeatures &features) -{ - Mat gray_image; - CV_Assert(image.depth() == CV_8U); - cvtColor(image, gray_image, CV_BGR2GRAY); - detector_->detect(gray_image, features.keypoints); - extractor_->compute(gray_image, features.keypoints, features.descriptors); -} - -#ifndef ANDROID -void GpuSurfFeaturesFinder::find(const Mat &image, ImageFeatures &features) -{ - CV_Assert(image.depth() == CV_8U); - - ensureSizeIsEnough(image.size(), image.type(), image_); - image_.upload(image); - - ensureSizeIsEnough(image.size(), CV_8UC1, gray_image_); - cvtColor(image_, gray_image_, CV_BGR2GRAY); - - surf_.nOctaves = num_octaves_; - surf_.nOctaveLayers = num_layers_; - surf_.upright = false; - surf_(gray_image_, GpuMat(), keypoints_); - - surf_.nOctaves = num_octaves_descr_; - surf_.nOctaveLayers = num_layers_descr_; - surf_.upright = true; - surf_(gray_image_, GpuMat(), keypoints_, descriptors_, true); - surf_.downloadKeypoints(keypoints_, features.keypoints); - - descriptors_.download(features.descriptors); -} - -void GpuSurfFeaturesFinder::collectGarbage() -{ - surf_.releaseMemory(); - image_.release(); - gray_image_.release(); - keypoints_.release(); - descriptors_.release(); -} -#endif - - -////////////////////////////////////////////////////////////////////////////// - struct DistIdxPair { bool operator<(const DistIdxPair &other) const { return dist < other.dist; } @@ -347,34 +249,76 @@ void FeaturesFinder::operator ()(const Mat &image, ImageFeatures &features) { find(image, features); features.img_size = image.size(); - //features.img = image.clone(); } -SurfFeaturesFinder::SurfFeaturesFinder(bool try_use_gpu, double hess_thresh, int num_octaves, int num_layers, +SurfFeaturesFinder::SurfFeaturesFinder(double hess_thresh, int num_octaves, int num_layers, int num_octaves_descr, int num_layers_descr) { -#ifndef ANDROID - if (try_use_gpu && getCudaEnabledDeviceCount() > 0) - impl_ = new GpuSurfFeaturesFinder(hess_thresh, num_octaves, num_layers, num_octaves_descr, num_layers_descr); - else -#endif - impl_ = new CpuSurfFeaturesFinder(hess_thresh, num_octaves, num_layers, num_octaves_descr, num_layers_descr); + detector_ = new SurfFeatureDetector(hess_thresh, num_octaves, num_layers); + extractor_ = new SurfDescriptorExtractor(num_octaves_descr, num_layers_descr); } void SurfFeaturesFinder::find(const Mat &image, ImageFeatures &features) { - (*impl_)(image, features); + Mat gray_image; + CV_Assert(image.depth() == CV_8U); + cvtColor(image, gray_image, CV_BGR2GRAY); + detector_->detect(gray_image, features.keypoints); + extractor_->compute(gray_image, features.keypoints, features.descriptors); } -void SurfFeaturesFinder::collectGarbage() +#ifndef ANDROID +SurfFeaturesFinderGpu::SurfFeaturesFinderGpu(double hess_thresh, int num_octaves, int num_layers, + int num_octaves_descr, int num_layers_descr) { - impl_->collectGarbage(); + surf_.keypointsRatio = 0.1f; + surf_.hessianThreshold = hess_thresh; + surf_.extended = false; + num_octaves_ = num_octaves; + num_layers_ = num_layers; + num_octaves_descr_ = num_octaves_descr; + num_layers_descr_ = num_layers_descr; } +void SurfFeaturesFinderGpu::find(const Mat &image, ImageFeatures &features) +{ + CV_Assert(image.depth() == CV_8U); + + ensureSizeIsEnough(image.size(), image.type(), image_); + image_.upload(image); + + ensureSizeIsEnough(image.size(), CV_8UC1, gray_image_); + cvtColor(image_, gray_image_, CV_BGR2GRAY); + + surf_.nOctaves = num_octaves_; + surf_.nOctaveLayers = num_layers_; + surf_.upright = false; + surf_(gray_image_, GpuMat(), keypoints_); + + surf_.nOctaves = num_octaves_descr_; + surf_.nOctaveLayers = num_layers_descr_; + surf_.upright = true; + surf_(gray_image_, GpuMat(), keypoints_, descriptors_, true); + surf_.downloadKeypoints(keypoints_, features.keypoints); + + descriptors_.download(features.descriptors); +} + +void SurfFeaturesFinderGpu::collectGarbage() +{ + surf_.releaseMemory(); + image_.release(); + gray_image_.release(); + keypoints_.release(); + descriptors_.release(); +} +#endif + + ////////////////////////////////////////////////////////////////////////////// MatchesInfo::MatchesInfo() : src_img_idx(-1), dst_img_idx(-1), num_inliers(0), confidence(0) {} diff --git a/modules/stitching/src/stitcher.cpp b/modules/stitching/src/stitcher.cpp index b3679d8c65..61722cae99 100644 --- a/modules/stitching/src/stitcher.cpp +++ b/modules/stitching/src/stitcher.cpp @@ -46,7 +46,6 @@ using namespace std; namespace cv { -// TODO put all #ifndef ANDROID here, avoid passing try_use_gpu Stitcher Stitcher::createDefault(bool try_use_gpu) { Stitcher stitcher; @@ -55,18 +54,25 @@ Stitcher Stitcher::createDefault(bool try_use_gpu) stitcher.setCompositingResol(ORIG_RESOL); stitcher.setPanoConfidenceThresh(1); stitcher.setHorizontalStrightening(true); - stitcher.setFeaturesFinder(new detail::SurfFeaturesFinder(try_use_gpu)); stitcher.setFeaturesMatcher(new detail::BestOf2NearestMatcher(try_use_gpu)); + #ifndef ANDROID - bool must_use_gpu = try_use_gpu && (gpu::getCudaEnabledDeviceCount() > 0); - stitcher.setWarper(must_use_gpu ? static_cast(new SphericalWarperGpu()) : - static_cast(new SphericalWarper())); -#else - stitcher.setWarper(new SphericalWarper()); + if (try_use_gpu && gpu::getCudaEnabledDeviceCount() > 0) + { + stitcher.setFeaturesFinder(new detail::SurfFeaturesFinderGpu()); + stitcher.setWarper(new SphericalWarperGpu()); + } + else #endif + { + stitcher.setFeaturesFinder(new detail::SurfFeaturesFinder()); + stitcher.setWarper(new SphericalWarper()); + } + stitcher.setExposureCompenstor(new detail::BlocksGainCompensator()); stitcher.setSeamFinder(new detail::GraphCutSeamFinder()); stitcher.setBlender(new detail::MultiBandBlender(try_use_gpu)); + return stitcher; } diff --git a/samples/cpp/stitching_detailed.cpp b/samples/cpp/stitching_detailed.cpp index ee5650102d..b03e8dd349 100644 --- a/samples/cpp/stitching_detailed.cpp +++ b/samples/cpp/stitching_detailed.cpp @@ -326,10 +326,16 @@ int main(int argc, char* argv[]) LOGLN("Finding features..."); int64 t = getTickCount(); - vector features(num_images); - SurfFeaturesFinder finder(try_gpu); - Mat full_img, img; + Ptr finder; +#ifndef ANDROID + if (try_gpu && gpu::getCudaEnabledDeviceCount() > 0) + finder = new SurfFeaturesFinderGpu(); + else +#endif + finder = new SurfFeaturesFinder(); + Mat full_img, img; + vector features(num_images); vector images(num_images); vector full_img_sizes(num_images); double seam_work_aspect = 1; @@ -366,7 +372,7 @@ int main(int argc, char* argv[]) is_seam_scale_set = true; } - finder(img, features[i]); + (*finder)(img, features[i]); features[i].img_idx = i; LOGLN("Features in image #" << i+1 << ": " << features[i].keypoints.size()); @@ -374,8 +380,7 @@ int main(int argc, char* argv[]) images[i] = img.clone(); } - finder.collectGarbage(); - + finder->collectGarbage(); full_img.release(); img.release();