|
|
|
@ -48,6 +48,7 @@ |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#include "opencv2/core/cuda.hpp" |
|
|
|
|
#include "opencv2/features2d.hpp" |
|
|
|
|
#include "opencv2/cudafilters.hpp" |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -62,382 +63,423 @@ namespace cv { namespace cuda { |
|
|
|
|
//! @addtogroup cudafeatures2d
|
|
|
|
|
//! @{
|
|
|
|
|
|
|
|
|
|
/** @brief Brute-force descriptor matcher.
|
|
|
|
|
|
|
|
|
|
For each descriptor in the first set, this matcher finds the closest descriptor in the second set |
|
|
|
|
by trying each one. This descriptor matcher supports masking permissible matches between descriptor |
|
|
|
|
sets. |
|
|
|
|
//
|
|
|
|
|
// DescriptorMatcher
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
The class BFMatcher_CUDA has an interface similar to the class DescriptorMatcher. It has two groups |
|
|
|
|
of match methods: for matching descriptors of one image with another image or with an image set. |
|
|
|
|
Also, all functions have an alternative to save results either to the GPU memory or to the CPU |
|
|
|
|
memory. |
|
|
|
|
/** @brief Abstract base class for matching keypoint descriptors.
|
|
|
|
|
|
|
|
|
|
@sa DescriptorMatcher, BFMatcher |
|
|
|
|
It has two groups of match methods: for matching descriptors of an image with another image or with |
|
|
|
|
an image set. |
|
|
|
|
*/ |
|
|
|
|
class CV_EXPORTS BFMatcher_CUDA |
|
|
|
|
class CV_EXPORTS DescriptorMatcher : public cv::Algorithm |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
explicit BFMatcher_CUDA(int norm = cv::NORM_L2); |
|
|
|
|
|
|
|
|
|
//! Add descriptors to train descriptor collection
|
|
|
|
|
void add(const std::vector<GpuMat>& descCollection); |
|
|
|
|
|
|
|
|
|
//! Get train descriptors collection
|
|
|
|
|
const std::vector<GpuMat>& getTrainDescriptors() const; |
|
|
|
|
|
|
|
|
|
//! Clear train descriptors collection
|
|
|
|
|
void clear(); |
|
|
|
|
|
|
|
|
|
//! Return true if there are not train descriptors in collection
|
|
|
|
|
bool empty() const; |
|
|
|
|
|
|
|
|
|
//! Return true if the matcher supports mask in match methods
|
|
|
|
|
bool isMaskSupported() const; |
|
|
|
|
|
|
|
|
|
//! Find one best match for each query descriptor
|
|
|
|
|
void matchSingle(const GpuMat& query, const GpuMat& train, |
|
|
|
|
GpuMat& trainIdx, GpuMat& distance, |
|
|
|
|
const GpuMat& mask = GpuMat(), Stream& stream = Stream::Null()); |
|
|
|
|
|
|
|
|
|
//! Download trainIdx and distance and convert it to CPU vector with DMatch
|
|
|
|
|
static void matchDownload(const GpuMat& trainIdx, const GpuMat& distance, std::vector<DMatch>& matches); |
|
|
|
|
//! Convert trainIdx and distance to vector with DMatch
|
|
|
|
|
static void matchConvert(const Mat& trainIdx, const Mat& distance, std::vector<DMatch>& matches); |
|
|
|
|
|
|
|
|
|
//! Find one best match for each query descriptor
|
|
|
|
|
void match(const GpuMat& query, const GpuMat& train, std::vector<DMatch>& matches, const GpuMat& mask = GpuMat()); |
|
|
|
|
|
|
|
|
|
//! Make gpu collection of trains and masks in suitable format for matchCollection function
|
|
|
|
|
void makeGpuCollection(GpuMat& trainCollection, GpuMat& maskCollection, const std::vector<GpuMat>& masks = std::vector<GpuMat>()); |
|
|
|
|
|
|
|
|
|
//! Find one best match from train collection for each query descriptor
|
|
|
|
|
void matchCollection(const GpuMat& query, const GpuMat& trainCollection, |
|
|
|
|
GpuMat& trainIdx, GpuMat& imgIdx, GpuMat& distance, |
|
|
|
|
const GpuMat& masks = GpuMat(), Stream& stream = Stream::Null()); |
|
|
|
|
|
|
|
|
|
//! Download trainIdx, imgIdx and distance and convert it to vector with DMatch
|
|
|
|
|
static void matchDownload(const GpuMat& trainIdx, const GpuMat& imgIdx, const GpuMat& distance, std::vector<DMatch>& matches); |
|
|
|
|
//! Convert trainIdx, imgIdx and distance to vector with DMatch
|
|
|
|
|
static void matchConvert(const Mat& trainIdx, const Mat& imgIdx, const Mat& distance, std::vector<DMatch>& matches); |
|
|
|
|
|
|
|
|
|
//! Find one best match from train collection for each query descriptor.
|
|
|
|
|
void match(const GpuMat& query, std::vector<DMatch>& matches, const std::vector<GpuMat>& masks = std::vector<GpuMat>()); |
|
|
|
|
|
|
|
|
|
//! Find k best matches for each query descriptor (in increasing order of distances)
|
|
|
|
|
void knnMatchSingle(const GpuMat& query, const GpuMat& train, |
|
|
|
|
GpuMat& trainIdx, GpuMat& distance, GpuMat& allDist, int k, |
|
|
|
|
const GpuMat& mask = GpuMat(), Stream& stream = Stream::Null()); |
|
|
|
|
|
|
|
|
|
//! Download trainIdx and distance and convert it to vector with DMatch
|
|
|
|
|
//! compactResult is used when mask is not empty. If compactResult is false matches
|
|
|
|
|
//! vector will have the same size as queryDescriptors rows. If compactResult is true
|
|
|
|
|
//! matches vector will not contain matches for fully masked out query descriptors.
|
|
|
|
|
static void knnMatchDownload(const GpuMat& trainIdx, const GpuMat& distance, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, bool compactResult = false); |
|
|
|
|
//! Convert trainIdx and distance to vector with DMatch
|
|
|
|
|
static void knnMatchConvert(const Mat& trainIdx, const Mat& distance, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, bool compactResult = false); |
|
|
|
|
|
|
|
|
|
//! Find k best matches for each query descriptor (in increasing order of distances).
|
|
|
|
|
//! compactResult is used when mask is not empty. If compactResult is false matches
|
|
|
|
|
//! vector will have the same size as queryDescriptors rows. If compactResult is true
|
|
|
|
|
//! matches vector will not contain matches for fully masked out query descriptors.
|
|
|
|
|
void knnMatch(const GpuMat& query, const GpuMat& train, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, int k, const GpuMat& mask = GpuMat(), |
|
|
|
|
bool compactResult = false); |
|
|
|
|
|
|
|
|
|
//! Find k best matches from train collection for each query descriptor (in increasing order of distances)
|
|
|
|
|
void knnMatch2Collection(const GpuMat& query, const GpuMat& trainCollection, |
|
|
|
|
GpuMat& trainIdx, GpuMat& imgIdx, GpuMat& distance, |
|
|
|
|
const GpuMat& maskCollection = GpuMat(), Stream& stream = Stream::Null()); |
|
|
|
|
|
|
|
|
|
//! Download trainIdx and distance and convert it to vector with DMatch
|
|
|
|
|
//! compactResult is used when mask is not empty. If compactResult is false matches
|
|
|
|
|
//! vector will have the same size as queryDescriptors rows. If compactResult is true
|
|
|
|
|
//! matches vector will not contain matches for fully masked out query descriptors.
|
|
|
|
|
//! @see BFMatcher_CUDA::knnMatchDownload
|
|
|
|
|
static void knnMatch2Download(const GpuMat& trainIdx, const GpuMat& imgIdx, const GpuMat& distance, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, bool compactResult = false); |
|
|
|
|
//! Convert trainIdx and distance to vector with DMatch
|
|
|
|
|
//! @see BFMatcher_CUDA::knnMatchConvert
|
|
|
|
|
static void knnMatch2Convert(const Mat& trainIdx, const Mat& imgIdx, const Mat& distance, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, bool compactResult = false); |
|
|
|
|
|
|
|
|
|
//! Find k best matches for each query descriptor (in increasing order of distances).
|
|
|
|
|
//! compactResult is used when mask is not empty. If compactResult is false matches
|
|
|
|
|
//! vector will have the same size as queryDescriptors rows. If compactResult is true
|
|
|
|
|
//! matches vector will not contain matches for fully masked out query descriptors.
|
|
|
|
|
void knnMatch(const GpuMat& query, std::vector< std::vector<DMatch> >& matches, int k, |
|
|
|
|
const std::vector<GpuMat>& masks = std::vector<GpuMat>(), bool compactResult = false); |
|
|
|
|
|
|
|
|
|
//! Find best matches for each query descriptor which have distance less than maxDistance.
|
|
|
|
|
//! nMatches.at<int>(0, queryIdx) will contain matches count for queryIdx.
|
|
|
|
|
//! carefully nMatches can be greater than trainIdx.cols - it means that matcher didn't find all matches,
|
|
|
|
|
//! because it didn't have enough memory.
|
|
|
|
|
//! If trainIdx is empty, then trainIdx and distance will be created with size nQuery x max((nTrain / 100), 10),
|
|
|
|
|
//! otherwize user can pass own allocated trainIdx and distance with size nQuery x nMaxMatches
|
|
|
|
|
//! Matches doesn't sorted.
|
|
|
|
|
void radiusMatchSingle(const GpuMat& query, const GpuMat& train, |
|
|
|
|
GpuMat& trainIdx, GpuMat& distance, GpuMat& nMatches, float maxDistance, |
|
|
|
|
const GpuMat& mask = GpuMat(), Stream& stream = Stream::Null()); |
|
|
|
|
|
|
|
|
|
//! Download trainIdx, nMatches and distance and convert it to vector with DMatch.
|
|
|
|
|
//! matches will be sorted in increasing order of distances.
|
|
|
|
|
//! compactResult is used when mask is not empty. If compactResult is false matches
|
|
|
|
|
//! vector will have the same size as queryDescriptors rows. If compactResult is true
|
|
|
|
|
//! matches vector will not contain matches for fully masked out query descriptors.
|
|
|
|
|
static void radiusMatchDownload(const GpuMat& trainIdx, const GpuMat& distance, const GpuMat& nMatches, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, bool compactResult = false); |
|
|
|
|
//! Convert trainIdx, nMatches and distance to vector with DMatch.
|
|
|
|
|
static void radiusMatchConvert(const Mat& trainIdx, const Mat& distance, const Mat& nMatches, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, bool compactResult = false); |
|
|
|
|
|
|
|
|
|
//! Find best matches for each query descriptor which have distance less than maxDistance
|
|
|
|
|
//! in increasing order of distances).
|
|
|
|
|
void radiusMatch(const GpuMat& query, const GpuMat& train, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, float maxDistance, |
|
|
|
|
const GpuMat& mask = GpuMat(), bool compactResult = false); |
|
|
|
|
|
|
|
|
|
//! Find best matches for each query descriptor which have distance less than maxDistance.
|
|
|
|
|
//! If trainIdx is empty, then trainIdx and distance will be created with size nQuery x max((nQuery / 100), 10),
|
|
|
|
|
//! otherwize user can pass own allocated trainIdx and distance with size nQuery x nMaxMatches
|
|
|
|
|
//! Matches doesn't sorted.
|
|
|
|
|
void radiusMatchCollection(const GpuMat& query, GpuMat& trainIdx, GpuMat& imgIdx, GpuMat& distance, GpuMat& nMatches, float maxDistance, |
|
|
|
|
const std::vector<GpuMat>& masks = std::vector<GpuMat>(), Stream& stream = Stream::Null()); |
|
|
|
|
|
|
|
|
|
//! Download trainIdx, imgIdx, nMatches and distance and convert it to vector with DMatch.
|
|
|
|
|
//! matches will be sorted in increasing order of distances.
|
|
|
|
|
//! compactResult is used when mask is not empty. If compactResult is false matches
|
|
|
|
|
//! vector will have the same size as queryDescriptors rows. If compactResult is true
|
|
|
|
|
//! matches vector will not contain matches for fully masked out query descriptors.
|
|
|
|
|
static void radiusMatchDownload(const GpuMat& trainIdx, const GpuMat& imgIdx, const GpuMat& distance, const GpuMat& nMatches, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, bool compactResult = false); |
|
|
|
|
//! Convert trainIdx, nMatches and distance to vector with DMatch.
|
|
|
|
|
static void radiusMatchConvert(const Mat& trainIdx, const Mat& imgIdx, const Mat& distance, const Mat& nMatches, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, bool compactResult = false); |
|
|
|
|
|
|
|
|
|
//! Find best matches from train collection for each query descriptor which have distance less than
|
|
|
|
|
//! maxDistance (in increasing order of distances).
|
|
|
|
|
void radiusMatch(const GpuMat& query, std::vector< std::vector<DMatch> >& matches, float maxDistance, |
|
|
|
|
const std::vector<GpuMat>& masks = std::vector<GpuMat>(), bool compactResult = false); |
|
|
|
|
|
|
|
|
|
int norm; |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
std::vector<GpuMat> trainDescCollection; |
|
|
|
|
}; |
|
|
|
|
//
|
|
|
|
|
// Factories
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
/** @brief Class used for corner detection using the FAST algorithm. :
|
|
|
|
|
*/ |
|
|
|
|
class CV_EXPORTS FAST_CUDA |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
enum
|
|
|
|
|
{ |
|
|
|
|
LOCATION_ROW = 0, |
|
|
|
|
RESPONSE_ROW, |
|
|
|
|
ROWS_COUNT |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//! all features have same size
|
|
|
|
|
static const int FEATURE_SIZE = 7; |
|
|
|
|
/** @brief Brute-force descriptor matcher.
|
|
|
|
|
|
|
|
|
|
/** @brief Constructor.
|
|
|
|
|
For each descriptor in the first set, this matcher finds the closest descriptor in the second set |
|
|
|
|
by trying each one. This descriptor matcher supports masking permissible matches of descriptor |
|
|
|
|
sets. |
|
|
|
|
|
|
|
|
|
@param threshold Threshold on difference between intensity of the central pixel and pixels on a |
|
|
|
|
circle around this pixel. |
|
|
|
|
@param nonmaxSuppression If it is true, non-maximum suppression is applied to detected corners |
|
|
|
|
(keypoints). |
|
|
|
|
@param keypointsRatio Inner buffer size for keypoints store is determined as (keypointsRatio \* |
|
|
|
|
image_width \* image_height). |
|
|
|
|
*/ |
|
|
|
|
explicit FAST_CUDA(int threshold, bool nonmaxSuppression = true, double keypointsRatio = 0.05); |
|
|
|
|
|
|
|
|
|
/** @brief Finds the keypoints using FAST detector.
|
|
|
|
|
|
|
|
|
|
@param image Image where keypoints (corners) are detected. Only 8-bit grayscale images are |
|
|
|
|
supported. |
|
|
|
|
@param mask Optional input mask that marks the regions where we should detect features. |
|
|
|
|
@param keypoints The output vector of keypoints. Can be stored both in CPU and GPU memory. For GPU |
|
|
|
|
memory: |
|
|
|
|
- keypoints.ptr\<Vec2s\>(LOCATION_ROW)[i] will contain location of i'th point |
|
|
|
|
- keypoints.ptr\<float\>(RESPONSE_ROW)[i] will contain response of i'th point (if non-maximum |
|
|
|
|
suppression is applied) |
|
|
|
|
@param normType One of NORM_L1, NORM_L2, NORM_HAMMING. L1 and L2 norms are |
|
|
|
|
preferable choices for SIFT and SURF descriptors, NORM_HAMMING should be used with ORB, BRISK and |
|
|
|
|
BRIEF). |
|
|
|
|
*/ |
|
|
|
|
void operator ()(const GpuMat& image, const GpuMat& mask, GpuMat& keypoints); |
|
|
|
|
/** @overload */ |
|
|
|
|
void operator ()(const GpuMat& image, const GpuMat& mask, std::vector<KeyPoint>& keypoints); |
|
|
|
|
static Ptr<DescriptorMatcher> createBFMatcher(int normType = cv::NORM_L2); |
|
|
|
|
|
|
|
|
|
/** @brief Download keypoints from GPU to CPU memory.
|
|
|
|
|
*/ |
|
|
|
|
static void downloadKeypoints(const GpuMat& d_keypoints, std::vector<KeyPoint>& keypoints); |
|
|
|
|
//
|
|
|
|
|
// Utility
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
/** @brief Converts keypoints from CUDA representation to vector of KeyPoint.
|
|
|
|
|
*/ |
|
|
|
|
static void convertKeypoints(const Mat& h_keypoints, std::vector<KeyPoint>& keypoints); |
|
|
|
|
|
|
|
|
|
/** @brief Releases inner buffer memory.
|
|
|
|
|
*/ |
|
|
|
|
void release(); |
|
|
|
|
/** @brief Returns true if the descriptor matcher supports masking permissible matches.
|
|
|
|
|
*/ |
|
|
|
|
virtual bool isMaskSupported() const = 0; |
|
|
|
|
|
|
|
|
|
bool nonmaxSuppression; |
|
|
|
|
//
|
|
|
|
|
// Descriptor collection
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
int threshold; |
|
|
|
|
/** @brief Adds descriptors to train a descriptor collection.
|
|
|
|
|
|
|
|
|
|
//! max keypoints = keypointsRatio * img.size().area()
|
|
|
|
|
double keypointsRatio; |
|
|
|
|
If the collection is not empty, the new descriptors are added to existing train descriptors. |
|
|
|
|
|
|
|
|
|
/** @brief Find keypoints and compute it's response if nonmaxSuppression is true.
|
|
|
|
|
@param descriptors Descriptors to add. Each descriptors[i] is a set of descriptors from the same |
|
|
|
|
train image. |
|
|
|
|
*/ |
|
|
|
|
virtual void add(const std::vector<GpuMat>& descriptors) = 0; |
|
|
|
|
|
|
|
|
|
@param image Image where keypoints (corners) are detected. Only 8-bit grayscale images are |
|
|
|
|
supported. |
|
|
|
|
@param mask Optional input mask that marks the regions where we should detect features. |
|
|
|
|
/** @brief Returns a constant link to the train descriptor collection.
|
|
|
|
|
*/ |
|
|
|
|
virtual const std::vector<GpuMat>& getTrainDescriptors() const = 0; |
|
|
|
|
|
|
|
|
|
The function returns count of detected keypoints. |
|
|
|
|
/** @brief Clears the train descriptor collection.
|
|
|
|
|
*/ |
|
|
|
|
int calcKeyPointsLocation(const GpuMat& image, const GpuMat& mask); |
|
|
|
|
virtual void clear() = 0; |
|
|
|
|
|
|
|
|
|
/** @brief Gets final array of keypoints.
|
|
|
|
|
/** @brief Returns true if there are no train descriptors in the collection.
|
|
|
|
|
*/ |
|
|
|
|
virtual bool empty() const = 0; |
|
|
|
|
|
|
|
|
|
@param keypoints The output vector of keypoints. |
|
|
|
|
/** @brief Trains a descriptor matcher.
|
|
|
|
|
|
|
|
|
|
The function performs non-max suppression if needed and returns final count of keypoints. |
|
|
|
|
Trains a descriptor matcher (for example, the flann index). In all methods to match, the method |
|
|
|
|
train() is run every time before matching. |
|
|
|
|
*/ |
|
|
|
|
int getKeyPoints(GpuMat& keypoints); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
GpuMat kpLoc_; |
|
|
|
|
int count_; |
|
|
|
|
virtual void train() = 0; |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 1 to 1 match
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
/** @brief Finds the best match for each descriptor from a query set (blocking version).
|
|
|
|
|
|
|
|
|
|
@param queryDescriptors Query set of descriptors. |
|
|
|
|
@param trainDescriptors Train set of descriptors. This set is not added to the train descriptors |
|
|
|
|
collection stored in the class object. |
|
|
|
|
@param matches Matches. If a query descriptor is masked out in mask , no match is added for this |
|
|
|
|
descriptor. So, matches size may be smaller than the query descriptors count. |
|
|
|
|
@param mask Mask specifying permissible matches between an input query and train matrices of |
|
|
|
|
descriptors. |
|
|
|
|
|
|
|
|
|
In the first variant of this method, the train descriptors are passed as an input argument. In the |
|
|
|
|
second variant of the method, train descriptors collection that was set by DescriptorMatcher::add is |
|
|
|
|
used. Optional mask (or masks) can be passed to specify which query and training descriptors can be |
|
|
|
|
matched. Namely, queryDescriptors[i] can be matched with trainDescriptors[j] only if |
|
|
|
|
mask.at\<uchar\>(i,j) is non-zero. |
|
|
|
|
*/ |
|
|
|
|
virtual void match(InputArray queryDescriptors, InputArray trainDescriptors, |
|
|
|
|
std::vector<DMatch>& matches, |
|
|
|
|
InputArray mask = noArray()) = 0; |
|
|
|
|
|
|
|
|
|
GpuMat score_; |
|
|
|
|
/** @overload
|
|
|
|
|
*/ |
|
|
|
|
virtual void match(InputArray queryDescriptors, |
|
|
|
|
std::vector<DMatch>& matches, |
|
|
|
|
const std::vector<GpuMat>& masks = std::vector<GpuMat>()) = 0; |
|
|
|
|
|
|
|
|
|
/** @brief Finds the best match for each descriptor from a query set (asynchronous version).
|
|
|
|
|
|
|
|
|
|
@param queryDescriptors Query set of descriptors. |
|
|
|
|
@param trainDescriptors Train set of descriptors. This set is not added to the train descriptors |
|
|
|
|
collection stored in the class object. |
|
|
|
|
@param matches Matches array stored in GPU memory. Internal representation is not defined. |
|
|
|
|
Use DescriptorMatcher::matchConvert method to retrieve results in standard representation. |
|
|
|
|
@param mask Mask specifying permissible matches between an input query and train matrices of |
|
|
|
|
descriptors. |
|
|
|
|
@param stream CUDA stream. |
|
|
|
|
|
|
|
|
|
In the first variant of this method, the train descriptors are passed as an input argument. In the |
|
|
|
|
second variant of the method, train descriptors collection that was set by DescriptorMatcher::add is |
|
|
|
|
used. Optional mask (or masks) can be passed to specify which query and training descriptors can be |
|
|
|
|
matched. Namely, queryDescriptors[i] can be matched with trainDescriptors[j] only if |
|
|
|
|
mask.at\<uchar\>(i,j) is non-zero. |
|
|
|
|
*/ |
|
|
|
|
virtual void matchAsync(InputArray queryDescriptors, InputArray trainDescriptors, |
|
|
|
|
OutputArray matches, |
|
|
|
|
InputArray mask = noArray(), |
|
|
|
|
Stream& stream = Stream::Null()) = 0; |
|
|
|
|
|
|
|
|
|
GpuMat d_keypoints_; |
|
|
|
|
}; |
|
|
|
|
/** @overload
|
|
|
|
|
*/ |
|
|
|
|
virtual void matchAsync(InputArray queryDescriptors, |
|
|
|
|
OutputArray matches, |
|
|
|
|
const std::vector<GpuMat>& masks = std::vector<GpuMat>(), |
|
|
|
|
Stream& stream = Stream::Null()) = 0; |
|
|
|
|
|
|
|
|
|
/** @brief Class for extracting ORB features and descriptors from an image. :
|
|
|
|
|
*/ |
|
|
|
|
class CV_EXPORTS ORB_CUDA |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
enum
|
|
|
|
|
{ |
|
|
|
|
X_ROW = 0, |
|
|
|
|
Y_ROW, |
|
|
|
|
RESPONSE_ROW, |
|
|
|
|
ANGLE_ROW, |
|
|
|
|
OCTAVE_ROW, |
|
|
|
|
SIZE_ROW, |
|
|
|
|
ROWS_COUNT |
|
|
|
|
}; |
|
|
|
|
/** @brief Converts matches array from internal representation to standard matches vector.
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
|
{ |
|
|
|
|
DEFAULT_FAST_THRESHOLD = 20 |
|
|
|
|
}; |
|
|
|
|
The method is supposed to be used with DescriptorMatcher::matchAsync to get final result. |
|
|
|
|
Call this method only after DescriptorMatcher::matchAsync is completed (ie. after synchronization). |
|
|
|
|
|
|
|
|
|
/** @brief Constructor.
|
|
|
|
|
|
|
|
|
|
@param nFeatures The number of desired features. |
|
|
|
|
@param scaleFactor Coefficient by which we divide the dimensions from one scale pyramid level to |
|
|
|
|
the next. |
|
|
|
|
@param nLevels The number of levels in the scale pyramid. |
|
|
|
|
@param edgeThreshold How far from the boundary the points should be. |
|
|
|
|
@param firstLevel The level at which the image is given. If 1, that means we will also look at the |
|
|
|
|
image scaleFactor times bigger. |
|
|
|
|
@param WTA_K |
|
|
|
|
@param scoreType |
|
|
|
|
@param patchSize |
|
|
|
|
@param gpu_matches Matches, returned from DescriptorMatcher::matchAsync. |
|
|
|
|
@param matches Vector of DMatch objects. |
|
|
|
|
*/ |
|
|
|
|
explicit ORB_CUDA(int nFeatures = 500, float scaleFactor = 1.2f, int nLevels = 8, int edgeThreshold = 31, |
|
|
|
|
int firstLevel = 0, int WTA_K = 2, int scoreType = 0, int patchSize = 31); |
|
|
|
|
|
|
|
|
|
/** @overload */ |
|
|
|
|
void operator()(const GpuMat& image, const GpuMat& mask, std::vector<KeyPoint>& keypoints); |
|
|
|
|
/** @overload */ |
|
|
|
|
void operator()(const GpuMat& image, const GpuMat& mask, GpuMat& keypoints); |
|
|
|
|
|
|
|
|
|
/** @brief Detects keypoints and computes descriptors for them.
|
|
|
|
|
|
|
|
|
|
@param image Input 8-bit grayscale image. |
|
|
|
|
@param mask Optional input mask that marks the regions where we should detect features. |
|
|
|
|
@param keypoints The input/output vector of keypoints. Can be stored both in CPU and GPU memory. |
|
|
|
|
For GPU memory: |
|
|
|
|
- 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\>(RESPONSE_ROW)[i] contains the response of the i'th feature. |
|
|
|
|
- keypoints.ptr\<float\>(ANGLE_ROW)[i] contains orientation 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. |
|
|
|
|
@param descriptors Computed descriptors. if blurForDescriptor is true, image will be blurred |
|
|
|
|
before descriptors calculation. |
|
|
|
|
virtual void matchConvert(InputArray gpu_matches, |
|
|
|
|
std::vector<DMatch>& matches) = 0; |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// knn match
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
/** @brief Finds the k best matches for each descriptor from a query set (blocking version).
|
|
|
|
|
|
|
|
|
|
@param queryDescriptors Query set of descriptors. |
|
|
|
|
@param trainDescriptors Train set of descriptors. This set is not added to the train descriptors |
|
|
|
|
collection stored in the class object. |
|
|
|
|
@param matches Matches. Each matches[i] is k or less matches for the same query descriptor. |
|
|
|
|
@param k Count of best matches found per each query descriptor or less if a query descriptor has |
|
|
|
|
less than k possible matches in total. |
|
|
|
|
@param mask Mask specifying permissible matches between an input query and train matrices of |
|
|
|
|
descriptors. |
|
|
|
|
@param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is |
|
|
|
|
false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, |
|
|
|
|
the matches vector does not contain matches for fully masked-out query descriptors. |
|
|
|
|
|
|
|
|
|
These extended variants of DescriptorMatcher::match methods find several best matches for each query |
|
|
|
|
descriptor. The matches are returned in the distance increasing order. See DescriptorMatcher::match |
|
|
|
|
for the details about query and train descriptors. |
|
|
|
|
*/ |
|
|
|
|
void operator()(const GpuMat& image, const GpuMat& mask, std::vector<KeyPoint>& keypoints, GpuMat& descriptors); |
|
|
|
|
/** @overload */ |
|
|
|
|
void operator()(const GpuMat& image, const GpuMat& mask, GpuMat& keypoints, GpuMat& descriptors); |
|
|
|
|
virtual void knnMatch(InputArray queryDescriptors, InputArray trainDescriptors, |
|
|
|
|
std::vector<std::vector<DMatch> >& matches, |
|
|
|
|
int k, |
|
|
|
|
InputArray mask = noArray(), |
|
|
|
|
bool compactResult = false) = 0; |
|
|
|
|
|
|
|
|
|
/** @brief Download keypoints from GPU to CPU memory.
|
|
|
|
|
*/ |
|
|
|
|
static void downloadKeyPoints(const GpuMat& d_keypoints, std::vector<KeyPoint>& keypoints); |
|
|
|
|
/** @brief Converts keypoints from CUDA representation to vector of KeyPoint.
|
|
|
|
|
*/ |
|
|
|
|
static void convertKeyPoints(const Mat& d_keypoints, std::vector<KeyPoint>& keypoints); |
|
|
|
|
/** @overload
|
|
|
|
|
*/ |
|
|
|
|
virtual void knnMatch(InputArray queryDescriptors, |
|
|
|
|
std::vector<std::vector<DMatch> >& matches, |
|
|
|
|
int k, |
|
|
|
|
const std::vector<GpuMat>& masks = std::vector<GpuMat>(), |
|
|
|
|
bool compactResult = false) = 0; |
|
|
|
|
|
|
|
|
|
/** @brief Finds the k best matches for each descriptor from a query set (asynchronous version).
|
|
|
|
|
|
|
|
|
|
@param queryDescriptors Query set of descriptors. |
|
|
|
|
@param trainDescriptors Train set of descriptors. This set is not added to the train descriptors |
|
|
|
|
collection stored in the class object. |
|
|
|
|
@param matches Matches array stored in GPU memory. Internal representation is not defined. |
|
|
|
|
Use DescriptorMatcher::knnMatchConvert method to retrieve results in standard representation. |
|
|
|
|
@param k Count of best matches found per each query descriptor or less if a query descriptor has |
|
|
|
|
less than k possible matches in total. |
|
|
|
|
@param mask Mask specifying permissible matches between an input query and train matrices of |
|
|
|
|
descriptors. |
|
|
|
|
@param stream CUDA stream. |
|
|
|
|
|
|
|
|
|
These extended variants of DescriptorMatcher::matchAsync methods find several best matches for each query |
|
|
|
|
descriptor. The matches are returned in the distance increasing order. See DescriptorMatcher::matchAsync |
|
|
|
|
for the details about query and train descriptors. |
|
|
|
|
*/ |
|
|
|
|
virtual void knnMatchAsync(InputArray queryDescriptors, InputArray trainDescriptors, |
|
|
|
|
OutputArray matches, |
|
|
|
|
int k, |
|
|
|
|
InputArray mask = noArray(), |
|
|
|
|
Stream& stream = Stream::Null()) = 0; |
|
|
|
|
|
|
|
|
|
//! returns the descriptor size in bytes
|
|
|
|
|
inline int descriptorSize() const { return kBytes; } |
|
|
|
|
/** @overload
|
|
|
|
|
*/ |
|
|
|
|
virtual void knnMatchAsync(InputArray queryDescriptors, |
|
|
|
|
OutputArray matches, |
|
|
|
|
int k, |
|
|
|
|
const std::vector<GpuMat>& masks = std::vector<GpuMat>(), |
|
|
|
|
Stream& stream = Stream::Null()) = 0; |
|
|
|
|
|
|
|
|
|
/** @brief Converts matches array from internal representation to standard matches vector.
|
|
|
|
|
|
|
|
|
|
The method is supposed to be used with DescriptorMatcher::knnMatchAsync to get final result. |
|
|
|
|
Call this method only after DescriptorMatcher::knnMatchAsync is completed (ie. after synchronization). |
|
|
|
|
|
|
|
|
|
@param gpu_matches Matches, returned from DescriptorMatcher::knnMatchAsync. |
|
|
|
|
@param matches Vector of DMatch objects. |
|
|
|
|
@param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is |
|
|
|
|
false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, |
|
|
|
|
the matches vector does not contain matches for fully masked-out query descriptors. |
|
|
|
|
*/ |
|
|
|
|
virtual void knnMatchConvert(InputArray gpu_matches, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, |
|
|
|
|
bool compactResult = false) = 0; |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// radius match
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
/** @brief For each query descriptor, finds the training descriptors not farther than the specified distance (blocking version).
|
|
|
|
|
|
|
|
|
|
@param queryDescriptors Query set of descriptors. |
|
|
|
|
@param trainDescriptors Train set of descriptors. This set is not added to the train descriptors |
|
|
|
|
collection stored in the class object. |
|
|
|
|
@param matches Found matches. |
|
|
|
|
@param maxDistance Threshold for the distance between matched descriptors. Distance means here |
|
|
|
|
metric distance (e.g. Hamming distance), not the distance between coordinates (which is measured |
|
|
|
|
in Pixels)! |
|
|
|
|
@param mask Mask specifying permissible matches between an input query and train matrices of |
|
|
|
|
descriptors. |
|
|
|
|
@param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is |
|
|
|
|
false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, |
|
|
|
|
the matches vector does not contain matches for fully masked-out query descriptors. |
|
|
|
|
|
|
|
|
|
For each query descriptor, the methods find such training descriptors that the distance between the |
|
|
|
|
query descriptor and the training descriptor is equal or smaller than maxDistance. Found matches are |
|
|
|
|
returned in the distance increasing order. |
|
|
|
|
*/ |
|
|
|
|
virtual void radiusMatch(InputArray queryDescriptors, InputArray trainDescriptors, |
|
|
|
|
std::vector<std::vector<DMatch> >& matches, |
|
|
|
|
float maxDistance, |
|
|
|
|
InputArray mask = noArray(), |
|
|
|
|
bool compactResult = false) = 0; |
|
|
|
|
|
|
|
|
|
inline void setFastParams(int threshold, bool nonmaxSuppression = true) |
|
|
|
|
{ |
|
|
|
|
fastDetector_.threshold = threshold; |
|
|
|
|
fastDetector_.nonmaxSuppression = nonmaxSuppression; |
|
|
|
|
} |
|
|
|
|
/** @overload
|
|
|
|
|
*/ |
|
|
|
|
virtual void radiusMatch(InputArray queryDescriptors, |
|
|
|
|
std::vector<std::vector<DMatch> >& matches, |
|
|
|
|
float maxDistance, |
|
|
|
|
const std::vector<GpuMat>& masks = std::vector<GpuMat>(), |
|
|
|
|
bool compactResult = false) = 0; |
|
|
|
|
|
|
|
|
|
/** @brief For each query descriptor, finds the training descriptors not farther than the specified distance (asynchronous version).
|
|
|
|
|
|
|
|
|
|
@param queryDescriptors Query set of descriptors. |
|
|
|
|
@param trainDescriptors Train set of descriptors. This set is not added to the train descriptors |
|
|
|
|
collection stored in the class object. |
|
|
|
|
@param matches Matches array stored in GPU memory. Internal representation is not defined. |
|
|
|
|
Use DescriptorMatcher::radiusMatchConvert method to retrieve results in standard representation. |
|
|
|
|
@param maxDistance Threshold for the distance between matched descriptors. Distance means here |
|
|
|
|
metric distance (e.g. Hamming distance), not the distance between coordinates (which is measured |
|
|
|
|
in Pixels)! |
|
|
|
|
@param mask Mask specifying permissible matches between an input query and train matrices of |
|
|
|
|
descriptors. |
|
|
|
|
@param stream CUDA stream. |
|
|
|
|
|
|
|
|
|
For each query descriptor, the methods find such training descriptors that the distance between the |
|
|
|
|
query descriptor and the training descriptor is equal or smaller than maxDistance. Found matches are |
|
|
|
|
returned in the distance increasing order. |
|
|
|
|
*/ |
|
|
|
|
virtual void radiusMatchAsync(InputArray queryDescriptors, InputArray trainDescriptors, |
|
|
|
|
OutputArray matches, |
|
|
|
|
float maxDistance, |
|
|
|
|
InputArray mask = noArray(), |
|
|
|
|
Stream& stream = Stream::Null()) = 0; |
|
|
|
|
|
|
|
|
|
/** @brief Releases inner buffer memory.
|
|
|
|
|
*/ |
|
|
|
|
void release(); |
|
|
|
|
/** @overload
|
|
|
|
|
*/ |
|
|
|
|
virtual void radiusMatchAsync(InputArray queryDescriptors, |
|
|
|
|
OutputArray matches, |
|
|
|
|
float maxDistance, |
|
|
|
|
const std::vector<GpuMat>& masks = std::vector<GpuMat>(), |
|
|
|
|
Stream& stream = Stream::Null()) = 0; |
|
|
|
|
|
|
|
|
|
/** @brief Converts matches array from internal representation to standard matches vector.
|
|
|
|
|
|
|
|
|
|
The method is supposed to be used with DescriptorMatcher::radiusMatchAsync to get final result. |
|
|
|
|
Call this method only after DescriptorMatcher::radiusMatchAsync is completed (ie. after synchronization). |
|
|
|
|
|
|
|
|
|
@param gpu_matches Matches, returned from DescriptorMatcher::radiusMatchAsync. |
|
|
|
|
@param matches Vector of DMatch objects. |
|
|
|
|
@param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is |
|
|
|
|
false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, |
|
|
|
|
the matches vector does not contain matches for fully masked-out query descriptors. |
|
|
|
|
*/ |
|
|
|
|
virtual void radiusMatchConvert(InputArray gpu_matches, |
|
|
|
|
std::vector< std::vector<DMatch> >& matches, |
|
|
|
|
bool compactResult = false) = 0; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//! if true, image will be blurred before descriptors calculation
|
|
|
|
|
bool blurForDescriptor; |
|
|
|
|
//
|
|
|
|
|
// Feature2DAsync
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
enum { kBytes = 32 }; |
|
|
|
|
/** @brief Abstract base class for CUDA asynchronous 2D image feature detectors and descriptor extractors.
|
|
|
|
|
*/ |
|
|
|
|
class CV_EXPORTS Feature2DAsync |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
virtual ~Feature2DAsync(); |
|
|
|
|
|
|
|
|
|
void buildScalePyramids(const GpuMat& image, const GpuMat& mask); |
|
|
|
|
/** @brief Detects keypoints in an image.
|
|
|
|
|
|
|
|
|
|
void computeKeyPointsPyramid(); |
|
|
|
|
@param image Image. |
|
|
|
|
@param keypoints The detected keypoints. |
|
|
|
|
@param mask Mask specifying where to look for keypoints (optional). It must be a 8-bit integer |
|
|
|
|
matrix with non-zero values in the region of interest. |
|
|
|
|
@param stream CUDA stream. |
|
|
|
|
*/ |
|
|
|
|
virtual void detectAsync(InputArray image, |
|
|
|
|
OutputArray keypoints, |
|
|
|
|
InputArray mask = noArray(), |
|
|
|
|
Stream& stream = Stream::Null()); |
|
|
|
|
|
|
|
|
|
void computeDescriptors(GpuMat& descriptors); |
|
|
|
|
/** @brief Computes the descriptors for a set of keypoints detected in an image.
|
|
|
|
|
|
|
|
|
|
void mergeKeyPoints(GpuMat& keypoints); |
|
|
|
|
@param image Image. |
|
|
|
|
@param keypoints Input collection of keypoints. |
|
|
|
|
@param descriptors Computed descriptors. Row j is the descriptor for j-th keypoint. |
|
|
|
|
@param stream CUDA stream. |
|
|
|
|
*/ |
|
|
|
|
virtual void computeAsync(InputArray image, |
|
|
|
|
OutputArray keypoints, |
|
|
|
|
OutputArray descriptors, |
|
|
|
|
Stream& stream = Stream::Null()); |
|
|
|
|
|
|
|
|
|
/** Detects keypoints and computes the descriptors. */ |
|
|
|
|
virtual void detectAndComputeAsync(InputArray image, |
|
|
|
|
InputArray mask, |
|
|
|
|
OutputArray keypoints, |
|
|
|
|
OutputArray descriptors, |
|
|
|
|
bool useProvidedKeypoints = false, |
|
|
|
|
Stream& stream = Stream::Null()); |
|
|
|
|
|
|
|
|
|
/** Converts keypoints array from internal representation to standard vector. */ |
|
|
|
|
virtual void convert(InputArray gpu_keypoints, |
|
|
|
|
std::vector<KeyPoint>& keypoints) = 0; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
int nFeatures_; |
|
|
|
|
float scaleFactor_; |
|
|
|
|
int nLevels_; |
|
|
|
|
int edgeThreshold_; |
|
|
|
|
int firstLevel_; |
|
|
|
|
int WTA_K_; |
|
|
|
|
int scoreType_; |
|
|
|
|
int patchSize_; |
|
|
|
|
//
|
|
|
|
|
// FastFeatureDetector
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
//! The number of desired features per scale
|
|
|
|
|
std::vector<size_t> n_features_per_level_; |
|
|
|
|
/** @brief Wrapping class for feature detection using the FAST method.
|
|
|
|
|
*/ |
|
|
|
|
class CV_EXPORTS FastFeatureDetector : public cv::FastFeatureDetector, public Feature2DAsync |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
enum
|
|
|
|
|
{ |
|
|
|
|
LOCATION_ROW = 0, |
|
|
|
|
RESPONSE_ROW, |
|
|
|
|
ROWS_COUNT, |
|
|
|
|
|
|
|
|
|
//! Points to compute BRIEF descriptors from
|
|
|
|
|
GpuMat pattern_; |
|
|
|
|
FEATURE_SIZE = 7 |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
std::vector<GpuMat> imagePyr_; |
|
|
|
|
std::vector<GpuMat> maskPyr_; |
|
|
|
|
static Ptr<FastFeatureDetector> create(int threshold=10, |
|
|
|
|
bool nonmaxSuppression=true, |
|
|
|
|
int type=FastFeatureDetector::TYPE_9_16, |
|
|
|
|
int max_npoints = 5000); |
|
|
|
|
|
|
|
|
|
GpuMat buf_; |
|
|
|
|
virtual void setMaxNumPoints(int max_npoints) = 0; |
|
|
|
|
virtual int getMaxNumPoints() const = 0; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
std::vector<GpuMat> keyPointsPyr_; |
|
|
|
|
std::vector<int> keyPointsCount_; |
|
|
|
|
//
|
|
|
|
|
// ORB
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
FAST_CUDA fastDetector_; |
|
|
|
|
/** @brief Class implementing the ORB (*oriented BRIEF*) keypoint detector and descriptor extractor
|
|
|
|
|
* |
|
|
|
|
* @sa cv::ORB |
|
|
|
|
*/ |
|
|
|
|
class CV_EXPORTS ORB : public cv::ORB, public Feature2DAsync |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
enum
|
|
|
|
|
{ |
|
|
|
|
X_ROW = 0, |
|
|
|
|
Y_ROW, |
|
|
|
|
RESPONSE_ROW, |
|
|
|
|
ANGLE_ROW, |
|
|
|
|
OCTAVE_ROW, |
|
|
|
|
SIZE_ROW, |
|
|
|
|
ROWS_COUNT |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
Ptr<cuda::Filter> blurFilter; |
|
|
|
|
static Ptr<ORB> create(int nfeatures=500, |
|
|
|
|
float scaleFactor=1.2f, |
|
|
|
|
int nlevels=8, |
|
|
|
|
int edgeThreshold=31, |
|
|
|
|
int firstLevel=0, |
|
|
|
|
int WTA_K=2, |
|
|
|
|
int scoreType=ORB::HARRIS_SCORE, |
|
|
|
|
int patchSize=31, |
|
|
|
|
int fastThreshold=20, |
|
|
|
|
bool blurForDescriptor=false); |
|
|
|
|
|
|
|
|
|
GpuMat d_keypoints_; |
|
|
|
|
//! if true, image will be blurred before descriptors calculation
|
|
|
|
|
virtual void setBlurForDescriptor(bool blurForDescriptor) = 0; |
|
|
|
|
virtual bool getBlurForDescriptor() const = 0; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//! @}
|
|
|
|
|