00001 #include "SIFT/LoweSIFT.H" 00002 #include "rutz/pipe.h" 00003 #include "Image/ColorOps.H" 00004 00005 const ModelOptionCateg MOC_LoweSIFT = { 00006 MOC_SORTPRI_3, "Official David Lowe SIFT related options" }; 00007 00008 const ModelOptionDef OPT_ExeName = 00009 { MODOPT_ARG(std::string), "ExeName", &MOC_LoweSIFT, OPTEXP_CORE, 00010 "Path to the official David Lowe SIFT binary", 00011 "lowesift-exe", '\0', "path/to/sift", "sift" }; 00012 00013 // ###################################################################### 00014 LoweSIFT::LoweSIFT(OptionManager& mgr, 00015 std::string const & descrName, 00016 std::string const & tagName) : 00017 ModelComponent(mgr, descrName, tagName), 00018 itsExePath(&OPT_ExeName, this) 00019 { } 00020 00021 // ###################################################################### 00022 std::vector<rutz::shared_ptr<Keypoint> > 00023 LoweSIFT::computeKeypoints(Image<PixRGB<byte> > const & img) 00024 { 00025 if(!img.initialized()) LFATAL("Uninitialized Image!"); 00026 00027 Image<byte> imgGray = luminance(img); 00028 00029 rutz::bidir_pipe siftExe(itsExePath.getVal().c_str(), NULL); 00030 00031 // Output the image to the sift exe in binary PGM format 00032 siftExe.out_stream() << "P5\n"; 00033 siftExe.out_stream() << imgGray.getWidth() << " " << imgGray.getHeight() << "\n"; 00034 siftExe.out_stream() << "255\n"; 00035 for(Image<byte>::const_iterator imgIt = imgGray.begin(); imgIt != imgGray.end(); ++imgIt) 00036 { 00037 siftExe.out_stream() << *imgIt; 00038 } 00039 00040 // Close the output stream so the binary knows the file is done 00041 siftExe.close_out(); 00042 00043 // Read the total number of keypoints 00044 int numKeypoints; 00045 siftExe.in_stream() >> numKeypoints; 00046 00047 // Read the length of each keypoint vector 00048 int keypointLength; 00049 siftExe.in_stream() >> keypointLength; 00050 00051 // Loop through all the keypoints and read them in 00052 LDEBUG("Loading %d keypoints of length %d", numKeypoints, keypointLength); 00053 std::vector<rutz::shared_ptr<Keypoint> > keypoints; 00054 for(int keyIdx=0; keyIdx < numKeypoints; ++keyIdx) 00055 { 00056 // Read in the kp meta data 00057 float row, column, scale, orientation; 00058 siftExe.in_stream() >> row >> column >> scale >> orientation; 00059 00060 // Read in the actual feature vector 00061 std::vector<byte> features(keypointLength); 00062 for(int dimenIdx=0; dimenIdx<keypointLength; ++dimenIdx) 00063 { 00064 byte feature; 00065 siftExe.in_stream() >> feature; 00066 features[dimenIdx] = feature; 00067 } 00068 00069 // Create the keypoint 00070 keypoints.push_back(rutz::shared_ptr<Keypoint>( 00071 new Keypoint(features, column, row, scale, orientation, 1))); 00072 } 00073 00074 return keypoints; 00075 }