00001 /*!@file SIFT/VisualObject.C Visual Objects to be recognized */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: John McInerney <jmcinerney6@gmail.com> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/CUDASIFT/CUDAVisualObject.C $ 00035 // $Id: CUDAVisualObject.C 14295 2010-12-02 20:02:32Z itti $ 00036 // 00037 00038 #include "CUDASIFT/CUDAVisualObject.H" 00039 #include "SIFT/VisualObject.H" 00040 #include "SIFT/ScaleSpace.H" 00041 #include "Image/ColorOps.H" 00042 //#include "Image/DrawOps.H" 00043 #include "Image/ShapeOps.H" 00044 #include "Image/Kernels.H" 00045 #include "Image/FilterOps.H" 00046 #include "Image/MathOps.H" 00047 //#include "Image/Pixels.H" 00048 //#include "Raster/Raster.H" 00049 00050 #include "CUDASIFT/cudaImage.h" 00051 #include "CUDASIFT/cudaSift.h" 00052 #include "CUDASIFT/tpimageutil.h" 00053 #include "CUDASIFT/tpimage.h" 00054 #include <algorithm> 00055 #include <cmath> 00056 #include <istream> 00057 #include <ostream> 00058 00059 #include <cctype> 00060 00061 00062 // ###################################################################### 00063 void CUDAVisualObject:: computeKeypoints() 00064 { 00065 CudaImage img1; 00066 // If we were given an image but no keypoints, let's extract them now: 00067 if(itsImage.initialized()) printf("Image initialized in computeKeypoints.\n"); 00068 else printf("Image not initialized in computeKeypoints.\n"); 00069 00070 if(itsKeypoints.empty()) printf("Keypoints empty in computeKeypoints.\n"); 00071 else printf("Keypoints not empty in computeKeypoints.\n"); 00072 00073 if (itsImage.initialized() && itsKeypoints.empty()){ 00074 LDEBUG("%s: initializing ScaleSpace from %dx%d image...", 00075 itsName.c_str(), itsImage.getWidth(), itsImage.getHeight()); 00076 00077 Image <float> fimage = luminance(itsImage); // CUDA SIFT only works on monochrome 00078 Image <float> lum = luminance(fimage); 00079 SImage<float> limg(lum.getWidth(),lum.getHeight(),lum.getArrayPtr()); 00080 //rescale(fimage, 256, 256);//Shouldn't be needed 00081 ReScale(limg, 1.0/256.0f); 00082 unsigned int w = limg.GetWidth(); 00083 unsigned int h = limg.GetHeight(); 00084 00085 std::cout << "Image size = (" << w << "," << h << ")" << std::endl; 00086 00087 AllocCudaImage(&img1, w, h, w, false, true); 00088 img1.h_data = limg.GetData(); 00089 Download(&img1); 00090 SiftData siftData; 00091 // There's a problem here! The second parameter should be the initial 00092 // number of keypoints. AddKeypoints should increase this as needed. 00093 // Setting this to 128 or 1024 seems to give somewhat reasonable results. 00094 // The keypoint prune for the Hough transform removes almost all the keypoints 00095 // for other powers of 2 including: 00096 // 1, 2, 4, 8, 16, 32, 64, 256, 512, 2048, 8192, 16384 00097 // Also, 00098 // the number of keypoints is different for the first run, running 00099 // through more than once seems to give consistent results... 00100 for (int j=0; j<0;j++){ 00101 InitSiftData(&siftData, 128, true, true); 00102 ExtractSift(&siftData, &img1, 3, 3, 0.3f, 0.02f); 00103 //PrintSiftData(&siftData); 00104 printf("DERK siftData.numPts=%d, siftData.maxPts=%d\n",siftData.numPts,siftData.maxPts); 00105 FreeSiftData(&siftData); 00106 } 00107 00108 InitSiftData(&siftData, 128, true, true); 00109 //Try a few different parameters for threshold. Lowe says 0.03f. 00110 //ExtractSift(&siftData, &img1, 3, 3, 0.3f, 0.04); 00111 ExtractSift(&siftData, &img1, 3, 3, 0.3f, 0.015f); 00112 //PrintSiftData(&siftData); //print them out to compare 00113 printf("DERK2 siftData.numPts=%d, siftData.maxPts=%d\n",siftData.numPts,siftData.maxPts); 00114 00115 for(int k=0;k<siftData.numPts;k++){ 00116 //printf("siftData.h_data[k].xpos=%f,siftData.h_data[k].ypos=%f\n", 00117 //siftData.h_data[k].xpos,siftData.h_data[k].ypos); 00118 float xpos = siftData.h_data[k].xpos; //itsX 00119 float ypos = siftData.h_data[k].ypos; //itsY 00120 float scale = siftData.h_data[k].scale; //itsS 00121 float orientation = siftData.h_data[k].orientation; //itsO 00122 float score = siftData.h_data[k].score; //itsM? not sure 00123 00124 std::vector<byte> OriFV = std::vector<byte>(); 00125 //std::vector<byte> ColFV = std::vector<byte>(); //no color 00126 00127 //In CUDA SIFT this is a float 128 vector. Convert to byte, so 00128 //unsigned? Some of the members of the float vector are negative. 00129 for(int l=0; l<128; l++){ //Hard coded as 128 byte vector 00130 ASSERT(siftData.h_data[k].data[l] > 0.0 - 0.0001); 00131 ASSERT(siftData.h_data[k].data[l] < 1.0 + 0.0001); 00132 //float temp = siftData.h_data[k].data[l] * 255.0; 00133 byte b = (byte) (siftData.h_data[k].data[l] * 255); // Vector components are [0,255] 00134 //if(temp > 255) printf("Oops, data not [0,1), temp = %.20f, byte=%d\n",temp,b); //Just checking 00135 //if(temp < 0) printf("Oops, data not [0,1), temp = %.20f, byte=%d\n",temp,b); //Just checking 00136 //printf("float siftData.h_data[%d].data[%d]= %f\n",k,l,siftData.h_data[k].data[l]); 00137 //printf("byte siftData.h_data[%d].data[%d]= %d\n",k,l,b); 00138 OriFV.push_back(b); 00139 //ColFV.push_back(b); //No color at this time 00140 } 00141 00142 //float ambiguity = siftData.h_data[k].ambiguity; //No analog in CPU SIFT 00143 //float edgeness = siftData.h_data[k].edgeness; //No analog in CPU SIFT 00144 00145 rutz::shared_ptr<Keypoint> r = 00146 rutz::shared_ptr<Keypoint>(new Keypoint(OriFV, xpos, ypos, scale, orientation, score)); 00147 itsKeypoints.push_back(r); 00148 } 00149 FreeSiftData(&siftData); 00150 img1.h_data=NULL; //Points to fimage, which is soon out of scope. 00151 FreeCudaImage(&img1); 00152 } 00153 }; 00154 00155 // ###################################################################### 00156 /* So things look consistent in everyone's emacs... */ 00157 /* Local Variables: */ 00158 /* indent-tabs-mode: nil */ 00159 /* End: */