//------------------------------------------------------------------------------------------------ // multi-grid belie propagation //------------------------------------------------------------------------------------------------ void BPFlow::generateCoarserLevel(BPFlow &bp) { //------------------------------------------------------------------------------------------------ // set the dimensions and parameters //------------------------------------------------------------------------------------------------ bp.Width=Width/2; if(Width%2==1) bp.Width++; bp.Height=Height/2; if(Height%2==1) bp.Height++; bp.Area=bp.Width*bp.Height; bp.s=s; bp.d=d; DImage foo; Im_s.smoothing(foo); foo.imresize(bp.Im_s,bp.Width,bp.Height); Im_d.smoothing(foo); foo.imresize(bp.Im_d,bp.Width,bp.Height); bp.IsDisplay=IsDisplay; bp.nNeighbors=nNeighbors; //------------------------------------------------------------------------------------------------ // allocate buffers //------------------------------------------------------------------------------------------------ for(int i=0;i<2;i++) { bp.pOffset[i]=new int[bp.Area]; bp.pWinSize[i]=new int[bp.Area]; ReduceImage(bp.pOffset[i],Width,Height,pOffset[i]); ReduceImage(bp.pWinSize[i],Width,Height,pWinSize[i]); for(int j = 0;j<bp.Area;j++) bp.pWinSize[i][j] = __max(bp.pWinSize[i][j],1); } //------------------------------------------------------------------------------------------------ // generate data term //------------------------------------------------------------------------------------------------ bp.nTotalMatches=bp.AllocateBuffer(bp.pDataTerm,bp.ptrDataTerm,bp.pWinSize[0],bp.pWinSize[1]); for(int i=0;i<bp.Height;i++) for(int j=0;j<bp.Width;j++) { int offset=i*bp.Width+j; for(int ii=0;ii<2;ii++) for(int jj=0;jj<2;jj++) { int y=i*2+ii; int x=j*2+jj; if(y<Height && x<Width) { int nStates=(bp.pWinSize[0][offset]*2+1)*(bp.pWinSize[1][offset]*2+1); for(int k=0;k<nStates;k++) bp.pDataTerm[offset].data()[k]+=pDataTerm[y*Width+x].data()[k]; } } } //------------------------------------------------------------------------------------------------ // generate range term //------------------------------------------------------------------------------------------------ bp.ComputeRangeTerm(gamma/2); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { FImage Im1,Im2; Im1.LoadMatlabImage(prhs[0]); Im2.LoadMatlabImage(prhs[1]); // define parameters double alpha=0.01; double d=1; double gamma=0.001; int nIterations=40; int nHierarchy=2; int wsize=5; // load the parameters for matching if(nrhs>=3) { int nDims=mxGetNumberOfDimensions(prhs[2]); if(nDims>2) mexErrMsgTxt("The third parameter must be a vector!"); const int* dims=mxGetDimensions(prhs[2]); if(dims[0]!=1 && dims[1]!=1) mexErrMsgTxt("The third parameter must be a vector!"); int nPara=dims[0]+dims[1]-1; double* para=(double *)mxGetData(prhs[2]); if(nPara>=1) alpha=para[0]; if(nPara>=2) d=para[1]; if(nPara>=3) gamma=para[2]; if(nPara>=4) nIterations=para[3]; if(nPara>=5) nHierarchy=para[4]; if(nPara>=6) wsize=para[5]; } //printf("Alpha: %f d: %f gamma: %f nIterations: %d nHierarchy: %d wsize: %d\n",alpha,d,gamma,nIterations,nHierarchy,wsize); // load offset information IntImage OffsetX,OffsetY; if(nrhs>=5) { OffsetX.LoadMatlabImage(prhs[3],false); // there is no force of conversion OffsetY.LoadMatlabImage(prhs[4],false); } IntImage WinSizeX,WinSizeY; if(nrhs>=7) { WinSizeX.LoadMatlabImage(prhs[5],false); // there is no force of conversion WinSizeY.LoadMatlabImage(prhs[6],false); } DImage Im_s,Im_d; if(nrhs==9) { Im_s.LoadMatlabImage(prhs[7],false); // no force of converstion Im_d.LoadMatlabImage(prhs[8],false); } // output parameters double* pEnergyList=NULL; if(nlhs>1) pEnergyList=outputMatrix2(plhs[1],1,nIterations); // the main function goes here BPFlow bpflow; bpflow.LoadImages(Im1.width(),Im1.height(),Im1.nchannels(),Im1.data(),Im2.width(),Im2.height(),Im2.data()); if(nrhs>7) bpflow.setPara(Im_s,Im_d); else bpflow.setPara(alpha,d); bpflow.setHomogeneousMRF(wsize); // first assume homogeneous setup if(nrhs>=4) bpflow.LoadOffset(OffsetX.data(),OffsetY.data()); if(nrhs>=6) bpflow.LoadWinSize(WinSizeX.data(),WinSizeY.data()); bpflow.ComputeDataTerm(); bpflow.ComputeRangeTerm(gamma); bpflow.MessagePassing(nIterations,nHierarchy,pEnergyList); bpflow.ComputeVelocity(); bpflow.flow().OutputToMatlab(plhs[0]); }
int main(int argc, char *argv[]) { time_t start,end; double dif; QCoreApplication a(argc, argv); time (&start); BiImage im1,im2,Im1,Im2; if(!im1.imread("sflowg.00.jpg")) { printf("Error in loading frame 1!"); return -1; } if(!im2.imread("sflowg.01.jpg")) { printf("Error in loading frame 2!"); return -1; } //if(!im1.imread("scene1.row2.jpg")) //{ // printf("Error in loading frame 1!"); // return -1; //} //if(!im2.imread("scene1.row3.jpg")) //{ // printf("Error in loading frame 2!"); // return -1; //} im1.GaussianSmoothing(Im1,.8,5); im2.GaussianSmoothing(Im2,.8,5); Im1.imresize(0.5); Im2.imresize(0.5); //Im1=im1; //Im2=im2; double alpha=0.03*255; double gamma=0.002*255; BPFlow bpflow; int wsize=7; bpflow.setDataTermTruncation(true); //bpflow.setTRW(true); //bpflow.setDisplay(false); bpflow.LoadImages(Im1.width(),Im1.height(),Im1.nchannels(),Im1.data(),Im2.data()); bpflow.setPara(alpha*2,alpha*20); bpflow.setHomogeneousMRF(wsize); bpflow.ComputeDataTerm(); bpflow.ComputeRangeTerm(gamma); bpflow.MessagePassing(100,3); //for(int i=0;i<55;i++) //{ // double CTRW=(i+1)*0.02; // bpflow.setCTRW(CTRW); // printf("No.%d CTRW=%f energy=%f\n",i+1,CTRW,bpflow.MessagePassing(300,1)); //} //bpflow.MessagePassing(60); bpflow.ComputeVelocity(); DImage vx(Im1.width(),Im1.height()),vy(Im1.width(),Im1.height()); for(int i=0;i<Im1.npixels();i++) { vx.data()[i]=bpflow.flow().data()[i*2]; vy.data()[i]=bpflow.flow().data()[i*2+1]; } vx.imwrite("vx_discrete.jpg",ImageIO::normalized); vy.imwrite("vy_discrete.jpg",ImageIO::normalized); time (&end); dif = difftime (end,start); printf ("It took you %.2lf seconds to run SIFT flow.\n", dif ); //return a.exec(); return 1; }
//------------------------------------------------------------------------------------------------ // multi-grid belief propagation //------------------------------------------------------------------------------------------------ void BPFlow::generateCoarserLevel(BPFlow &bp) { //------------------------------------------------------------------------------------------------ // set the dimensions and parameters //------------------------------------------------------------------------------------------------ bp.Width = Width / 2; if(Width % 2 == 1) bp.Width++; bp.Height = Height / 2; if(Height % 2 == 1) bp.Height++; bp.WinSize = WinSize; bp.Area = bp.Width * bp.Height; bp.s = s; bp.d = d; // DImage foo; // Im_s.smoothing(foo); // foo.imresize(bp.Im_s,bp.Width,bp.Height); // Im_d.smoothing(foo); // foo.imresize(bp.Im_d,bp.Width,bp.Height); bp.IsDisplay = IsDisplay; bp.nNeighbors = nNeighbors; bp.setPenalty(4 * alphaD, alphaV); //------------------------------------------------------------------------------------------------ // allocate buffers //------------------------------------------------------------------------------------------------ for(int i = 0; i < 2; i++) { bp.pOffset[i] = new int[bp.Area]; ReduceImage(bp.pOffset[i], Width, Height, pOffset[i]); } // generate mask bp.pMask1 = new bool[bp.Area]; bp.pMask2 = new bool[bp.Area]; memset(bp.pMask1, 0, sizeof(bool) * bp.Area); memset(bp.pMask2, 0, sizeof(bool) * bp.Area); int sum1 = 0; int sum2 = 0; for (int i = 0; i < bp.Width; i++) { for (int j = 0; j < bp.Height; j++) { int offset = i + j * bp.Width; sum1 = 0; sum2 = 0; for(int ii = 0; ii < 2; ii++) for(int jj = 0; jj < 2; jj++) { int x = j * 2 + jj; int y = i * 2 + ii; if(y < Height && x < Width) { int index = x + y * Width; if (pMask1[index]) sum1++; if (pMask2[index]) sum2++; } } if (sum1 > 0) bp.pMask1[offset] = true; if (sum2 > 0) bp.pMask2[offset] = true; } } // allocate buffer for(int i=0;i<2;i++) { bp.pOffset[i] = new int[bp.Area]; ReduceImage(bp.pOffset[i], Width, Height, pOffset[i]); } //------------------------------------------------------------------------------------------------ // generate data term //------------------------------------------------------------------------------------------------ bp.nTotalMatches = bp.AllocateBuffer(bp.pDataTerm, bp.ptrDataTerm, bp.WinSize); int nStates = (bp.WinSize * 2 + 1) * (bp.WinSize * 2 + 1); for(int i = 0; i < bp.Height; i++) for(int j = 0; j < bp.Width; j++) { int offset = i * bp.Width + j; for(int ii = 0; ii < 2; ii++) { for(int jj = 0; jj < 2; jj++) { int y = i * 2 + ii; int x = j * 2 + jj; if(y < Height && x < Width) { for(int k = 0; k < nStates; k++) bp.pDataTerm[offset].data()[k] += pDataTerm[y * Width + x].data()[k]; } } } } //------------------------------------------------------------------------------------------------ // generate range term //------------------------------------------------------------------------------------------------ bp.ComputeRangeTerm(gamma / 2); }