Example #1
0
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]);
    }
  }
}