00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "GpuSurfDetectorInternal.hpp"
00032 #include "gpu_utils.h"
00033 #include "assert_macros.hpp"
00034 #include "fasthessian.h"
00035 #include "gpu_area.h"
00036 #include "keypoint_interpolation.h"
00037 #include "non_max_suppression.h"
00038 #include "orientation.h"
00039 #include "descriptors.h"
00040 #include <boost/lexical_cast.hpp>
00041 #include <fstream>
00042 #include "detector.h"
00043
00044 namespace asrl {
00045
00046 GpuSurfDetectorInternal::GpuSurfDetectorInternal(GpuSurfConfiguration config) :
00047 m_initialized(false),
00048 m_config(config)
00049 {
00050 int deviceCount;
00051 int device;
00052 cudaError_t err;
00053 cudaGetDeviceCount(&deviceCount);
00054 ASRL_ASSERT_GT(deviceCount,0,"There are no CUDA capable devices present");
00055
00056
00057 err = cudaGetDevice(&device);
00058 ASRL_ASSERT_EQ(err,cudaSuccess, "Unable to get the CUDA device: " << cudaGetErrorString(err));
00059
00060 err = cudaGetDeviceProperties(&m_deviceProp,device);
00061 ASRL_ASSERT_EQ(err,cudaSuccess, "Unable to get the CUDA device properties: " << cudaGetErrorString(err));
00062
00063
00064 ASRL_ASSERT_GE(m_deviceProp.major,1,"Minimum compute capability 1.1 is necessary");
00065 ASRL_ASSERT_GE(m_deviceProp.minor,1,"Minimum compute capability 1.1 is necessary");
00066
00067 m_maxmin.init(ASRL_SURF_MAX_CANDIDATES,false);
00068 m_maxmin.memset(0);
00069
00070 }
00071
00072 GpuSurfDetectorInternal::~GpuSurfDetectorInternal()
00073 {
00074
00075 }
00076
00077 void GpuSurfDetectorInternal::buildIntegralImage(cv::Mat & image)
00078 {
00079
00080 if(!m_initialized || m_intImg->width() != image.cols || m_intImg->height() != image.rows)
00081 {
00082 initDetector(image.cols,image.rows);
00083 }
00084
00085 m_intProcessor->process(image, *m_intImg);
00086 texturize_integral_image(m_intImg->d_get());
00087 init_globals(m_intImg->width(), m_intImg->height(), m_octaves, m_config.nOctaves);
00088 }
00089
00090 void GpuSurfDetectorInternal::saveIntegralImage(std::string const & basename)
00091 {
00092 float * iimg = m_intImg->h_get();
00093 std::stringstream sout;
00094 sout << basename << "-iimg.bin";
00095 std::ofstream fout(sout.str().c_str(),std::ios::binary);
00096 ASRL_ASSERT(fout.good(),"Unable to open file \"" << sout.str() << "\" for writing");
00097 int size[2];
00098 size[0] = m_intImg->width();
00099 size[1] = m_intImg->height();
00100 fout.write(reinterpret_cast<const char *>(&size[0]),2*sizeof(int));
00101 fout.write(reinterpret_cast<const char *>(iimg),m_intImg->width()*m_intImg->height() * sizeof(float));
00102
00103 }
00104
00105
00106 void GpuSurfDetectorInternal::detectKeypoints()
00107 {
00108 detectKeypoints(m_config.threshold);
00109 }
00110
00111 void GpuSurfDetectorInternal::detectKeypoints(float threshold)
00112 {
00113 m_features.featureCounterMem().memset(0);
00114
00115
00116 for(int o = 0; o < m_config.nOctaves; o++)
00117 {
00118 if(m_octaves[o].valid())
00119 {
00120 run_surf_detector(m_interest.d_get(), m_octaves[o], o, m_features,
00121 threshold, m_config.detector_threads_x,
00122 m_config.detector_threads_y, m_config.nonmax_threads_x,
00123 m_config.nonmax_threads_y);
00124 }
00125 }
00126 }
00127
00128 void GpuSurfDetectorInternal::findOrientation()
00129 {
00130 int nFeatures = m_features.ftCount();
00131 if(nFeatures > 0)
00132 {
00133 find_orientation(m_features.deviceFeatures(), m_features.ftCount());
00134 ASRL_CHECK_CUDA_ERROR_DBG("Find orientation");
00135 }
00136 }
00137
00138 void GpuSurfDetectorInternal::findOrientationFast()
00139 {
00140 int nFeatures = m_features.ftCount();
00141 if(nFeatures > 0)
00142 {
00143 find_orientation_fast(m_features.deviceFeatures(), m_features.ftCount());
00144 ASRL_CHECK_CUDA_ERROR_DBG("Find orientation fast");
00145 }
00146 }
00147
00148 void GpuSurfDetectorInternal::computeDescriptors()
00149 {
00150 int nFeatures = m_features.ftCount();
00151
00152 if(nFeatures > 0)
00153 {
00154 compute_descriptors(m_features.deviceDescriptors(), m_features.deviceFeatures(), m_features.ftCount());
00155 ASRL_CHECK_CUDA_ERROR_DBG("compute descriptors");
00156 }
00157
00158 }
00159
00160 void GpuSurfDetectorInternal::computeUprightDescriptors()
00161 {
00162 ASRL_THROW("Not implemented");
00163 }
00164
00165 void GpuSurfDetectorInternal::getKeypoints(std::vector<cv::KeyPoint> & outKeypoints)
00166 {
00167 int ftcount = m_features.ftCount();
00168
00169 m_features.getKeypoints(outKeypoints);
00170
00171
00172 }
00173
00174
00175 void GpuSurfDetectorInternal::setKeypoints(std::vector<cv::KeyPoint> const & inKeypoints)
00176 {
00177 m_features.setKeypoints(inKeypoints);
00178 }
00179
00180 void GpuSurfDetectorInternal::getDescriptors(std::vector<float> & outDescriptors)
00181 {
00182 int ftcount = m_features.ftCount();
00183
00184 m_features.descriptorsMem().pullFromDevice();
00185 cudaThreadSynchronize();
00186
00187
00188
00189 outDescriptors.resize(descriptorSize() * ftcount);
00190
00191
00192 memcpy(&outDescriptors[0],m_features.hostDescriptors(), descriptorSize() * ftcount * sizeof(float));
00193
00194 }
00195
00196 int GpuSurfDetectorInternal::descriptorSize()
00197 {
00198 return ASRL_SURF_DESCRIPTOR_DIM;
00199 }
00200
00201
00202 void GpuSurfDetectorInternal::initDetector(int width, int height) {
00203
00204 m_intProcessor.reset(new GpuIntegralImageProcessor(width, height));
00205
00206 m_intImg.reset(new GpuIntegralImage(width, height));
00207
00208
00209 m_dxx_width = 1 + m_config.l1;
00210 m_dxx_height = m_config.l2;
00211
00212 for(int o = 0; o < m_config.nOctaves; o++)
00213 {
00214 m_octaves[o].init(width,height,m_config.l1,m_config.l2,m_config.l3, m_config.l4, m_config.edgeScale, m_config.initialScale, o, m_config.initialStep, m_config.nIntervals);
00215 }
00216
00217 m_interest.init(m_octaves[0].stride() * m_octaves[0].height() * m_octaves[0].intervals());
00218
00219 m_initialized = true;
00220 }
00221
00222 }