00001 00002 #include "CUDA/CudaCutPaste.H" 00003 #include "CUDA/CudaSaliency.H" 00004 #include "CUDA/CudaMathOps.H" 00005 #include "CUDA/CudaFramework.H" 00006 #include "CUDA/CudaImageDisplayGL.H" 00007 #include "Component/ModelManager.H" 00008 #include "INVT/neovision2cuda.H" 00009 #include "Util/StringConversions.H" 00010 #include "Transport/FrameInfo.H" 00011 #include "Util/log.H" 00012 #include "Util/StringUtil.H" 00013 #include <string> 00014 #include <vector> 00015 #define MAX_INPUT_WIDTH 1920 00016 #define MAX_INPUT_HEIGHT 1080 00017 #define CHARACTER_SIZE 10 00018 #define NFRAMESAVG 3 // Number of frames to average over to get Frames/Second 00019 00020 //Nv2LabelReader *reader = NULL; 00021 00022 00023 neovision2cuda::neovision2cuda(nub::ref<InputFrameSeries> ifs_in, nub::ref<OutputFrameSeries> ofs_in, nub::ref<CudaSaliency> csm_in, std::vector<rutz::shared_ptr<Nv2LabelReader> > readers_in) : CudaImageDisplayGL(), ifs(ifs_in), ofs(ofs_in), csm(csm_in), readers(readers_in) 00024 { 00025 frameTimes.clear(); 00026 } 00027 00028 // ###################################################################### 00029 void neovision2cuda::idleFunction() 00030 { 00031 if(getShutdown()) 00032 { 00033 printf("Shutdown\n"); 00034 exit(0); 00035 return; 00036 } 00037 cudaEvent_t start,stop; 00038 cudaEventCreate(&start); 00039 cudaEventCreate(&stop); 00040 cudaEventRecord(start,0); 00041 00042 pwin->update(); // handle pending preference window events 00043 00044 //Getting 1st frame image 00045 //printf("Handling frame\n"); 00046 const FrameState is = ifs->updateNext(); 00047 if (is == FRAME_COMPLETE) 00048 { 00049 printf("\n\n************************************** SHUTTING DOWN ******************************************\n\n"); 00050 setShutdown(true); 00051 return; 00052 } 00053 GenericFrame input = ifs->readFrame(); 00054 if (!input.initialized()) 00055 { 00056 printf("\n\n************************************** SHUTTING DOWN (Empty Frame) ******************************************\n\n"); 00057 setShutdown(true); 00058 return; 00059 } 00060 00061 static int FrameNumber = -1; 00062 FrameNumber++; 00063 00064 const Image<PixRGB<byte> > inbyte = input.asRgb(); 00065 00066 Image<PixRGB<float> > infloat = inbyte; 00067 //printf("Copying CPU image to CUDA\n"); 00068 CudaImage<PixRGB<float> > cfloat = CudaImage<PixRGB<float> >(infloat,framework.getMP(),framework.getDev()); 00069 //printf("Updating Canvas With Raw Image\n"); 00070 00071 // Need to shrink input if larger than 1920x1080 00072 //CudaImage<PixRGB<float> > cfloat_resize = cudaRescale(cfloat,int(600*x_scale),int(400*y_scale)); 00073 //Updating 00074 framework.updateCanvas(1,cfloat); 00075 00076 //Getting 2nd frame image 00077 //printf("Calculating Saliency\n"); 00078 csm->doCudaInput(cfloat); 00079 00080 //Different Maps 00081 CudaImage<float> out = csm->getCudaOutput(); 00082 00083 CudaImage<PixRGB<float> > cimap = cudaRescale(cudaToRGB(csm->getIMap()),w_cm,h_cm); 00084 CudaImage<PixRGB<float> > ccmap = cudaRescale(cudaToRGB(csm->getCMap()),w_cm,h_cm); 00085 CudaImage<PixRGB<float> > comap = cudaRescale(cudaToRGB(csm->getOMap()),w_cm,h_cm); 00086 CudaImage<PixRGB<float> > cfmap = cudaRescale(cudaToRGB(csm->getFMap()),w_cm,h_cm); 00087 CudaImage<PixRGB<float> > cmmap = cudaRescale(cudaToRGB(csm->getMMap()),w_cm,h_cm); 00088 CudaImage<PixRGB<float> > cinhibitionmap = cudaRescale(cudaToRGB(csm->getInhibitionMap()),w_sm,h_sm); 00089 00090 Point2D<int> salmap_peak; 00091 Point2D<int> rawmap_peak; 00092 Point2D<int> inputmap_peak; // Modified from raw map peak to fit on image, given a rectangle size 00093 00094 00095 std::vector<Point2D<int> > maxsaliency = csm->getSalMaxLoc(); 00096 std::vector<float > max_val = csm->getSalMax(); 00097 00098 //Scaling max_point 00099 CudaImage<PixRGB<float> > csal = cudaRescale(cudaToRGB(out),w_sm,h_sm); 00100 00101 00102 //Updating 00103 framework.updateCanvas(2,csal); 00104 framework.updateCanvas(3,cimap); 00105 framework.updateCanvas(4,ccmap); 00106 framework.updateCanvas(5,comap); 00107 framework.updateCanvas(6,cfmap); 00108 framework.updateCanvas(7,cmmap); 00109 framework.updateCanvas(8,cinhibitionmap); 00110 00111 char buffer[25]; 00112 // Push a frame time on 00113 frameTimes.push_back(Timer()); 00114 if(frameTimes.size() > NFRAMESAVG) 00115 { 00116 Timer t = frameTimes[0]; 00117 frameTimes.pop_front(); 00118 sprintf(buffer,"Frame No. %d, FPS %.2f",ifs->frame(),NFRAMESAVG/t.getSecs()); 00119 } 00120 else 00121 sprintf(buffer,"Frame No. %d",ifs->frame()); 00122 00123 int rectW = csm->getPatchSize(); 00124 int rectH = csm->getPatchSize(); 00125 00126 00127 00128 //Text update functions 00129 // framework.initTextLayer(CHARACTER_SIZE*40,20); 00130 // framework.setText(buffer,Point2D<int>(w_in,2*h_sm),PixRGB<float>(255.0f,0.0f,0.0f),PixRGB<float>(0.0f,0.0f,0.0f),SimpleFont::FIXED(10),false); 00131 // framework.initTextLayer(CHARACTER_SIZE*4,20); 00132 // framework.setText("IMAP",imapFramePoint,PixRGB<float>(255.0f,0.0f,0.0f),PixRGB<float>(0.0f,0.0f,0.0f),SimpleFont::FIXED(10),false); 00133 // framework.setText("CMAP",cmapFramePoint,PixRGB<float>(255.0f,0.0f,0.0f),PixRGB<float>(0.0f,0.0f,0.0f),SimpleFont::FIXED(10),false); 00134 // framework.setText("OMAP",omapFramePoint,PixRGB<float>(255.0f,0.0f,0.0f),PixRGB<float>(0.0f,0.0f,0.0f),SimpleFont::FIXED(10),false); 00135 // framework.setText("FMAP",fmapFramePoint,PixRGB<float>(255.0f,0.0f,0.0f),PixRGB<float>(0.0f,0.0f,0.0f),SimpleFont::FIXED(10),false); 00136 // framework.setText("MMAP",mmapFramePoint,PixRGB<float>(255.0f,0.0f,0.0f),PixRGB<float>(0.0f,0.0f,0.0f),SimpleFont::FIXED(10),false); 00137 // framework.initTextLayer(CHARACTER_SIZE*8,20); 00138 // framework.setText("InhibMAP",inhibitionMapFramePoint,PixRGB<float>(255.0f,0.0f,0.0f),PixRGB<float>(0.0f,0.0f,0.0f),SimpleFont::FIXED(10),false); 00139 // framework.initTextLayer(CHARACTER_SIZE*11,20); 00140 // framework.setText("SaliencyMAP",saliencyFramePoint,PixRGB<float>(255.0f,0.0f,0.0f),PixRGB<float>(0.0f,0.0f,0.0f),SimpleFont::FIXED(10),false); 00141 00142 // Draw rectangles to frame border of mapsup 00143 framework.drawRectangle_topleftpoint(imapFramePoint,PixRGB<float>(255.0f,255.0f,255.0f),w_cm,h_cm,1); 00144 framework.drawRectangle_topleftpoint(cmapFramePoint,PixRGB<float>(255.0f,255.0f,255.0f),w_cm,h_cm,1); 00145 framework.drawRectangle_topleftpoint(omapFramePoint,PixRGB<float>(255.0f,255.0f,255.0f),w_cm,h_cm,1); 00146 framework.drawRectangle_topleftpoint(fmapFramePoint,PixRGB<float>(255.0f,255.0f,255.0f),w_cm,h_cm,1); 00147 framework.drawRectangle_topleftpoint(mmapFramePoint,PixRGB<float>(255.0f,255.0f,255.0f),w_cm,h_cm,1); 00148 framework.drawRectangle_topleftpoint(saliencyFramePoint,PixRGB<float>(255.0f,255.0f,255.0f),w_sm,h_sm,1); 00149 framework.drawRectangle_topleftpoint(inhibitionMapFramePoint,PixRGB<float>(255.0f,255.0f,255.0f),w_sm,h_sm,1); 00150 00151 00152 for(unsigned int p=0;p<maxsaliency.size();p++) 00153 { 00154 rawmap_peak.i = maxsaliency[p].i * cfloat.getWidth() / double(out.getWidth()); 00155 rawmap_peak.j = maxsaliency[p].j * cfloat.getHeight() / double(out.getHeight()); 00156 inputmap_peak = rawmap_peak; 00157 00158 00159 // Make sure bounding box does not exceed size of image 00160 rectW=std::min((cfloat.getWidth()-rawmap_peak.i-1)*2,rectW); 00161 rectH=std::min((cfloat.getHeight()-rawmap_peak.j-1)*2,rectH); 00162 00163 // If we are running over the left edge 00164 if(inputmap_peak.i-rectW/2.0 < 0) 00165 { 00166 inputmap_peak.i=rectW/2.0; 00167 } 00168 // If we are running over the right edge 00169 if(inputmap_peak.i+rectW/2.0 >= cfloat.getWidth()) 00170 { 00171 inputmap_peak.i=cfloat.getWidth()-1-rectW/2.0; 00172 } 00173 // If we are running over the top edge 00174 if(inputmap_peak.j-rectH/2.0 < 0) 00175 { 00176 inputmap_peak.j=rectH/2.0; 00177 } 00178 // If we are running over the bottom edge 00179 if(inputmap_peak.j+rectH/2.0 >= cfloat.getHeight()) 00180 { 00181 inputmap_peak.j=cfloat.getHeight()-1-rectH/2.0; 00182 } 00183 00184 // Given the known good rectangle sitting at inputmap_peak, calculate the equivalent for the saliency map 00185 salmap_peak.i = saliencyFramePoint.i + inputmap_peak.i * csal.getWidth() / cfloat.getWidth(); 00186 salmap_peak.j = inputmap_peak.j * csal.getHeight() / cfloat.getHeight(); 00187 int salmapRectW = rectW*csal.getWidth()/double(cfloat.getWidth()); 00188 int salmapRectH = rectH*csal.getHeight()/double(cfloat.getHeight()); 00189 00190 00191 // Draw rectangles around peak activation 00192 framework.drawRectangle_centrepoint(inputmap_peak,PixRGB<float>(255.0f,0.0f,0.0f),rectW,rectH,1); 00193 framework.drawRectangle_centrepoint(salmap_peak,PixRGB<float>(255.0f,0.0f,0.0f),salmapRectW,salmapRectH,1); 00194 00195 00196 // Send the patch to any listening patch readers 00197 int fi = std::max(rawmap_peak.i-rectW/2,0); 00198 int fj = std::max(rawmap_peak.j-rectH/2,0); 00199 Rectangle foa = Rectangle(Point2D<int>(fi,fj),Dims(rectW,rectH)); 00200 int patch_id = ifs->frame()*maxsaliency.size()+p; 00201 rutz::time patchElapsedTime = rutz::time::wall_clock_now(); 00202 00203 bool isTraining = false; 00204 std::string label = std::string("FindLabel"); 00205 std::string remoteCommand = std::string(""); 00206 bool ignoreNonMatch = false; 00207 int textLength = 80; 00208 Image<PixRGB<float> > img = cfloat.exportToImage(); 00209 Image<PixRGB<float> > patch = crop(img,foa); 00210 printf("Sending patch to readers\n"); 00211 for(unsigned int i=0;i<readers.size();i++) 00212 readers[i]->sendPatch(patch_id,img,foa,patch,patchElapsedTime,isTraining,label,remoteCommand,rawmap_peak); 00213 //printf("Reading patches\n"); 00214 00215 00216 //std::vector<Nv2LabelReader::LabeledImage> result; 00217 00218 for(unsigned int i=0;i<readers.size();i++) 00219 { 00220 Nv2LabelReader::LabeledImage li = readers[i]->getNextLabeledImage(ignoreNonMatch,textLength,FrameNumber); 00221 if (li.label != std::string("")) 00222 { 00223 printf("*************** GOT LABEL [%s] *****************\n",li.label.c_str()); 00224 if(li.img.initialized()) 00225 { 00226 ofs->writeRGB(li.img, li.ident, FrameInfo("object-labeled image", SRC_POS)); 00227 } 00228 } 00229 } 00230 } 00231 cudaEventRecord(stop,0); 00232 cudaEventSynchronize(stop); 00233 00234 00235 cudaEventDestroy(start); 00236 cudaEventDestroy(stop); 00237 } 00238 00239 00240 // ###################################################################### 00241 void neovision2cuda::runDisplay(int w_originput, int h_originput, MemoryPolicy mp, int dev) 00242 { 00243 00244 n_cm = 5; 00245 n_sm = 2; 00246 aspect_ratio = w_originput/double(h_originput); 00247 if(w_originput > MAX_INPUT_WIDTH || h_originput > MAX_INPUT_HEIGHT) 00248 { 00249 if(aspect_ratio > MAX_INPUT_WIDTH/double(MAX_INPUT_HEIGHT)) 00250 { 00251 // Width is violating max principle 00252 w_in = MAX_INPUT_WIDTH; 00253 h_in = w_in/aspect_ratio; 00254 } 00255 else 00256 { 00257 // Height is violating max principle 00258 h_in = MAX_INPUT_HEIGHT; 00259 w_in = h_in*aspect_ratio; 00260 } 00261 } 00262 else 00263 { 00264 // Input dimensions are OK 00265 w_in = w_originput; 00266 h_in = h_originput; 00267 } 00268 00269 int w = 1.25 * w_originput; 00270 w_cm = w/double(n_cm); 00271 h_cm = w_cm/aspect_ratio; 00272 int h = h_originput + h_cm; 00273 w_sm = 0.2 * w; 00274 h_sm = w_sm/aspect_ratio; 00275 00276 // Setup preferences 00277 pwin = new PrefsWindow("control panel", SimpleFont::FIXED(8)); 00278 pwin->setValueNumChars(16); 00279 pwin->addPrefsForComponent(csm.get()); 00280 00281 //Setting up frame starting points (top left coordinates) 00282 //Large Maps 00283 rawFramePoint = Point2D<int>(0,0); 00284 saliencyFramePoint = Point2D<int>( w_in,0); 00285 inhibitionMapFramePoint = Point2D<int>(w_in,h_sm); 00286 //Small maps 00287 int mrg_sm = 0; // Margin between small maps 00288 imapFramePoint = Point2D<int>(int(w_cm+mrg_sm)*0,h_in); 00289 cmapFramePoint = Point2D<int>(int(w_cm+mrg_sm)*1,h_in); 00290 omapFramePoint = Point2D<int>(int(w_cm+mrg_sm)*2,h_in); 00291 fmapFramePoint = Point2D<int>(int(w_cm+mrg_sm)*3,h_in); 00292 mmapFramePoint = Point2D<int>(int(w_cm+mrg_sm)*4,h_in); 00293 //Associating coordinates with numeric frame symbols like 1,2,3... 00294 framework.setPoint(1,rawFramePoint); 00295 framework.setPoint(2,saliencyFramePoint); 00296 framework.setPoint(3,imapFramePoint); 00297 framework.setPoint(4,cmapFramePoint); 00298 framework.setPoint(5,omapFramePoint); 00299 framework.setPoint(6,fmapFramePoint); 00300 framework.setPoint(7,mmapFramePoint); 00301 framework.setPoint(8,inhibitionMapFramePoint); 00302 00303 //Initialise text layer of size 250 X 20 00304 framework.initTextLayer(w_in,20); 00305 00306 //Start framework 00307 framework.startFramework(w,h,dev,mp); 00308 createDisplay(w,h); 00309 00310 // Register this class' idle function 00311 glutIdleFunc(neovision2cuda::idleWrapper); 00312 glutMainLoop(); 00313 00314 cuda_invt_allocation_show_stats(1, "final",0); 00315 00316 //cutilExit(argc, argv); 00317 00318 } 00319 00320 // ###################################################################### 00321 int main(int argc, char **argv) 00322 { 00323 MYLOGVERB = LOG_INFO; 00324 // instantiate a model manager (for camera input): 00325 ModelManager *mgr = new ModelManager("CudaSaliency Tester"); 00326 // NOTE: make sure you register your OutputFrameSeries with the 00327 // manager before you do your InputFrameSeries, to ensure that 00328 // outputs for the current frame get saved before the next input 00329 // frame is loaded. 00330 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(*mgr)); 00331 nub::ref<InputFrameSeries> ifs(new InputFrameSeries(*mgr)); 00332 nub::ref<CudaSaliency> csm(new CudaSaliency(*mgr)); 00333 00334 const PixRGB<byte> colors[4] = 00335 { 00336 PixRGB<byte>(128,255,0), 00337 PixRGB<byte>(0,255,128), 00338 PixRGB<byte>(0,0,255), 00339 PixRGB<byte>(255,0,255) 00340 }; 00341 00342 // Change destination of ofs 00343 00344 //reader = new Nv2LabelReader(col,localPort,serverStr); 00345 mgr->addSubComponent(ofs); 00346 mgr->addSubComponent(ifs); 00347 mgr->addSubComponent(csm); 00348 00349 mgr->exportOptions(MC_RECURSE); 00350 // Parse command-line: 00351 if (mgr->parseCommandLine(argc, argv, "<Cuda Dev> <ip:port,ip:port,...>", 2, 2) == false) return -1; 00352 std::string devStr = mgr->getExtraArg(0); 00353 int dev = strtol(devStr.c_str(),NULL,0); 00354 std::string addrlist = mgr->getExtraArg(1); 00355 MemoryPolicy mp = GLOBAL_DEVICE_MEMORY; 00356 printf("Using CUDA Device %d\n",dev); 00357 // Set device before model manager start 00358 csm->setDevice(mp,dev); 00359 00360 // if (addrlist.empty()) 00361 // { 00362 // int localPort = 9931; 00363 // std::string serverStr = std::string("127.0.0.1:9930"); 00364 // } 00365 00366 std::vector<rutz::shared_ptr<Nv2LabelReader> > readers; 00367 std::vector<std::string> addrs; 00368 split(addrlist, ",", std::back_inserter(addrs)); 00369 00370 for (size_t i = 0; i < addrs.size(); ++i) 00371 { 00372 std::vector<std::string> serverAddress; 00373 split(addrs[i],":",std::back_inserter(serverAddress)); 00374 ASSERT(serverAddress.size() == 2); 00375 int localPort = strtol(serverAddress[1].c_str(),NULL,0)+1; 00376 readers.push_back 00377 (rutz::make_shared 00378 (new Nv2LabelReader(colors[i%4], 00379 localPort, 00380 addrs[i]))); 00381 } 00382 00383 00384 00385 mgr->start(); 00386 ifs->startStream(); 00387 Dims inDims = ifs->peekDims(); 00388 00389 // Check if it is hd or not . 00390 // If hd then fit everything in max window size else resize the window size accordigly. 00391 // Preserving the aspect ration and layout percentages to rescale. 00392 // int w = 2406; //Default 00393 // int h = 1376; //Default 00394 00395 00396 /* 00397 } 00398 00399 } 00400 */ 00401 neovision2cuda *n = neovision2cuda::createCudaDisplay(ifs,ofs,csm,readers); 00402 n->runDisplay(inDims.w(),inDims.h(),mp,dev); 00403 //delete reader; 00404 return 0; 00405 }