/** * @file LocalFeaturesiftGPU.cpp * @brief A Sift-Implementation, which uses the GPU. * @author Eric Bach * @date 11/20/2011 */ #include "LocalFeatureSiftGPU.h" #include "core/basics/StringTools.h" using namespace OBJREC; using namespace std; using namespace NICE; LocalFeatureSiftGPU::LocalFeatureSiftGPU (const Config* conf) : LocalFeatureSift (conf) { const string section = "SIFTGPU"; gpuLanguage = conf->gS (section, "language", "cuda"); multiGPU = conf->gB (section, "multigpu", false); numOfGPU = conf->gI (section, "numgpu" , 1); // for multiGPU its neccessary, that you got more the one devices /*if( multiGPU && ( numOfGPU < 2 ) ) fthrow( Exception, "For multiple GPU, you need more the one device!"); // fill deviceStat: all devices are unused (=free) for( unsigned int i=0; i < numOfGPU; i++ ) deviceStat.insert(pair(i, true));*/ } LocalFeatureSiftGPU::~LocalFeatureSiftGPU () { } int LocalFeatureSiftGPU::getNextDeviceID() { StatTable::iterator it = deviceStat.begin(); for (; it != deviceStat.end(); ++it) { bool free = it->second; if (free) { it->second = !free; return it->first; } } // no free device was found return -1; } void LocalFeatureSiftGPU::releaseDevice (int id) { StatTable::iterator it = deviceStat.find (id); // if given id is associated with a device, set this gpu on free if (it != deviceStat.end()) it->second = true; } void LocalFeatureSiftGPU::computeDesc (const NICE::Image & img, VVector & positions, VVector & descriptors) const { // fill the parameter for //char device[2] = {'0' + deviceID, '\0'}; char* argv[] = { // First octave to detect DOG keypoints "-fo" , const_cast (StringTools::convertToString (first_octave).c_str()), // Maximum number of Octaves "-no" , const_cast (StringTools::convertToString (octaves).c_str()), // Number of DOG levels in an octave. "-d" , const_cast (StringTools::convertToString (levels).c_str()), // Write unnormalized descriptor if specified. const_cast (normalizeFeature ? "" : "-unn"), // Descriptor grid size factor (magnif ??) "-dw" , const_cast (StringTools::convertToString (magnif).c_str()), // use cuda / which device TODO const_cast (gpuLanguage == "cuda" ? "-cuda" : "-pack"), const_cast (gpuLanguage == "cuda" ? "0" : ""), // verbose levels "-v", "0" }; int argc = sizeof (argv) / sizeof (char*); // sift Instanz SiftGPU sift; // give parameter to sift sift.ParseParam (argc, argv); // check, whether siftgpu is full supported const int support = sift.CreateContextGL(); // const int support = sift.VerifyContextGL(); /*if( support == SiftGPU::SIFTGPU_PARTIAL_SUPPORTED ) clog << "ยท[log] LocalFeatureSift: SIFTGPU spartial supported" << endl;*/ if ( support != SiftGPU::SIFTGPU_FULL_SUPPORTED) { fthrow( Exception, "LocalFeatureSift: Its not able to use SIFTGPU, because it is not supported." ); } else{ clog << "[log] LocalFeatureSift: SIFTGPU full supported" << endl; } // set keypoints const int numberOfKeypoints = positions.size(); SiftGPU::SiftKeypoint keys[numberOfKeypoints]; // copy the NICEKeypoints into SiftKeypoints for (int i = 0; i < numberOfKeypoints; i++) { keys[i].x = positions[i][0]; keys[i].y = positions[i][1]; keys[i].s = positions[i][2]; keys[i].o = positions[i][3]; } sift.SetKeypointList (numberOfKeypoints, keys); // run SIFT const int imageWidth = img.width(); const int imageHeight = img.height(); const unsigned char* rawImageData = img.getPixelPointer(); sift.RunSIFT (imageWidth, imageHeight, rawImageData, GL_LUMINANCE, GL_UNSIGNED_BYTE); // get descriptors const int descr_size = 128; const int numberOfDescriptors = sift.GetFeatureNum(); float desc[descr_size * numberOfDescriptors]; //vector desc (descr_size * numberOfDescriptors); sift.GetFeatureVector (keys, desc); // TODO: kopieren durch Iterator erledigen Vector localDesc (descr_size); // copy the SiftDescriptors into NICEDescriptors for (int i = 0; i < numberOfDescriptors; i++) { for (int j = 0; j < descr_size; j++) { localDesc[j] = (integerValues ? (int) (512 * desc[i*descr_size+j]) : desc[i*descr_size+j]); } descriptors.push_back (localDesc); } } int LocalFeatureSiftGPU::getDescriptors (const NICE::Image & img, VVector & positions, VVector & descriptors) const { sortPositions (positions); computeDesc (img, positions, descriptors); return 0; }