Commit e6f3c9b0 authored by Andrey Pavlenko's avatar Andrey Pavlenko Committed by OpenCV Buildbot

Merge pull request #2281 from vpisarev:ocl_surf

parents 055f41c9 3e0c72a8
...@@ -235,7 +235,7 @@ public: ...@@ -235,7 +235,7 @@ public:
// Compute the BRISK features and descriptors on an image // Compute the BRISK features and descriptors on an image
void operator()( InputArray image, InputArray mask, std::vector<KeyPoint>& keypoints, void operator()( InputArray image, InputArray mask, std::vector<KeyPoint>& keypoints,
OutputArray descriptors, bool useProvidedKeypoints=false ) const; OutputArray descriptors, bool useProvidedKeypoints=false ) const;
AlgorithmInfo* info() const; AlgorithmInfo* info() const;
......
...@@ -246,105 +246,3 @@ The class ``SURF_CUDA`` uses some buffers and provides access to it. All buffers ...@@ -246,105 +246,3 @@ The class ``SURF_CUDA`` uses some buffers and provides access to it. All buffers
.. note:: .. note::
* An example for using the SURF keypoint matcher on GPU can be found at opencv_source_code/samples/gpu/surf_keypoint_matcher.cpp * An example for using the SURF keypoint matcher on GPU can be found at opencv_source_code/samples/gpu/surf_keypoint_matcher.cpp
ocl::SURF_OCL
-------------
.. ocv:class:: ocl::SURF_OCL
Class used for extracting Speeded Up Robust Features (SURF) from an image. ::
class SURF_OCL
{
public:
enum KeypointLayout
{
X_ROW = 0,
Y_ROW,
LAPLACIAN_ROW,
OCTAVE_ROW,
SIZE_ROW,
ANGLE_ROW,
HESSIAN_ROW,
ROWS_COUNT
};
//! the default constructor
SURF_OCL();
//! the full constructor taking all the necessary parameters
explicit SURF_OCL(double _hessianThreshold, int _nOctaves=4,
int _nOctaveLayers=2, bool _extended=false, float _keypointsRatio=0.01f, bool _upright = false);
//! returns the descriptor size in float's (64 or 128)
int descriptorSize() const;
//! upload host keypoints to device memory
void uploadKeypoints(const vector<KeyPoint>& keypoints,
oclMat& keypointsocl);
//! download keypoints from device to host memory
void downloadKeypoints(const oclMat& keypointsocl,
vector<KeyPoint>& keypoints);
//! download descriptors from device to host memory
void downloadDescriptors(const oclMat& descriptorsocl,
vector<float>& descriptors);
void operator()(const oclMat& img, const oclMat& mask,
oclMat& keypoints);
void operator()(const oclMat& img, const oclMat& mask,
oclMat& keypoints, oclMat& descriptors,
bool useProvidedKeypoints = false);
void operator()(const oclMat& img, const oclMat& mask,
std::vector<KeyPoint>& keypoints);
void operator()(const oclMat& img, const oclMat& mask,
std::vector<KeyPoint>& keypoints, oclMat& descriptors,
bool useProvidedKeypoints = false);
void operator()(const oclMat& img, const oclMat& mask,
std::vector<KeyPoint>& keypoints,
std::vector<float>& descriptors,
bool useProvidedKeypoints = false);
void releaseMemory();
// SURF parameters
double hessianThreshold;
int nOctaves;
int nOctaveLayers;
bool extended;
bool upright;
//! max keypoints = min(keypointsRatio * img.size().area(), 65535)
float keypointsRatio;
oclMat sum, mask1, maskSum, intBuffer;
oclMat det, trace;
oclMat maxPosBuffer;
};
The class ``SURF_OCL`` implements Speeded Up Robust Features descriptor. There is a fast multi-scale Hessian keypoint detector that can be used to find the keypoints (which is the default option). But the descriptors can also be computed for the user-specified keypoints. Only 8-bit grayscale images are supported.
The class ``SURF_OCL`` can store results in the GPU and CPU memory. It provides functions to convert results between CPU and GPU version ( ``uploadKeypoints``, ``downloadKeypoints``, ``downloadDescriptors`` ). The format of CPU results is the same as ``SURF`` results. GPU results are stored in ``oclMat``. The ``keypoints`` matrix is :math:`\texttt{nFeatures} \times 7` matrix with the ``CV_32FC1`` type.
* ``keypoints.ptr<float>(X_ROW)[i]`` contains x coordinate of the i-th feature.
* ``keypoints.ptr<float>(Y_ROW)[i]`` contains y coordinate of the i-th feature.
* ``keypoints.ptr<float>(LAPLACIAN_ROW)[i]`` contains the laplacian sign of the i-th feature.
* ``keypoints.ptr<float>(OCTAVE_ROW)[i]`` contains the octave of the i-th feature.
* ``keypoints.ptr<float>(SIZE_ROW)[i]`` contains the size of the i-th feature.
* ``keypoints.ptr<float>(ANGLE_ROW)[i]`` contain orientation of the i-th feature.
* ``keypoints.ptr<float>(HESSIAN_ROW)[i]`` contains the response of the i-th feature.
The ``descriptors`` matrix is :math:`\texttt{nFeatures} \times \texttt{descriptorSize}` matrix with the ``CV_32FC1`` type.
The class ``SURF_OCL`` uses some buffers and provides access to it. All buffers can be safely released between function calls.
.. seealso:: :ocv:class:`SURF`
.. note::
* OCL : An example of the SURF detector can be found at opencv_source_code/samples/ocl/surf_matcher.cpp
...@@ -142,7 +142,6 @@ public: ...@@ -142,7 +142,6 @@ public:
CV_PROP_RW bool upright; CV_PROP_RW bool upright;
protected: protected:
void detectImpl( InputArray image, std::vector<KeyPoint>& keypoints, InputArray mask = noArray() ) const; void detectImpl( InputArray image, std::vector<KeyPoint>& keypoints, InputArray mask = noArray() ) const;
void computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors ) const; void computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors ) const;
}; };
......
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_NONFREE_OCL_HPP__
#define __OPENCV_NONFREE_OCL_HPP__
#include "opencv2/ocl.hpp"
namespace cv
{
namespace ocl
{
//! Speeded up robust features, port from CUDA module.
////////////////////////////////// SURF //////////////////////////////////////////
class CV_EXPORTS SURF_OCL
{
public:
enum KeypointLayout
{
X_ROW = 0,
Y_ROW,
LAPLACIAN_ROW,
OCTAVE_ROW,
SIZE_ROW,
ANGLE_ROW,
HESSIAN_ROW,
ROWS_COUNT
};
//! the default constructor
SURF_OCL();
//! the full constructor taking all the necessary parameters
explicit SURF_OCL(double _hessianThreshold, int _nOctaves = 4,
int _nOctaveLayers = 2, bool _extended = false, float _keypointsRatio = 0.01f, bool _upright = false);
//! returns the descriptor size in float's (64 or 128)
int descriptorSize() const;
//! returns the default norm type
int defaultNorm() const;
//! upload host keypoints to device memory
void uploadKeypoints(const std::vector<cv::KeyPoint> &keypoints, oclMat &keypointsocl);
//! download keypoints from device to host memory
void downloadKeypoints(const oclMat &keypointsocl, std::vector<KeyPoint> &keypoints);
//! download descriptors from device to host memory
void downloadDescriptors(const oclMat &descriptorsocl, std::vector<float> &descriptors);
//! finds the keypoints using fast hessian detector used in SURF
//! supports CV_8UC1 images
//! keypoints will have nFeature cols and 6 rows
//! keypoints.ptr<float>(X_ROW)[i] will contain x coordinate of i'th feature
//! keypoints.ptr<float>(Y_ROW)[i] will contain y coordinate of i'th feature
//! keypoints.ptr<float>(LAPLACIAN_ROW)[i] will contain laplacian sign of i'th feature
//! keypoints.ptr<float>(OCTAVE_ROW)[i] will contain octave of i'th feature
//! keypoints.ptr<float>(SIZE_ROW)[i] will contain size of i'th feature
//! keypoints.ptr<float>(ANGLE_ROW)[i] will contain orientation of i'th feature
//! keypoints.ptr<float>(HESSIAN_ROW)[i] will contain response of i'th feature
void operator()(const oclMat &img, const oclMat &mask, oclMat &keypoints);
//! finds the keypoints and computes their descriptors.
//! Optionally it can compute descriptors for the user-provided keypoints and recompute keypoints direction
void operator()(const oclMat &img, const oclMat &mask, oclMat &keypoints, oclMat &descriptors,
bool useProvidedKeypoints = false);
void operator()(const oclMat &img, const oclMat &mask, std::vector<KeyPoint> &keypoints);
void operator()(const oclMat &img, const oclMat &mask, std::vector<KeyPoint> &keypoints, oclMat &descriptors,
bool useProvidedKeypoints = false);
void operator()(const oclMat &img, const oclMat &mask, std::vector<KeyPoint> &keypoints, std::vector<float> &descriptors,
bool useProvidedKeypoints = false);
void releaseMemory();
// SURF parameters
float hessianThreshold;
int nOctaves;
int nOctaveLayers;
bool extended;
bool upright;
//! max keypoints = min(keypointsRatio * img.size().area(), 65535)
float keypointsRatio;
oclMat sum, mask1, maskSum, intBuffer;
oclMat det, trace;
oclMat maxPosBuffer;
};
}
}
#endif //__OPENCV_NONFREE_OCL_HPP__
This diff is collapsed.
...@@ -60,11 +60,6 @@ ...@@ -60,11 +60,6 @@
# include "opencv2/cudaarithm.hpp" # include "opencv2/cudaarithm.hpp"
#endif #endif
#ifdef HAVE_OPENCV_OCL
# include "opencv2/nonfree/ocl.hpp"
# include "opencv2/ocl/private/util.hpp"
#endif
#include "opencv2/core/private.hpp" #include "opencv2/core/private.hpp"
#endif #endif
...@@ -108,6 +108,7 @@ Modifications by Ian Mahon ...@@ -108,6 +108,7 @@ Modifications by Ian Mahon
*/ */
#include "precomp.hpp" #include "precomp.hpp"
#include "surf.hpp"
namespace cv namespace cv
{ {
...@@ -897,11 +898,42 @@ void SURF::operator()(InputArray _img, InputArray _mask, ...@@ -897,11 +898,42 @@ void SURF::operator()(InputArray _img, InputArray _mask,
OutputArray _descriptors, OutputArray _descriptors,
bool useProvidedKeypoints) const bool useProvidedKeypoints) const
{ {
Mat img = _img.getMat(), mask = _mask.getMat(), mask1, sum, msum; int imgtype = _img.type(), imgcn = CV_MAT_CN(imgtype);
bool doDescriptors = _descriptors.needed(); bool doDescriptors = _descriptors.needed();
CV_Assert(!img.empty() && img.depth() == CV_8U); CV_Assert(!_img.empty() && CV_MAT_DEPTH(imgtype) == CV_8U && (imgcn == 1 || imgcn == 3 || imgcn == 4));
if( img.channels() > 1 ) CV_Assert(_descriptors.needed() || !useProvidedKeypoints);
if( ocl::useOpenCL() )
{
SURF_OCL ocl_surf;
UMat gpu_kpt;
bool ok = ocl_surf.init(this);
if( ok )
{
if( !_descriptors.needed() )
{
ok = ocl_surf.detect(_img, _mask, gpu_kpt);
}
else
{
if(useProvidedKeypoints)
ocl_surf.uploadKeypoints(keypoints, gpu_kpt);
ok = ocl_surf.detectAndCompute(_img, _mask, gpu_kpt, _descriptors, useProvidedKeypoints);
}
}
if( ok )
{
if(!useProvidedKeypoints)
ocl_surf.downloadKeypoints(gpu_kpt, keypoints);
return;
}
}
Mat img = _img.getMat(), mask = _mask.getMat(), mask1, sum, msum;
if( imgcn > 1 )
cvtColor(img, img, COLOR_BGR2GRAY); cvtColor(img, img, COLOR_BGR2GRAY);
CV_Assert(mask.empty() || (mask.type() == CV_8U && mask.size() == img.size())); CV_Assert(mask.empty() || (mask.type() == CV_8U && mask.size() == img.size()));
......
///////////// see LICENSE.txt in the OpenCV root directory //////////////
#ifndef __OPENCV_NONFREE_SURF_HPP__
#define __OPENCV_NONFREE_SURF_HPP__
namespace cv
{
//! Speeded up robust features, port from CUDA module.
////////////////////////////////// SURF //////////////////////////////////////////
class SURF_OCL
{
public:
enum KeypointLayout
{
X_ROW = 0,
Y_ROW,
LAPLACIAN_ROW,
OCTAVE_ROW,
SIZE_ROW,
ANGLE_ROW,
HESSIAN_ROW,
ROWS_COUNT
};
//! the full constructor taking all the necessary parameters
SURF_OCL();
bool init(const SURF* params);
//! returns the descriptor size in float's (64 or 128)
int descriptorSize() const { return params->extended ? 128 : 64; }
void uploadKeypoints(const std::vector<KeyPoint> &keypoints, UMat &keypointsGPU);
void downloadKeypoints(const UMat &keypointsGPU, std::vector<KeyPoint> &keypoints);
//! finds the keypoints using fast hessian detector used in SURF
//! supports CV_8UC1 images
//! keypoints will have nFeature cols and 6 rows
//! keypoints.ptr<float>(X_ROW)[i] will contain x coordinate of i'th feature
//! keypoints.ptr<float>(Y_ROW)[i] will contain y coordinate of i'th feature
//! keypoints.ptr<float>(LAPLACIAN_ROW)[i] will contain laplacian sign of i'th feature
//! keypoints.ptr<float>(OCTAVE_ROW)[i] will contain octave of i'th feature
//! keypoints.ptr<float>(SIZE_ROW)[i] will contain size of i'th feature
//! keypoints.ptr<float>(ANGLE_ROW)[i] will contain orientation of i'th feature
//! keypoints.ptr<float>(HESSIAN_ROW)[i] will contain response of i'th feature
bool detect(InputArray img, InputArray mask, UMat& keypoints);
//! finds the keypoints and computes their descriptors.
//! Optionally it can compute descriptors for the user-provided keypoints and recompute keypoints direction
bool detectAndCompute(InputArray img, InputArray mask, UMat& keypoints,
OutputArray descriptors, bool useProvidedKeypoints = false);
protected:
bool setImage(InputArray img, InputArray mask);
// kernel callers declarations
bool calcLayerDetAndTrace(int octave, int layer_rows);
bool findMaximaInLayer(int counterOffset, int octave, int layer_rows, int layer_cols);
bool interpolateKeypoint(int maxCounter, UMat &keypoints, int octave, int layer_rows, int maxFeatures);
bool calcOrientation(UMat &keypoints);
bool setUpRight(UMat &keypoints);
bool computeDescriptors(const UMat &keypoints, OutputArray descriptors);
bool detectKeypoints(UMat &keypoints);
const SURF* params;
int refcount;
//! max keypoints = min(keypointsRatio * img.size().area(), 65535)
UMat sum, intBuffer;
UMat det, trace;
UMat maxPosBuffer;
int img_cols, img_rows;
int maxCandidates;
int maxFeatures;
UMat img, counters;
// texture buffers
ocl::Image2D imgTex, sumTex;
bool haveImageSupport;
String kerOpts;
int status;
};
/*
template<typename _Tp> void copyVectorToUMat(const std::vector<_Tp>& v, UMat& um)
{
if(v.empty())
um.release();
else
Mat(1, (int)(v.size()*sizeof(v[0])), CV_8U, (void*)&v[0]).copyTo(um);
}
template<typename _Tp> void copyUMatToVector(const UMat& um, std::vector<_Tp>& v)
{
if(um.empty())
v.clear();
else
{
size_t sz = um.total()*um.elemSize();
CV_Assert(um.isContinuous() && (sz % sizeof(_Tp) == 0));
v.resize(sz/sizeof(_Tp));
Mat m(um.size(), um.type(), &v[0]);
um.copyTo(m);
}
}*/
}
#endif
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment