00001 /*!@file AppDevices/test-grab.C Test frame grabbing and X display */ 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: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppDevices/test-grab.C $ 00035 // $Id: test-grab.C 14290 2010-12-01 21:44:03Z itti $ 00036 // 00037 00038 #include "Util/log.H" 00039 00040 #if !defined(INVT_HAVE_OPENNI) || !defined(INVT_HAVE_NITE) 00041 00042 int main(const int argc, const char **argv) 00043 { LFATAL("Need OpenNI and Nite installed. Check configure output."); return 1; } 00044 00045 #else 00046 00047 #include "Component/ModelManager.H" 00048 #include "Devices/FrameGrabberFactory.H" 00049 #include "Devices/OpenNIGrabber.H" 00050 #include "GUI/XWindow.H" 00051 #include "Image/Image.H" 00052 #include "Image/Pixels.H" 00053 #include "Raster/Raster.H" 00054 #include "Raster/GenericFrame.H" 00055 #include "Transport/FrameIstream.H" 00056 #include "Util/Timer.H" 00057 #include "Util/Types.H" 00058 00059 00060 #include <cstdio> 00061 #include <cstdlib> 00062 #include <cstring> 00063 #include <XnOS.h> 00064 #include <XnCppWrapper.h> 00065 00066 // Header for NITE 00067 #include <XnVNite.h> 00068 00069 #define NAVG 20 00070 // Callback for when the focus is in progress 00071 void XN_CALLBACK_TYPE SessionProgress(const XnChar* strFocus, const XnPoint3D& ptFocusPoint, XnFloat fProgress, void* UserCxt) 00072 { 00073 LINFO("Session in Progress!"); 00074 } 00075 // callback for session start 00076 void XN_CALLBACK_TYPE SessionStart(const XnPoint3D& ptFocusPoint, void* UserCxt) 00077 { 00078 LINFO("Session started!"); 00079 } 00080 // Callback for session end 00081 void XN_CALLBACK_TYPE SessionEnd(void* UserCxt) 00082 { 00083 printf("Session ended!"); 00084 } 00085 // Callback for wave detection 00086 void XN_CALLBACK_TYPE OnWaveCB(void* cxt) 00087 { 00088 printf("Wave!\n"); 00089 } 00090 00091 //Callback for swipe left 00092 void XN_CALLBACK_TYPE SwipeLeft(XnFloat fVelocity, XnFloat fAngle, void* cxt) 00093 { 00094 printf("Swipe Left!\n"); 00095 } 00096 00097 //Callback for swipe right 00098 void XN_CALLBACK_TYPE SwipeRight(XnFloat fVelocity, XnFloat fAngle, void* cxt) 00099 { 00100 printf("Swipe Right!\n"); 00101 } 00102 00103 //Callback for swipe up 00104 void XN_CALLBACK_TYPE SwipeUp(XnFloat fVelocity, XnFloat fAngle, void* cxt) 00105 { 00106 printf("Swipe Up!\n"); 00107 } 00108 00109 //Callback for swipe down 00110 void XN_CALLBACK_TYPE SwipeDown(XnFloat fVelocity, XnFloat fAngle, void* cxt) 00111 { 00112 printf("Swipe Down!\n"); 00113 } 00114 00115 //Callback for steady 00116 void XN_CALLBACK_TYPE Steady(XnFloat fVelocity, void* cxt) 00117 { 00118 printf("Steady!\n"); 00119 } 00120 00121 //Callback for push 00122 void XN_CALLBACK_TYPE Push(XnFloat fVelocity, XnFloat fAngle, void* cxt) 00123 { 00124 printf("Push!\n"); 00125 } 00126 00127 int main(const int argc, const char **argv) 00128 { 00129 // instantiate a model manager: 00130 ModelManager manager("Gesture Tester"); 00131 manager.exportOptions(MC_RECURSE); 00132 00133 nub::soft_ref<OpenNIGrabber> gb = nub::soft_ref<OpenNIGrabber>(new OpenNIGrabber(manager)); 00134 manager.addSubComponent(gb); 00135 gb->exportOptions(MC_RECURSE); 00136 // let's get all our ModelComponent instances started: 00137 00138 manager.start(); 00139 00140 //NITE/Gesture 00141 xn::Context *gbNI; 00142 gbNI = gb->getContext(); 00143 00144 XnVSessionManager *sessionManager = new XnVSessionManager(); 00145 //the current session manager will look at the entire image for a start point. 00146 //there are some mechanisms that can help narrow the focus for 00147 XnStatus rc = ((XnVSessionManager*)sessionManager)->Initialize(gbNI, "Click,Wave", "RaiseHand"); 00148 if (rc != XN_STATUS_OK) 00149 { 00150 LFATAL("Session Manager couldn't initialize: %s\n", xnGetStatusString(rc)); 00151 delete sessionManager; 00152 } 00153 gbNI->StartGeneratingAll(); 00154 sessionManager->RegisterSession(NULL, &SessionStart, &SessionEnd, &SessionProgress); 00155 00156 00157 00158 // init & register wave control 00159 XnVWaveDetector wc; 00160 wc.RegisterWave(NULL, OnWaveCB); 00161 sessionManager->AddListener(&wc); 00162 00163 //init and register swipe control 00164 XnVSwipeDetector sw(false); 00165 sw.RegisterSwipeUp(NULL, SwipeUp); 00166 sw.RegisterSwipeDown(NULL, SwipeDown); 00167 sw.RegisterSwipeLeft(NULL, SwipeLeft); 00168 sw.RegisterSwipeRight(NULL, SwipeRight); 00169 sessionManager->AddListener(&sw); 00170 00171 //init and register steady control 00172 XnVSteadyDetector st; 00173 st.RegisterSteady(NULL, Steady); 00174 sessionManager->AddListener(&st); 00175 00176 //init and register push control 00177 XnVPushDetector pd; 00178 pd.RegisterPush(NULL, Push); 00179 sessionManager->AddListener(&pd); 00180 00181 // get ready for main loop: 00182 Timer tim; uint64 t[NAVG]; int frame = 0; 00183 GenericFrameSpec fspec = gb->peekFrameSpec(); 00184 Dims windims = fspec.dims; 00185 if (fspec.nativeType == GenericFrame::RGBD) windims = Dims(windims.w() * 2, windims.h()); 00186 XWindow win(windims, -1, -1, "test-grab window"); 00187 int count = 0; 00188 00189 // prepare a gamma table for RGBD displays (e.g., Kinect grabber): 00190 uint16 itsGamma[2048]; 00191 for (int i = 0; i < 2048; ++i) { 00192 float v = i/2048.0; 00193 v = powf(v, 3)* 6; 00194 itsGamma[i] = v*6*256; 00195 } 00196 00197 // get the frame grabber to start streaming: 00198 gb->startStream(); 00199 00200 while(1) { 00201 ++count; tim.reset(); 00202 00203 GenericFrame fr = gb->readFrame(); 00204 00205 ((XnVSessionManager*)sessionManager)->Update(gbNI); 00206 00207 Image< PixRGB<byte> > ima = fr.asRgbU8(); 00208 00209 if (fspec.nativeType == GenericFrame::RGBD) { 00210 Image<uint16> dimg = fr.asGrayU16(); // get the depth image 00211 00212 Image<PixRGB<byte> > d(dimg.getDims(), NO_INIT); 00213 const int sz = dimg.size(); 00214 for (int i = 0; i < sz; ++i) { 00215 uint v = dimg.getVal(i); if (v > 2047) v = 2047; 00216 int pval = itsGamma[v]; 00217 int lb = pval & 0xff; 00218 switch (pval>>8) { 00219 case 0: d.setVal(i, PixRGB<byte>(255, 255-lb, 255-lb)); break; 00220 case 1: d.setVal(i, PixRGB<byte>(255, lb, 0)); break; 00221 case 2: d.setVal(i, PixRGB<byte>(255-lb, 255, 0)); break; 00222 case 3: d.setVal(i, PixRGB<byte>(0, 255, lb)); break; 00223 case 4: d.setVal(i, PixRGB<byte>(0, 255-lb, 255)); break; 00224 case 5: d.setVal(i, PixRGB<byte>(0, 0, 255-lb)); break; 00225 default: d.setVal(i, PixRGB<byte>(0, 0, 0)); break; 00226 } 00227 } 00228 ima = concatX(ima, d); 00229 } 00230 00231 uint64 t0 = tim.get(); // to measure display time 00232 00233 win.drawImage(ima); 00234 00235 t[frame % NAVG] = tim.get(); 00236 t0 = t[frame % NAVG] - t0; 00237 if (t0 > 20000ULL) LINFO("Display took %lluus", t0); 00238 00239 00240 // compute and show framerate over the last NAVG frames: 00241 if (frame % NAVG == 0 && frame > 0) 00242 { 00243 uint64 avg = 0ULL; for (int i = 0; i < NAVG; i ++) avg += t[i]; 00244 float avg2 = 1000.0F / float(avg) * float(NAVG); 00245 printf("Framerate: %.1f fps\n", avg2); 00246 } 00247 frame ++; 00248 } 00249 00250 // stop all our ModelComponents 00251 manager.stop(); 00252 00253 // all done! 00254 return 0; 00255 } 00256 00257 #endif 00258 00259 // ###################################################################### 00260 /* So things look consistent in everyone's emacs... */ 00261 /* Local Variables: */ 00262 /* indent-tabs-mode: nil */ 00263 /* End: */