void LucasKanade::compute(const CImg< unsigned char > &I1, const CImg< unsigned char > &I2, CImg< double > &V) { int baseIndex = 0, index; int i; int x, y; LSQInput lsqInput; LSQResults lsqResults; width_ = I1.width(); height_ = I1.height(); I1_.assign(I1, true); I2_.assign(I2, true); computeGradients_(I1_, G1_); if(COMPUTE_RESIDUALS_ == true) { residualSum_ = 0.0; maxResidual_ = 0.0; numResidualSumTerms_ = 0; } roi_ = LucasKanadeROI(-WINDOW_RADIUS_, -WINDOW_RADIUS_, WINDOW_SIZE_, WINDOW_SIZE_, I1_, G1_, W_); roi_.initialize(); for(y = 0; y < height_; y++) { index = baseIndex; for(x = 0; x < width_; x++) { lsqInput.x = x; lsqInput.y = y; lsqInput.ivx = V(x, y, 0, 0); lsqInput.ivy = V(x, y, 0, 1); computeLSQVelocity_(lsqInput, lsqResults); V(x, y, 0, 0) = lsqResults.vx; V(x, y, 0, 1) = lsqResults.vy; for(i = 0; i < getNumResultQualityChannels(); i++) V(x, y, 0, 2 + i) = lsqResults.quality[i]; index++; roi_.translate(1, 0); } baseIndex += width_; roi_.translate(-width_, 1); } }
void HornSchunck::compute(const CImg< unsigned char > &I1, const CImg< unsigned char > &I2, CImg< double > &V) { int x, y, i; double uAvg, vAvg; double numer, denom; width_ = I1.dimx(); height_ = I1.dimy(); CImg< double > V_; V_.assign(V, true); computeGradients_(I1, I2); for(i = 0; i < NUM_ITERATIONS_; i++) { for(y = 1; y < height_ - 1; y++) { //#pragma omp parallel for ordered schedule(static) shared(V_) private(numer,denom,uAvg,vAvg) for(x = 1; x < width_ - 1; x++) { uAvg = (V_(x, y-1, 0) + V_(x+1, y, 0) + V_(x, y+1, 0) + V_(x-1, y, 0)) / 6.0 + (V_(x-1, y-1, 0) + V_(x+1, y-1, 0) + V_(x-1, y+1, 0) + V_(x+1, y+1, 0)) / 12.0; vAvg = (V_(x, y-1, 1) + V_(x+1, y, 1) + V_(x, y+1, 1) + V_(x-1, y, 1)) / 6.0 + (V_(x-1, y-1, 1) + V_(x+1, y-1, 1) + V_(x-1, y+1, 1) + V_(x+1, y+1, 1)) / 12.0; numer = Gx_(x, y)*uAvg + Gy_(x, y)*vAvg + Gt_(x, y); denom = ALPHA_*ALPHA_ + Gx_(x, y)*Gx_(x, y) + Gy_(x, y)*Gy_(x, y); //#pragma omp ordered V_(x, y, 0) = (1.0 - RELAX_COEFF_) * V_(x, y, 0) + RELAX_COEFF_ * (uAvg - Gx_(x, y)*numer/denom); V_(x, y, 1) = (1.0 - RELAX_COEFF_) * V_(x, y, 1) + RELAX_COEFF_ * (vAvg - Gy_(x, y)*numer/denom); V_(x, y, 2) = 1.0; } } repairEdges_(V_); printProgressBar_(1.0*i / (NUM_ITERATIONS_ - 1)); } std::cout<<std::endl; }
void Proesmans::compute(const CImg< unsigned char > &I1, const CImg< unsigned char > &I2, CImg< double > &VF, CImg< double > &VB) { int i, j; int x, y; double vAvg[2]; double xd, yd; double It; double vNext[2]; width_ = I1.dimx(); height_ = I1.dimy(); I_[0].assign(I1, true); I_[1].assign(I2, true); V_[0].assign(VF, true); V_[1].assign(VB, true); computeGradients_(I_[0], G_[0]); computeGradients_(I_[1], G_[1]); gamma_[0] = CImg< double >(width_, height_); gamma_[1] = CImg< double >(width_, height_); for(i = 0; i < NUM_ITERATIONS_; i++) { if(i < NUM_ITERATIONS_) computeConsistencyMaps_(); for(y = 1; y < height_ - 1; y++) { for(x = 1; x < width_ - 1; x++) { for(j = 0; j < 2 ; j++) { computeAvg_(x, y, gamma_[j], V_[j], &vAvg[0]); xd = x + vAvg[0]; yd = y + vAvg[1]; //iteration step if(xd >= 0 && xd <= width_ - 1 && yd >= 0 && yd <= height_ - 1) { It = (I_[1 - j].linear_at2(xd, yd) - I_[j].at2(x, y)) * INTENSITY_SCALE_; IterationStep_(G_[j](x, y, 0), G_[j](x, y, 1), It, vAvg, &vNext[0]); } else { // use consistency-weighted average as the next value // if (xd,yd) is outside the image vNext[0] = vAvg[0]; vNext[1] = vAvg[1]; } if(i < NUM_ITERATIONS_) { V_[j](x, y, 0) = vNext[0]; V_[j](x, y, 1) = vNext[1]; } } // store quality information (gamma) if(i < NUM_ITERATIONS_) { VF(x, y, 2) = gamma_[0](x, y); VB(x, y, 2) = gamma_[1](x, y); } } } if(i < NUM_ITERATIONS_ && BOUNDARY_CONDITIONS_ == NEUMANN) { repairEdges_(V_[0]); repairEdges_(V_[1]); } } }