Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

OpticalFlow.cc

Go to the documentation of this file.
00001 #include "OpticalFlow.h"
00002 #include "DualCoding/DualCoding.h"
00003 
00004 using namespace DualCoding;
00005 
00006 OpticalFlow::OpticalFlow() : integratedFlow(0.0f), flowVectors(NUM_FLOW_VECTORS),
00007            flowVectorVisuals(NUM_FLOW_VECTORS), pastTranslations(NUM_FRAMES),
00008            pyramid1(), pyramid2(), currPyramid(&pyramid1), prevPyramid(NULL) {}
00009 
00010 bool OpticalFlow::myFlowComp(const FlowVector &v1, const FlowVector &v2) {
00011   return (v1.flow(0,0) < v2.flow(0,0));
00012 }
00013 
00014 bool OpticalFlow::myFlowComp2(const FlowVector &v1, const FlowVector &v2) {
00015   return (v1.relevanceScore < v2.relevanceScore);
00016 }
00017 
00018 
00019 void OpticalFlow::computeRelevanceScores() {
00020   for(unsigned int i = 0; i < NUM_FLOW_VECTORS; i++) {
00021     float score = 0;
00022     for(unsigned int j = 0; j < NUM_FRAMES; j++) {
00023       score += (1.0f/((float)(j+1))) * fabs(flowVectors[i].flow(0,0) - pastTranslations[j]);
00024     }
00025     flowVectors[i].relevanceScore = score;
00026   }
00027 }
00028 
00029 void OpticalFlow::updateFlow() {
00030   currPyramid->loadFromRawY();
00031   if(prevPyramid == NULL) {
00032     swapPyramids();
00033     return;
00034   }
00035   
00036   initializePositions();
00037   for(unsigned int L = RawImagePyramid::NUM_PYRAMID_LAYERS; L > 0; L--) {
00038     for(unsigned int i = 0; i < NUM_FLOW_VECTORS; i++) {
00039       fmat::Column<2> flow = iterativeLucasKanade(flowVectors[i].position/pow(2,L-1),
00040               flowVectors[i].flow,
00041               (*prevPyramid)[L-1],
00042               (*currPyramid)[L-1],
00043               FLOW_WINDOW);
00044       if(L != 0)
00045   flowVectors[i].flow = 2 * (flowVectors[i].flow + flow);
00046       else
00047   flowVectors[i].flow = (flowVectors[i].flow + flow);
00048     }
00049   }
00050 
00051   computeRelevanceScores();
00052   sort(flowVectors.begin(), flowVectors.end(), myFlowComp2);
00053   sort(flowVectors.begin(), flowVectors.begin()+(2*NUM_FLOW_VECTORS/3), myFlowComp);
00054 
00055   float trans = flowVectors[2*NUM_FLOW_VECTORS/6].flow(0,0);
00056   integratedFlow += trans;
00057   
00058   for(int i = NUM_FRAMES-1; i>=1; i--)
00059     pastTranslations[i] = pastTranslations[i-1];
00060   pastTranslations[0] = trans;
00061   // drawFlow();
00062   swapPyramids();
00063 }
00064 
00065 void OpticalFlow::swapPyramids() {
00066   if(currPyramid == &pyramid1) {
00067     currPyramid = &pyramid2;
00068     prevPyramid = &pyramid1;
00069   }
00070   else {
00071     currPyramid = &pyramid1;
00072     prevPyramid = &pyramid2;
00073   }
00074 }
00075 
00076 void OpticalFlow::drawFlow() {
00077   static Sketch<uchar> rawY(VRmixin::sketchFromRawY(), "rawY", true);
00078 
00079   rawY = VRmixin::sketchFromRawY();
00080   
00081   int i = 0;
00082   SHAPEVEC_ITERATE(flowVectorVisuals, LineData, line) {
00083     fmat::Column<2> startPt = 2*flowVectors[i].position;
00084     fmat::Column<2> endPt = 2*flowVectors[i].position + flowVectors[i].flow;
00085     EndPoint startPt2 = EndPoint(startPt(0,0), startPt(1,0));
00086     EndPoint endPt2 = EndPoint(endPt(0,0),endPt(1,0));
00087     if(!line.isValid()) {
00088       LineData line2(VRmixin::camShS,startPt2,endPt2);
00089       line = Shape<LineData>(line2);
00090     } else {
00091       line->setEndPts(startPt2, endPt2);
00092     }
00093     i++;
00094   }}
00095 }
00096 
00097 void OpticalFlow::initializePositions() {
00098   unsigned int j = 0;
00099   unsigned int const width = (*prevPyramid)[SCORE_LAYER].getWidth();
00100   unsigned int const height = (*prevPyramid)[SCORE_LAYER].getHeight();
00101   unsigned int const xinc = width/CANDIDATE_FEATURE_RESOLUTION;
00102   unsigned int const yinc = height/CANDIDATE_FEATURE_RESOLUTION;
00103   unsigned int const numFeatures = (width/xinc) * (height/yinc);
00104   std::vector<ScorePoint> eigens(numFeatures);
00105 
00106   for(unsigned int x = 0; x < width; x+=xinc) {
00107     for(unsigned int y = 0; y < height; y+=yinc) {
00108       if ( j >= numFeatures )
00109   std::cout << "*** j = " << j << std::endl;
00110       eigens[j].position(0,0) = x;
00111       eigens[j].position(1,0) = y;
00112       eigens[j].score = (*prevPyramid)[SCORE_LAYER].imageScore(x,y,SCORE_WINDOW);
00113       // std::cout << "  " << j << ":  x=" << x << "  y=" << y << "  score=" << eigens[j].score << std::endl;
00114       j++;
00115     }
00116   }
00117 
00118   sort(eigens.begin(), eigens.end(), scoreComp);
00119   if(eigens[0].score == 0) {
00120     cout << "VISUAL ODOMETRY FAILED" << endl;
00121     return;
00122   }
00123 
00124   for(unsigned int i = 0; i < NUM_FLOW_VECTORS; i++) {
00125     flowVectors[i].position = eigens[i].position;
00126     flowVectors[i].flow = fmat::pack(0,0);
00127     }
00128 }
00129 
00130 fmat::Column<2>
00131 OpticalFlow::iterativeLucasKanade(fmat::Column<2> center, fmat::Column<2> trans,
00132           RawImage& img1, RawImage& img2, int window) {
00133   fmat::Matrix<2,2> G = img1.spatialGradientMatrix(center(0,0),center(1,0),window);
00134   if(fmat::det(G) == 0)
00135     return fmat::pack(0,0);
00136   fmat::Matrix<2,2> Ginv = fmat::invert(G);
00137 
00138   const unsigned int MAX_ITERATIONS = 5;
00139   const float ACCURACY_THRESHOLD = 0.1f;
00140   fmat::Column<2> opticalFlow;
00141   for(unsigned int i = 0; i < MAX_ITERATIONS; i++) {
00142     fmat::Column<2> b;
00143     for(float x = center(0,0) - window; x <= center(0,0)+window; x++) {
00144       for(float y = center(1,0) - window; y <= center(1,0)+window; y++) {
00145   float delta = img1(x,y) - img2(x + trans(0,0) + opticalFlow(0,0),
00146                y + trans(1,0) + opticalFlow(1,0));
00147   fmat::Column<2> grad = img1.gradient(x,y);
00148 
00149   b += grad * delta;
00150       }
00151     }
00152     
00153     fmat::Column<2> gamma = Ginv * b;
00154     opticalFlow += gamma;
00155 
00156     //    if(((gamma(0,0) * gamma(0,0)) + (gamma(1,0)*gamma(1,0))) < ACCURACY_THRESHOLD)
00157     //      break;
00158     if( (gamma(0,0) * gamma(0,0)) + (gamma(1,0) * gamma(1,0)) < ACCURACY_THRESHOLD )
00159       break;
00160   }
00161 
00162   return opticalFlow;
00163 }
00164 
00165 /*   Josh's original version
00166 fmat::Column<2>
00167 OpticalFlow::iterativeLucasKanade(fmat::Column<2> center, fmat::Column<2> trans,
00168           RawImage& img1, RawImage& img2, int window) {
00169   const unsigned int MAX_ITERATIONS = 5;
00170   const float ACCURACY_THRESHOLD = 0.1f;
00171   fmat::Column<2> opticalFlow;
00172   for(unsigned int i = 0; i < MAX_ITERATIONS; i++) {
00173     fmat::Column<2> b;
00174     fmat::Matrix<2,2> G = img1.spatialGradientMatrix(center(0,0),center(1,0),window);
00175     for(float x = center(0,0) - window; x <= center(0,0)+window; x++) {
00176       for(float y = center(1,0) - window; y <= center(1,0)+window; y++) {
00177   float delta = img1(x,y) - img2(x + trans(0,0) + opticalFlow(0,0),
00178                y + trans(1,0) + opticalFlow(1,0));
00179   fmat::Column<2> grad = img1.gradient(x,y);
00180 
00181   b += grad * delta;
00182       }
00183     }
00184     
00185     if(fmat::det(G) == 0) {
00186       cout << "========Bad Point========" << endl;
00187       return fmat::pack(0,0);
00188     }
00189 
00190     G = fmat::invert(G);
00191     
00192     fmat::Column<2> gamma = G * b;
00193 
00194     opticalFlow += gamma;
00195 
00196     //    if(((gamma(0,0) * gamma(0,0)) + (gamma(1,0)*gamma(1,0))) < ACCURACY_THRESHOLD)
00197     //      break;
00198     if( (gamma(0,0) * gamma(0,0)) + (gamma(1,0) * gamma(1,0)) < ACCURACY_THRESHOLD )
00199       break;
00200   }
00201 
00202   return opticalFlow;
00203 }
00204 
00205 */

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:45 2016 by Doxygen 1.6.3