00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef APPMEDIA_APP_MOUSE_CHASER_C_DEFINED
00039 #define APPMEDIA_APP_MOUSE_CHASER_C_DEFINED
00040
00041 #include "Component/ModelManager.H"
00042 #include "Devices/FrameGrabberConfigurator.H"
00043 #include "Devices/DeviceOpts.H"
00044 #include "GUI/XWindow.H"
00045 #include "Image/Image.H"
00046 #include "Image/MathOps.H"
00047 #include "Image/ShapeOps.H"
00048 #include "Image/ColorOps.H"
00049 #include "Image/DrawOps.H"
00050 #include "Image/Range.H"
00051 #include "Raster/Raster.H"
00052 #include "Transport/FrameIstream.H"
00053 #include "Util/Timer.H"
00054 #include "Util/Types.H"
00055 #include "Util/log.H"
00056
00057 #include "Media/FrameSeries.H"
00058 #include "Media/MediaOpts.H"
00059 #include "Raster/GenericFrame.H"
00060 #include <cstdio>
00061 #include <numeric>
00062 #include <iostream>
00063
00064 Point2D<int> getMeanMotion(const Image<float>& itsImg,float thresh);
00065
00066
00067 int main(int argc,const char**argv)
00068 {
00069
00070
00071 ModelManager *mgr = new ModelManager("locust model frame series style");
00072
00073 nub::ref<InputFrameSeries> ifs(new InputFrameSeries(*mgr));
00074 mgr->addSubComponent(ifs);
00075 mgr->setOptionValString(&OPT_FrameGrabberFPS, "30");
00076 mgr->exportOptions(MC_RECURSE);
00077
00078
00079 if (mgr->parseCommandLine(argc, argv, "<threshold>", 1, 1) == false) return(1);
00080
00081 int itsMoThresh = mgr->getExtraArgAs<int>(0);
00082
00083
00084 Dims imageDims = ifs->peekDims();
00085 LINFO("w=%d,h=%d",imageDims.w(),imageDims.h());
00086
00087 Dims layer_screen(800,800);
00088 XWindow layers(layer_screen, 0, 0, "layers");
00089
00090
00091 mgr->start();
00092
00093 const FrameState is = ifs->updateNext();
00094 if(is == FRAME_COMPLETE)
00095 LFATAL("frames completed!");
00096
00097 Image <PixRGB<byte> > prev,crnt;
00098
00099 std::vector<Image<PixRGB<byte> > > frames;
00100 std::vector<Image<float> > motion;
00101
00102 prev = ifs->readRGB();
00103 frames.push_back(prev);
00104
00105 if(!prev.initialized())
00106 LFATAL("frame killed");
00107
00108
00109 bool happy=false,happyBlob=false;
00110 int crit = imageDims.w()/2;
00111 while(!happy && !happyBlob)
00112 {
00113 Image<PixRGB<byte> > testImg = prev;
00114 int choice,x,y;
00115
00116 LINFO("Input a threshold image center is at %d: ",imageDims.w()/2);
00117 std::cin >> choice;
00118 if(choice == 0)
00119 happy =true;
00120 else
00121 {
00122
00123 drawLine(testImg,Point2D<int>(crit,0),
00124 Point2D<int>(crit,imageDims.h()),PixRGB<byte>(255,0,0),2);
00125 layers.drawImage(rescale(testImg,320,240),0,0);
00126 crit = choice;
00127
00128 }
00129
00130 LINFO("Input an x pos: ");
00131 std::cin >> x;
00132 LINFO("Input an y pos: ");
00133 std::cin >> y;
00134
00135 if(x == -1)
00136 happyBlob =true;
00137 else
00138 {
00139 Rectangle r1(Point2D<int>(x,y),Dims(30,30));
00140 drawRect(testImg,r1,PixRGB<byte>(255,0,0),1);
00141 layers.drawImage(rescale(testImg,320,240),0,0);
00142 crit = choice;
00143 }
00144
00145 }
00146
00147
00148 LINFO("processing...");
00149
00150 Timer T,frameTim;
00151 T.reset();
00152 int fTotal=0;
00153
00154 frameTim.reset();
00155 while(is != FRAME_COMPLETE)
00156 {
00157 const FrameState is = ifs->updateNext();
00158 if(is == FRAME_COMPLETE)
00159 break;
00160
00161
00162 crnt = ifs->readRGB();
00163 if(!crnt.initialized())
00164 break;
00165 frames.push_back(crnt);
00166 motion.push_back(absDiff(luminance(crnt),luminance(prev)));
00167 prev= crnt;
00168 fTotal++;
00169 }
00170
00171 LINFO("Total movie time %f: \ntime to compute motion: %f",frameTim.getSecs(),
00172 T.getSecs());
00173 T.reset();
00174
00175
00176 std::vector<Point2D<int> > posVec;
00177 std::vector<int> posX;
00178 std::vector<Image<float> >::iterator itM = motion.begin();
00179 Point2D<int> prevMean = getMeanMotion(*itM,itsMoThresh);
00180 int fLeft=0;
00181 posVec.push_back(prevMean);
00182
00183 for(std::vector<Image<PixRGB<byte> > >::iterator it = frames.begin();
00184 it!=frames.end()-1;++it)
00185 {
00186 Image<PixRGB<byte> > vid= *it;
00187 Point2D<int> meanMotion = getMeanMotion(*itM,80);
00188 if(meanMotion.i == 0 && meanMotion.j == 0)
00189 meanMotion = prevMean;
00190 else
00191 prevMean = meanMotion;
00192
00193 posVec.push_back(meanMotion);
00194 posX.push_back(meanMotion.i);
00195 if (meanMotion.i < crit)
00196 fLeft++;
00197
00198
00199 Image<PixRGB<byte> > mot= *itM;
00200 ++itM;
00201 }
00202
00203 LINFO("time to compute motion position: %f",T.getSecs());
00204 LINFO("num frames on left %d, num frames on right %d",fLeft,fTotal-fLeft);
00205 LINFO("time on left %f, time on right %f",fLeft/25.0,(fTotal-fLeft)/25.0);
00206
00207
00208 Image<PixRGB<byte> > itsPlot = linePlot(posX, 400,500,0,0,
00209 "xPosition","position","time/s",
00210 PixRGB<byte>(0,0,0),
00211 PixRGB<byte>(255,255,255),5,0);
00212
00213 itM = motion.begin();
00214 std::vector<Point2D<int> >::iterator posItr = posVec.begin();
00215 Point2D<int> meanMotion;
00216 layers.drawImage(itsPlot,0,240+10);
00217 for(std::vector<Image<PixRGB<byte> > >::iterator it = frames.begin();
00218 it!=frames.end()-1;++it)
00219 {
00220
00221 Image<PixRGB<byte> > vid= *it;
00222 Image<PixRGB<byte> > mot= *itM++;
00223 mot= mot*5;
00224 meanMotion = *posItr++;
00225 drawCross(mot,meanMotion,PixRGB<byte>(255,255,0),3,2);
00226 drawLine(mot,Point2D<int>(crit,0),Point2D<int>(crit,imageDims.h()),
00227 PixRGB<byte>(255,0,0),2);
00228 layers.drawImage(rescale(mot,320,240),0,0);
00229
00230
00231
00232
00233 }
00234
00235 mgr->stop();
00236 return 0;
00237 }
00238
00239
00240
00241
00242
00243 std::vector<Point2D<int> > getMotionVector(const Image<float>& itsImg,
00244 float thresh)
00245 {
00246
00247 std::vector<Point2D<int> > motionVec;
00248 int cnt=0;
00249
00250 for(Image<float>::const_iterator itr=itsImg.begin();itr!=itsImg.end();++itr)
00251 {
00252 if(*itr >= thresh)
00253 motionVec.push_back(Point2D<int>(cnt % itsImg.getWidth(),
00254 (cnt-(cnt % itsImg.getWidth()))/itsImg.getWidth()));
00255 cnt++;
00256
00257 }
00258 return motionVec;
00259
00260
00261 }
00262
00263
00264 Point2D<int> getMeanMotion(const Image<float>& itsImg,float thresh)
00265
00266 {
00267
00268 std::vector<Point2D<int> > motionVec = getMotionVector(itsImg,thresh);
00269
00270 if(motionVec.size() == 0)
00271 return Point2D<int>(0,0);
00272 else
00273 {
00274
00275 std::vector<int> x,y;
00276 std::vector<Point2D<int> >::const_iterator itr=motionVec.begin();
00277
00278 while(itr!=motionVec.end())
00279 {
00280 Point2D<int> temp = *itr;
00281 x.push_back(temp.i);
00282 y.push_back(temp.j);
00283 ++itr;
00284 }
00285
00286 int meanX= std::accumulate(x.begin(),x.end(),0.0)/x.size();
00287 int meanY = std::accumulate(y.begin(),y.end(),0.0)/y.size();
00288
00289 return Point2D<int>(meanX,meanY);
00290 }
00291
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 #endif // APPMEDIA_APP_MOUSE_CHASER_C_DEFINED