예제 #1
0
Vector<T> IM_Solver::Gauss_Seidel_Iteration(const Base_Matrix<T>& A, 
                                            const Vector<T>& b,
                                            Vector<T>& XO,
                                            const T TOL,
                                            const unsigned int Limit)
{
    unsigned int k = 1, n = b.getSize();
    Vector<T> x(n);
    
    if(A.numCols() != n || A.numRows() != n || XO.getSize() != n)
        throw Incompatible_Vector_Err();
     
    while(k <= Limit)
    {
        for(unsigned int i = 0; i < n; i++)
        {
            T sum = 0;            
            for(unsigned int j = 0; j < n; j++)
            {
                if(j < i)
                {
                    sum += -A(i,j)*x[j];
                }
                else if(j > i)
                {
                    sum += -A(i,j)*XO[j];
                }
            }
            x[i] = (sum+b[i])/A(i,i);
        }
        
        if(L2_norm(x-XO) < TOL)
        {
            return x;
        }
        k++;
        XO = x;
    }
    return Vector<T>(0);
}
예제 #2
0
파일: nl_means.cpp 프로젝트: BIC-MNI/EZminc
//Main function
 void *Sub_denoise_mt(void *arguments)
{

  nl_mean_mt arg;
  arg=*(nl_mean_mt *)arguments;
  int PID=0;
  PID=arg.thread_num;
  int ret;
  int x_min,x_max,y_min,y_max, z_min, z_max;
  int NbElement2 = (2*arg.neighborhoodsize[0]+1)*(2*arg.neighborhoodsize[1]+1)*(2*arg.neighborhoodsize[2]+1);
  
  typedef float Voisinages[NbElement2];
  Voisinages V1,V2;
  
  float w_max = 0;

  double epsilon= 0.0001;
  
  int offset_k = 0;
  int offset_j = 0;
  int offset_kk = 0;
  int offset_jj = 0;

  for (int k=arg.debut; k < arg.fin ; k++)
  {
    double count = 0;
    offset_k = k*(arg.vol_size[0]*arg.vol_size[1]);
   
    for (int j=0; j < arg.vol_size[1] ; j++)
    {
     
      offset_j = j*arg.vol_size[0];
      
      for (int i=0; i < arg.vol_size[0] ; i++)
      {
        float global_sum = 0;
        float average    = 0;
      


        x_min = MAX(0,i-arg.search[0]);      x_max = MIN(arg.vol_size[0]-1,i+arg.search[0]);
        y_min = MAX(0,j-arg.search[1]);      y_max = MIN(arg.vol_size[1]-1,j+arg.search[1]);
        z_min = MAX(0,k-arg.search[2]);      z_max = MIN(arg.vol_size[2]-1,k+arg.search[2]);

         // Only the voxel with a local mean and variance different to zero are processed. 
        // By this way the computational time is reduced since the background is not taken into account (or the B-scan mask for US image)
       
       
        if ((arg.mean_map[offset_k + offset_j + i] > epsilon) && (arg.var_map[offset_k + offset_j + i] > epsilon))
        {

          if ((arg.weight_method == 0) || (arg.weight_method == 2)) 
            Neiborghood(arg.in,i,j,k,arg.neighborhoodsize,V1,arg.vol_size,arg.weight_method);
//             
          if (arg.weight_method == 1)
            Neiborghood(arg.in,i,j,k,arg.neighborhoodsize,V1,arg.vol_size,arg.weight_method);

          w_max = 0;
          
          for (int kk = z_min; kk <= z_max; kk++)
          {
            offset_kk = kk*(arg.vol_size[0]*arg.vol_size[1]);
            
            for (int jj = y_min; jj <= y_max; jj++)
            {
              
              offset_jj = jj*arg.vol_size[0];
              
              for (int ii = x_min; ii <= x_max; ii++)
              {
		
                // To avoid the compute the weigh with null patch and the division by zero in ratio and ratio 2
                
                if ((arg.mean_map[offset_kk + offset_jj + ii] > epsilon) && (arg.var_map[offset_kk + offset_jj + ii] > epsilon))   
                {

                  
                  float ratio  = arg.mean_map[offset_k + offset_j + i]/arg.mean_map[offset_kk + offset_jj + ii];

                  float ratio2 = arg.var_map[offset_k + offset_j + i]/arg.var_map[offset_kk + offset_jj + ii];
                  
                  float weight = 0;

			
                      if ((arg.weight_method == 0) || (arg.weight_method == 2))
                      {
                            
                          if (   (arg.m_min <= ratio) && (ratio <= (1/arg.m_min)) 
                              && (arg.v_min <= ratio2) && (ratio2 <= (1/arg.v_min)) )
                          {
                            
                            
                            if ((ii != i) || (jj != j) || (kk != k))
                            {
                              float val_in;
                              count = count + 1;
                              Neiborghood(arg.in,ii,jj,kk,arg.neighborhoodsize,V2,arg.vol_size,arg.weight_method);
                              
                              weight = Weight(L2_norm(V1,V2,arg.neighborhoodsize),arg.beta,arg.filtering_param);
                              global_sum = global_sum + weight;
                              
                              
                              val_in=arg.hallucinate?arg.hallucinate[offset_kk + offset_jj + ii]:arg.in[offset_kk + offset_jj + ii];//VF
                              
                              //Rician denoising
                              if (arg.weight_method == 2) 
                                average = average + val_in * val_in *weight;
                              else
                                average = average + val_in * weight;
                              
                              if (weight > w_max) w_max = weight;
                            }
                          }
                        }
                        
                       else
                        {
                            
                         if (  (arg.m_min <= ratio) && (ratio <= (1/arg.m_min)))
                          {
                            if ((ii != i) || (jj != j) || (kk != k))
                            {
                              float val_in;
                              count = count + 1;
                              //Pearson distance computation
                              weight = Weight(Pearson_distance(V1,V2,arg.neighborhoodsize),arg.beta,arg.filtering_param);
                              global_sum = global_sum + weight;
                              val_in=arg.hallucinate?arg.hallucinate[offset_kk + offset_jj + ii]:arg.in[offset_kk + offset_jj + ii]; //VF
                              average = average + val_in * weight;
                              if (weight > w_max) w_max = weight;

                             }
                           }
                         }
                }
              }
            }
          }
	
       
          
          global_sum = global_sum + w_max;
          
          double denoised_value = 0.0;
          float val_in=arg.hallucinate?arg.hallucinate[offset_k + offset_j + i]:arg.in[offset_k + offset_j + i];//VF
         
        
          
          
          // Rician denoising
          if (arg.weight_method == 2)
          {
            average = average + val_in * val_in * w_max;
            
            if (global_sum != 0.0) 
            {  
             
              denoised_value = (average/global_sum) - (2*arg.filtering_param * arg.filtering_param); 
              
              if (denoised_value > 0.0)
                denoised_value = sqrt (denoised_value);
              else 
                denoised_value = 0.0;
              
              arg.out[offset_k + offset_j + i] = denoised_value;
            }
            else
            {
              arg.out[offset_k + offset_j + i] =  val_in;
            }
          }
          // Gaussian and Speckle denoising
          else
          {
           
            average = average + val_in*w_max; 
          
            if (global_sum != 0.0)
              arg.out[offset_k + offset_j + i] = average/global_sum;
            else
              arg.out[offset_k + offset_j + i] =  val_in;
          }
           
	
        }
      }
    }

    if(debug)
      std::cout<<"Thread ( "<< std::setw(2) <<PID+1<< " ) has finished the slice :"<<std::setw(3)<< k <<std::endl;

    ret = pthread_mutex_lock(arg.mp);
    *arg.mean_neighboors = *arg.mean_neighboors + count/(arg.vol_size[0]*arg.vol_size[1]);
    ret = pthread_mutex_unlock(arg.mp);
  }
  if(debug)
    std::cout<<"End of the thread : "<<std::setw(2)<<PID+1<<std::endl;
  
  pthread_exit(0);
}