//-------------------------------------------------------------------------------------- // function to perfomr coarse to fine optical flow estimation //-------------------------------------------------------------------------------------- void OpticalFlow::Coarse2FineFlow(DImage &vx, DImage &vy, DImage &warpI2,const DImage &Im1, const DImage &Im2, double alpha, double ratio, int minWidth, int nOuterFPIterations, int nInnerFPIterations, int nCGIterations) { // first build the pyramid of the two images GaussianPyramid GPyramid1; GaussianPyramid GPyramid2; if(IsDisplay) cout<<"Constructing pyramid..."; GPyramid1.ConstructPyramid(Im1,ratio,minWidth); GPyramid2.ConstructPyramid(Im2,ratio,minWidth); if(IsDisplay) cout<<"done!"<<endl; // now iterate from the top level to the bottom DImage Image1,Image2,WarpImage2; for(int k=GPyramid1.nlevels()-1; k>=0; k--) { if(IsDisplay) cout<<"Pyramid level "<<k; int width=GPyramid1.Image(k).width(); int height=GPyramid1.Image(k).height(); im2feature(Image1,GPyramid1.Image(k)); im2feature(Image2,GPyramid2.Image(k)); if(k==GPyramid1.nlevels()-1) // if at the top level { vx.allocate(width,height); vy.allocate(width,height); //warpI2.copyData(Image2); WarpImage2.copyData(Image2); } else { vx.imresize(width,height); vx.Multiplywith(1/ratio); vy.imresize(width,height); vy.Multiplywith(1/ratio); //warpFL(warpI2,GPyramid1.Image(k),GPyramid2.Image(k),vx,vy); warpFL(WarpImage2,Image1,Image2,vx,vy); } //SmoothFlowPDE(GPyramid1.Image(k),GPyramid2.Image(k),warpI2,vx,vy,alpha,nOuterFPIterations,nInnerFPIterations,nCGIterations); //SmoothFlowPDE(Image1,Image2,WarpImage2,vx,vy,alpha*pow((1/ratio),k),nOuterFPIterations,nInnerFPIterations,nCGIterations); SmoothFlowPDE(Image1,Image2,WarpImage2,vx,vy,alpha,nOuterFPIterations,nInnerFPIterations,nCGIterations); if(IsDisplay) cout<<endl; } warpFL(warpI2,Im1,Im2,vx,vy); }
//-------------------------------------------------------------------------------------- // function to perfomr coarse to fine optical flow estimation //-------------------------------------------------------------------------------------- void OpticalFlow::Coarse2FineFlow(DImage &vx, DImage &vy, DImage &warpI2,const DImage &Im1, const DImage &Im2, double alpha, double ratio, int minWidth, int nOuterFPIterations, int nInnerFPIterations, int nCGIterations) { // first build the pyramid of the two images GaussianPyramid GPyramid1; GaussianPyramid GPyramid2; if(IsDisplay) cout<<"Constructing pyramid..."; GPyramid1.ConstructPyramid(Im1,ratio,minWidth); GPyramid2.ConstructPyramid(Im2,ratio,minWidth); if(IsDisplay) cout<<"done!"<<endl; // now iterate from the top level to the bottom DImage Image1,Image2,WarpImage2; // initialize noise // cout << GPyramid1.nlevels() << " pyramid levels\n"; for(int k=GPyramid1.nlevels()-1;k>=0;k--) { if(IsDisplay) cout<<"Pyramid level "<<k+1; int width=GPyramid1.Image(k).width(); int height=GPyramid1.Image(k).height(); im2feature(Image1,GPyramid1.Image(k)); im2feature(Image2,GPyramid2.Image(k)); // cout << "\t- level " << k+1 << " size " << width <<"x" << height <<endl; if(k==GPyramid1.nlevels()-1) // if at the top level { vx.allocate(width,height); vy.allocate(width,height); WarpImage2.copyData(Image2); } else { vx.imresize(width,height); vx.Multiplywith(1/ratio); vy.imresize(width,height); vy.Multiplywith(1/ratio); if(interpolation == Bilinear) warpFL(WarpImage2,Image1,Image2,vx,vy); else Image2.warpImageBicubicRef(Image1,WarpImage2,vx,vy); } SmoothFlowSOR(Image1,Image2,WarpImage2,vx,vy,alpha,nOuterFPIterations+k,nInnerFPIterations,nCGIterations+k*3); //GMPara.display(); if(IsDisplay) cout<<endl; } //warpFL(warpI2,Im1,Im2,vx,vy); Im2.warpImageBicubicRef(Im1,warpI2,vx,vy); warpI2.threshold(); }
//-------------------------------------------------------------------------------------- // function to perfomr coarse to fine optical flow estimation //-------------------------------------------------------------------------------------- void OpticalFlow::Coarse2FineFlow(DImage &vx, DImage &vy, DImage &warpI2,const DImage &Im1, const DImage &Im2, double alpha, double ratio, int minWidth, int nOuterFPIterations, int nInnerFPIterations, int nCGIterations) { // first build the pyramid of the two images GaussianPyramid GPyramid1; GaussianPyramid GPyramid2; if(IsDisplay) cout<<"Constructing pyramid..."; GPyramid1.ConstructPyramid(Im1,ratio,minWidth); GPyramid2.ConstructPyramid(Im2,ratio,minWidth); if(IsDisplay) cout<<"done!"<<endl; // now iterate from the top level to the bottom DImage Image1,Image2,WarpImage2; //GaussianMixture GMPara(Im1.nchannels()+2); // initialize noise switch(noiseModel){ case GMixture: GMPara.reset(Im1.nchannels()+2); break; case Lap: LapPara.allocate(Im1.nchannels()+2); for(int i = 0;i<LapPara.dim();i++) LapPara[i] = 0.02; break; } for(int k=GPyramid1.nlevels()-1;k>=0;k--) { if(IsDisplay) cout<<"Pyramid level "<<k; int width=GPyramid1.Image(k).width(); int height=GPyramid1.Image(k).height(); im2feature(Image1,GPyramid1.Image(k)); im2feature(Image2,GPyramid2.Image(k)); if(k==GPyramid1.nlevels()-1) // if at the top level { vx.allocate(width,height); vy.allocate(width,height); //warpI2.copyData(Image2); WarpImage2.copyData(Image2); } else { vx.imresize(width,height); vx.Multiplywith(1/ratio); vy.imresize(width,height); vy.Multiplywith(1/ratio); //warpFL(warpI2,GPyramid1.Image(k),GPyramid2.Image(k),vx,vy); if(interpolation == Bilinear) warpFL(WarpImage2,Image1,Image2,vx,vy); else Image2.warpImageBicubicRef(Image1,WarpImage2,vx,vy); } //SmoothFlowPDE(GPyramid1.Image(k),GPyramid2.Image(k),warpI2,vx,vy,alpha,nOuterFPIterations,nInnerFPIterations,nCGIterations); //SmoothFlowPDE(Image1,Image2,WarpImage2,vx,vy,alpha*pow((1/ratio),k),nOuterFPIterations,nInnerFPIterations,nCGIterations,GMPara); //SmoothFlowPDE(Image1,Image2,WarpImage2,vx,vy,alpha,nOuterFPIterations,nInnerFPIterations,nCGIterations); SmoothFlowSOR(Image1,Image2,WarpImage2,vx,vy,alpha,nOuterFPIterations+k,nInnerFPIterations,nCGIterations+k*3); //GMPara.display(); if(IsDisplay) cout<<endl; } //warpFL(warpI2,Im1,Im2,vx,vy); Im2.warpImageBicubicRef(Im1,warpI2,vx,vy); warpI2.threshold(); }