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_COLORHIST_C_DEFINED
00039 #define APPMEDIA_APP_MOUSE_CHASER_COLORHIST_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 "Transport/FrameInfo.H"
00061 #include <cstdio>
00062 #include <numeric>
00063 #include <iostream>
00064 #include <fstream>
00065
00066 Point2D<int> getMeanMotion(const Image<float>& itsImg,float thresh);
00067 Point2D<int> featTrack(Image<PixRGB<byte> >& crnt, Point2D<int> prevTrackPt,
00068 PixRGB<float> itsMeanRGB, Dims rectDims);
00069 float euclidDist(PixRGB<float> a, PixRGB<float> b);
00070
00071 int prevDir = 0;
00072 int main(int argc,const char**argv)
00073 {
00074
00075
00076 ModelManager *mgr = new ModelManager("Animal Tracker");
00077 nub::ref<InputFrameSeries> ifs(new InputFrameSeries(*mgr));
00078 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(*mgr));
00079
00080 mgr->addSubComponent(ifs);
00081 mgr->addSubComponent(ofs);
00082
00083 mgr->setOptionValString(&OPT_FrameGrabberFPS, "30");
00084 mgr->exportOptions(MC_RECURSE);
00085
00086
00087 if (mgr->parseCommandLine(argc, argv, "", 0, 0) == false) return(1);
00088
00089
00090 Dims imageDims = ifs->peekDims();
00091 LINFO("w=%d,h=%d",imageDims.w(),imageDims.h());
00092
00093 Dims layer_screen(800,800);
00094 XWindow layers(layer_screen, 0, 0, "layers");
00095
00096
00097 mgr->start();
00098
00099 const FrameState is = ifs->updateNext();
00100 if(is == FRAME_COMPLETE)
00101 LFATAL("frames completed!");
00102
00103 Image <PixRGB<byte> > crnt,prev;
00104 Image <PixRGB<byte> > dispImg;
00105 std::vector<Image<PixRGB<byte> > > frames;
00106
00107 prev = ifs->readRGB();
00108 frames.push_back(prev);
00109
00110 if(!prev.initialized())
00111 LFATAL("frame killed");
00112
00113 bool happy=false,happyBlob=false;
00114 int crit = imageDims.w()/2;
00115 int x,y;
00116 Dims rectDims(imageDims.w()/8,imageDims.h()/8);
00117
00118 dispImg = prev;
00119 drawLine(dispImg,Point2D<int>(crit,0),
00120 Point2D<int>(crit,imageDims.h()),PixRGB<byte>(255,0,0),2);
00121 drawGrid(dispImg,10,10,1,PixRGB<byte> (255,0,0));
00122 layers.drawImage(dispImg,0,0);
00123 std::string saveName;
00124 saveName = mgr->getOptionValString(&OPT_InputFrameSource);
00125 saveName = saveName + ".dat";
00126 std::ofstream outFile(saveName.c_str());
00127
00128 while(!happy && !happyBlob)
00129 {
00130 Image<PixRGB<byte> > testImg = prev;
00131
00132 int choice, choiceX, choiceY;
00133 LINFO("Input a threshold image center is at %d: ",imageDims.w()/2);
00134 std::cin >> choice;
00135 if(choice == -1)
00136 happy =true;
00137 else
00138 {
00139 drawLine(testImg,Point2D<int>(choice,0),
00140 Point2D<int>(choice,imageDims.h()),PixRGB<byte>(255,0,0),2);
00141 drawGrid(testImg,10,10,0.5,PixRGB<byte> (255,0,0));
00142 layers.drawImage(testImg,0,0);
00143 crit = choice;
00144 }
00145
00146 LINFO("Input an x pos: ");
00147 std::cin >> choiceX;
00148 LINFO("Input an y pos: ");
00149 std::cin >> choiceY;
00150
00151 if(choiceX == -1)
00152 happyBlob =true;
00153 else
00154 {
00155 Rectangle r1(Point2D<int>(choiceX,choiceY),rectDims);
00156 drawRect(testImg,r1,PixRGB<byte>(0,255,0),1);
00157 layers.drawImage(testImg,0,0);
00158 x = choiceX;
00159 y = choiceY;
00160 }
00161 }
00162
00163
00164 LINFO("processing...");
00165
00166 Timer T,frameTim;
00167 T.reset();
00168 int fTotal=1;
00169
00170 frameTim.reset();
00171
00172 std::vector<int> trackX;
00173 std::vector<int> trackY;
00174
00175 trackX.push_back(x);
00176 trackY.push_back(y);
00177
00178 Point2D<int> prevTrackPt, crntTrackPt;
00179 prevTrackPt = Point2D<int>(x,y);
00180
00181 Image<PixRGB<float> > target= crop(prev,prevTrackPt,rectDims,false);
00182 PixRGB<float> itsMeanRGB = meanRGB(target);
00183 int leftCnt=0,rightCnt=0;
00184
00185 Image<PixRGB<byte> > meanBkg =prev;
00186
00187 while(is != FRAME_COMPLETE)
00188 {
00189 const FrameState is = ifs->updateNext();
00190 if(is == FRAME_COMPLETE)
00191 break;
00192
00193
00194 crnt = ifs->readRGB();
00195
00196 if(!crnt.initialized())
00197 break;
00198
00199 crntTrackPt = featTrack(crnt, prevTrackPt, itsMeanRGB,rectDims);
00200 prevTrackPt = crntTrackPt;
00201
00202 Rectangle r1(crntTrackPt,rectDims);
00203 drawRect(crnt,r1,PixRGB<byte>(255,0,0),1);
00204 Point2D<int> cross = crntTrackPt;
00205 cross.i += rectDims.w()/2;
00206 cross.j += rectDims.h()/2;
00207
00208 outFile << cross.i << "\t" << cross.j << std::endl;
00209
00210 if (cross.i < crit)
00211 {
00212 leftCnt++;
00213 writeText(crnt, Point2D<int> (2,0),"LEFT",
00214 PixRGB<byte>(0,255,0),PixRGB<byte>(0,0,0),
00215 SimpleFont::FIXED(9));
00216 }
00217 else
00218 {
00219 rightCnt++;
00220 writeText(crnt, Point2D<int> (2,0),"RIGHT",
00221 PixRGB<byte>(0,255,0),PixRGB<byte>(0,0,0),
00222 SimpleFont::FIXED(9));
00223 }
00224
00225 drawCross(crnt, cross, PixRGB<byte>(255,255,0), 3, 2);
00226 drawLine(crnt, Point2D<int>(crit,0), Point2D<int>(crit,imageDims.h()),
00227 PixRGB<byte>(255,0,0),2);
00228
00229
00230 ofs->writeRgbLayout(crnt,"MouseChaser", FrameInfo("output",SRC_POS));
00231 fTotal++;
00232 }
00233
00234 LINFO("Total movie time %f: \ntime to compute motion: %f",frameTim.getSecs(), T.getSecs());
00235 T.reset();
00236
00237 LINFO("Result cnts: LEFT = %d, RIGHT= %d ",leftCnt, rightCnt);
00238 float total = (float) (leftCnt + rightCnt);
00239
00240 float leftP = (float)leftCnt/total;
00241 float rightP = (float)rightCnt/total;
00242
00243 LINFO("Results: LEFT = %.2f %%, RIGHT= %.2f %% total=%f", leftP*100.0F, rightP*100.0F,total);
00244
00245
00246
00247
00248
00249
00250
00251
00252 mgr->stop();
00253 return 0;
00254 }
00255
00256
00257
00258
00259
00260 Point2D<int> featTrack(Image<PixRGB<byte> > &crnt, Point2D<int> prevTrackPt,
00261 PixRGB<float> itsMeanRGB, Dims rectDims)
00262 {
00263 int x = prevTrackPt.i;
00264 int y = prevTrackPt.j;
00265
00266 std::vector<Image<PixRGB<byte> > > regions;
00267 std::vector<float> colorDists;
00268 std::vector<Point2D<int> > thePoints;
00269
00270
00271 int pd =40;
00272
00273 for (int i = x-pd;i <= x+pd; i+=5)
00274 for (int j = y-pd; j<=y+pd; j+=5)
00275 if (crnt.coordsOk(i, j) &
00276 crnt.coordsOk(i + rectDims.w()-1, j + rectDims.h()-1))
00277 thePoints.push_back(Point2D<int>(i,j));
00278
00279 std::vector<Point2D<int> >::iterator pItr = thePoints.begin();
00280
00281 while(pItr != thePoints.end())
00282 regions.push_back(crop(crnt,*pItr++,rectDims,false));
00283
00284 for(std::vector<Image<PixRGB<byte> > >::iterator it = regions.begin();
00285 it!=regions.end(); ++it)
00286 {
00287 int dist = euclidDist(itsMeanRGB,meanRGB(*it));
00288 Image<PixRGB<float> > temp = *it;
00289 dist = dist + euclidDist(temp.getVal(Point2D<int>(rectDims.w()/2,
00290 rectDims.h()/2)),
00291 itsMeanRGB);
00292 colorDists.push_back(dist);
00293 }
00294
00295
00296
00297
00298 int min = *(std::min_element(colorDists.begin(),colorDists.end()));
00299 if (min > 120)
00300 return prevTrackPt;
00301 else
00302 {
00303 prevDir = std::min_element(colorDists.begin(),colorDists.end())-
00304 colorDists.begin();
00305 return thePoints[std::min_element(colorDists.begin(),colorDists.end())-
00306 colorDists.begin()];
00307 }
00308 }
00309
00310
00311
00312
00313
00314 float euclidDist(PixRGB<float> a, PixRGB<float> b)
00315 {
00316 float rDiff, gDiff, bDiff;
00317 rDiff= abs(a.red()-b.red());
00318 gDiff= abs(a.green()-b.green());
00319 bDiff= abs(a.blue()-b.blue());
00320
00321 return sqrt(rDiff*rDiff + gDiff*gDiff + bDiff*bDiff);
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 #endif // APPMEDIA_APP_MOUSE_CHASER_COLORHIST_C_DEFINED