Commit 8d5e9522 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

very preliminary port of SURF to T-API (compiles but certainly does not work)

parent 652a0bd5
......@@ -235,7 +235,7 @@ public:
// Compute the BRISK features and descriptors on an image
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;
......
......@@ -142,7 +142,6 @@ public:
CV_PROP_RW bool upright;
protected:
void detectImpl( InputArray image, std::vector<KeyPoint>& keypoints, InputArray mask = noArray() ) 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__
......@@ -45,6 +45,12 @@
//
//M*/
// The number of degrees between orientation samples in calcOrientation
#define ORI_SEARCH_INC 5
// The local size of the calcOrientation kernel
#define ORI_LOCAL_SIZE (360 / ORI_SEARCH_INC)
// specialized for non-image2d_t supported platform, intel HD4000, for example
#ifdef DISABLE_IMAGE2D
#define IMAGE_INT32 __global uint *
......@@ -175,7 +181,7 @@ F calcAxisAlignedDerivative(
}
//calculate targeted layer per-pixel determinant and trace with an integral image
__kernel void icvCalcLayerDetAndTrace(
__kernel void SURF_calcLayerDetAndTrace(
IMAGE_INT32 sumTex, // input integral image
__global float * det, // output Determinant
__global float * trace, // output trace
......@@ -338,7 +344,7 @@ bool within_check(IMAGE_INT32 maskSumTex, int sum_i, int sum_j, int size, int ro
// Non-maximal suppression to further filtering the candidates from previous step
__kernel
void icvFindMaximaInLayer_withmask(
void SURF_findMaximaInLayerWithMask(
__global const float * det,
__global const float * trace,
__global int4 * maxPosBuffer,
......@@ -466,7 +472,7 @@ void icvFindMaximaInLayer_withmask(
}
__kernel
void icvFindMaximaInLayer(
void SURF_findMaximaInLayer(
__global float * det,
__global float * trace,
__global int4 * maxPosBuffer,
......@@ -624,7 +630,7 @@ inline bool solve3x3_float(const float4 *A, const float *b, float *x)
////////////////////////////////////////////////////////////////////////
// INTERPOLATION
__kernel
void icvInterpolateKeypoint(
void SURF_interpolateKeypoint(
__global const float * det,
__global const int4 * maxPosBuffer,
__global float * keypoints,
......@@ -829,7 +835,7 @@ void reduce_32_sum(volatile __local float * data, volatile float* partial_reduc
}
__kernel
void icvCalcOrientation(
void SURF_calcOrientation(
IMAGE_INT32 sumTex,
__global float * keypoints,
int keypoints_step,
......@@ -995,18 +1001,17 @@ void icvCalcOrientation(
}
__kernel
void icvSetUpright(
void SURF_setUpright(
__global float * keypoints,
int keypoints_step,
int nFeatures
)
int keypoints_step, int keypoints_offset,
int rows, int cols )
{
int i = get_global_id(0);
keypoints_step /= sizeof(*keypoints);
__global float* featureDir = keypoints + ANGLE_ROW * keypoints_step;
if(get_global_id(0) <= nFeatures)
if(i < cols)
{
featureDir[get_global_id(0)] = 270.0f;
keypoints[mad24(keypoints_step, ANGLE_ROW, i)] = 270.f;
}
}
......@@ -1162,6 +1167,7 @@ void calc_dx_dy(
s_dy_bin[tid] = vy;
}
}
void reduce_sum25(
volatile __local float* sdata1,
volatile __local float* sdata2,
......@@ -1225,16 +1231,14 @@ void reduce_sum25(
}
__kernel
void compute_descriptors64(
void SURF_computeDescriptors64(
IMAGE_INT8 imgTex,
int img_step, int img_offset,
int rows, int cols,
__global const float* keypoints,
int keypoints_step, int keypoints_offset,
__global float * descriptors,
__global const float * keypoints,
int descriptors_step,
int keypoints_step,
int rows,
int cols,
int img_step
)
int descriptors_step, int descriptors_offset)
{
descriptors_step /= sizeof(float);
keypoints_step /= sizeof(float);
......@@ -1279,17 +1283,16 @@ void compute_descriptors64(
}
}
}
__kernel
void compute_descriptors128(
void SURF_computeDescriptors128(
IMAGE_INT8 imgTex,
__global float * descriptors,
__global float * keypoints,
int descriptors_step,
int keypoints_step,
int rows,
int cols,
int img_step
)
int img_step, int img_offset,
int rows, int cols,
__global const float* keypoints,
int keypoints_step, int keypoints_offset,
__global float* descriptors,
int descriptors_step, int descriptors_offset)
{
descriptors_step /= sizeof(*descriptors);
keypoints_step /= sizeof(*keypoints);
......@@ -1483,7 +1486,7 @@ void reduce_sum64(volatile __local float* smem, int tid)
}
__kernel
void normalize_descriptors128(__global float * descriptors, int descriptors_step)
void SURF_normalizeDescriptors128(__global float * descriptors, int descriptors_step)
{
descriptors_step /= sizeof(*descriptors);
// no need for thread ID
......@@ -1509,8 +1512,9 @@ void normalize_descriptors128(__global float * descriptors, int descriptors_step
// normalize and store in output
descriptor_base[get_local_id(0)] = lookup / len;
}
__kernel
void normalize_descriptors64(__global float * descriptors, int descriptors_step)
void SURF_normalizeDescriptors64(__global float * descriptors, int descriptors_step)
{
descriptors_step /= sizeof(*descriptors);
// no need for thread ID
......
......@@ -60,11 +60,6 @@
# include "opencv2/cudaarithm.hpp"
#endif
#ifdef HAVE_OPENCV_OCL
# include "opencv2/nonfree/ocl.hpp"
# include "opencv2/ocl/private/util.hpp"
#endif
#include "opencv2/core/private.hpp"
#endif
......@@ -108,6 +108,7 @@ Modifications by Ian Mahon
*/
#include "precomp.hpp"
#include "surf.hpp"
namespace cv
{
......@@ -897,11 +898,42 @@ void SURF::operator()(InputArray _img, InputArray _mask,
OutputArray _descriptors,
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();
CV_Assert(!img.empty() && img.depth() == CV_8U);
if( img.channels() > 1 )
CV_Assert(!_img.empty() && CV_MAT_DEPTH(imgtype) == CV_8U && (imgcn == 1 || imgcn == 3 || imgcn == 4));
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);
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(UMat &det, UMat &trace, int octave, int layer_rows);
bool findMaximaInLayer(const UMat &det, const UMat &trace, UMat &maxPosBuffer,
UMat &maxCounter, int counterOffset,
int octave, int layer_rows, int layer_cols);
bool interpolateKeypoint(const UMat &det, const UMat &maxPosBuffer, int maxCounter,
UMat &keypoints, UMat &counters, 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, mask1, maskSum, intBuffer;
UMat det, trace;
UMat maxPosBuffer;
int img_cols, img_rows;
int maxCandidates;
int maxFeatures;
UMat img, counters;
// texture buffers
ocl::Image2D imgTex, sumTex, maskSumTex;
bool haveImageSupport;
int status;
ocl::Kernel kerCalcDetTrace, kerFindMaxima, kerFindMaximaMask, kerInterp;
ocl::Kernel kerUpRight, kerOri, kerCalcDesc64, kerCalcDesc128, kerNormDesc64, kerNormDesc128;
};
/*
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