⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mg.cpp

📁 把黑白照片转换成彩色照片的数值优化算法。
💻 CPP
字号:
#include "mg.h"
#include <iostream.h>

 

void MG::smooth(int level) {
  Tensor3d& P = _P[level] ;
  Tensor3d& D = _Div[level];
  
  
  int len_x = (int)(_len_x * pow(2,-level)) ;
  int len_y = (int)(_len_y * pow(2,-level)) ;
  
  
 
  double v,av;
  int nanind=-1;
  vector<pair<index,float> >::iterator cnebl_itr;
  
  bool first_nan=1;
  
  for(int z = 0 ; z< _len_z ; z++){
    for(int y = 0 ; y < len_y ; y++){
      for(int x = 0 ; x < len_x ; x++) {
	
	if ((level==0)&(!_I[level](x,y,z))){
	  P(x,y,z)=D(x,y,z);
	  continue;
	}
	if ((level>0)&(!_I[level](x,y,z))){
	  continue;
	}
	vector<pair<index,float> >& cnebl=_nebl[level](x,y,z);
	  
	v=0;
        av=cnebl.begin()->second;

        cnebl_itr=cnebl.begin(); cnebl_itr++;
	for (; cnebl_itr!=cnebl.end();cnebl_itr++){
	  v+=cnebl_itr->second*(*cnebl_itr->first);
	}
	P(x,y,z)=(D(x,y,z)-v)/(av);
	
      }
    } 
  }
}

void MG::set_init_guess(void) {
}
  
void MG::calc_next_level_residual(int level) {
  Tensor3d& D = _Div[level] ;
  int len_x = (int)(_len_x * pow(2,-level)) ;
  int len_y = (int)(_len_y * pow(2,-level)) ;

  Tensor3d R(len_x, len_y,_len_z) ;
  vector<pair<index,float> >::iterator cnebl_itr;
  
  double v ;
  
  if (level==0){
    _residual=0;
  }
 
  R.clear(0);
  for(int z = 0 ; z < _len_z ; z++){
    for(int y = 0 ; y < len_y ; y++){
      for(int x = 0 ; x < len_x ; x++) {
	if(_I[level](x,y,z) < 1) {
	  R(x,y,z) = 0 ;
	  continue;
	}
	v=0;
	vector<pair<index,float> >& cnebl=_nebl[level](x,y,z);
	cnebl_itr=cnebl.begin();
	for (; cnebl_itr!=cnebl.end();cnebl_itr++){
	  v+=cnebl_itr->second*(*cnebl_itr->first);
	}
	R(x,y,z)=D(x,y,z)-v;
      }
    }
  }
  if (level==0){
    _residual =_residual+ R.norm_euc() ;
  }
  if ( (level+1)<_depth){
    restrict(_P[level],_P[level+1]) ;
  }
  
  int nx = len_x / 2 ;
  int ny = len_y / 2 ;
  
  if(level == 0) {
    //  cout <<"level "<<level<<" residual "<< _residual << endl ;
  }
  
}

void MG::zero_next_level(int level) {
}


void MG::add_prolonged_prev_level(int level) {
  Tensor3d pP,tpP; 

  restrict(_P[level],tpP);
  tpP-=_P[level+1];
  prolong(tpP, pP);  
  _P[level] -= pP ;
}


void MG::advance_in_time() {
}


void MG::prolong(Tensor3d& P, Tensor3d& pP) {
  {
    int nx = P.len_x ;
    int ny = P.len_y ;
    int nz = P.len_z ;
    
    int px = nx ;
    int py = ny ;
    int pz = nz ;
    
    int ppx = nx * 2 ;
    int ppy = ny * 2 ;
    int ppz = nz ;
    
    pP.set(ppx, ppy ,ppz) ;

    /* prolonging P */
    for (int z=0; z<nz; z++){
      
      int xxyy = 1 + ppx +z*ppx*ppy;
      int xxpyy = xxyy + 1 ;
      int xxyyp = xxyy + ppx ;
      int xxpyyp = xxyy + 1 + ppx ;
    
      int xy = 0 +z*px*py;
      int xpy = 1 +z*px*py;
      int xyp = px +z*px*py;
      int xpyp = 1 + px +z*px*py ;
      int x,y;
      for( y = 1 ; y < py ; y++) {
	for(x = 1 ; x < px ; x++) {
         
	  pP[xxyy] = 0.5 * P[xy] + 0.25 * (P[xpy] + P[xyp]) ;
	  pP[xxpyy] = 0.5 * P[xpy] + 0.25 * (P[xy] + P[xpyp]) ;
	  pP[xxyyp] = 0.5 * P[xyp] + 0.25 * (P[xpyp] + P[xy]) ;
	  pP[xxpyyp] = 0.5 * P[xpyp] + 0.25 * (P[xpy] + P[xyp]) ;
	  xy ++ ; xpy ++ ; xyp ++ ; xpyp ++ ;
	  xxyy += 2 ; xxpyy += 2 ; xxyyp += 2 ; xxpyyp += 2 ; 
	}
	xy ++ ; xpy ++ ; xyp ++ ; xpyp ++ ;
	xxyy += ppx + 2 ; xxpyy += ppx + 2 ; xxyyp += ppx + 2 ; xxpyyp += ppx + 2 ;
      }

      for( x = 1 ; x < px ; x++) {
	pP(2*x-1,0,z) = P(x-1,0,z) * 0.75 +  P(x,0,z) * 0.25 ;
	pP(2*x-1,ppy-1,z) = P(x-1,py-1,z) * 0.75 +  P(x,py-1,z) * 0.25 ;

	pP(2*x,0,z) = P(x-1,0,z) * 0.25 +  P(x,0,z) * 0.75 ;
	pP(2*x,ppy-1,z) = P(x-1,py-1,z) * 0.25 +  P(x,py-1,z) * 0.75 ;

      }
      for( y = 1 ; y < py ; y++) {
	pP(0,2*y-1,z) = P(0,y-1,z) * 0.75 +  P(0,y,z) * 0.25 ;
	pP(ppx-1,2*y-1,z) = P(px-1,y-1,z) * 0.75 +  P(px-1,y,z) * 0.25 ;

	pP(0,2*y,z) = P(0,y-1,z) * 0.25 + P(0,y,z) * 0.75 ;
	pP(ppx-1,2*y,z) = P(px-1,y-1,z) * 0.25 +  P(px-1,y,z) * 0.75 ;
      }
     
      pP(0,0,z) = P(0,0,z) ;
      pP(ppx-1,0,z) = P(px-1,0,z) ;
      pP(0,ppy-1,z) = P(0,py-1,z) ;
      pP(ppx-1,ppy-1,z) = P(px-1,py-1,z) ;
    }
  }

}



void MG::restrict(Tensor3d& P, Tensor3d& rP) {
 
  int nx = P.len_x ;
  int ny = P.len_y ;
  int nz = P.len_z;
  
  int px = nx / 2 ;
  int py = ny / 2 ;
  int pz = nz;
  rP.set(px, py, pz) ;
  
  int ppx = nx ;

  for (int z=0; z<nz; z++)
  {
    int xy = z*px*py;
    int xxyy = z*nx*ny ;
    int xxpyy = 1 + z*nx*ny;
    int xxyyp = 1 * ppx + z*nx*ny ;
    int xxpyyp = 1 + 1 * ppx + z*nx*ny ;
    
    for(int y = 0 ; y < py ; y++) {
      for(int x = 0 ; x < px ; x++) {
	rP[xy] = (P[xxyy] + P[xxpyy] + P[xxyyp] + P[xxpyyp]) * 0.25 ;
	xy ++ ;
	xxyy += 2 ; xxpyy += 2 ; xxyyp += 2 ; xxpyyp += 2 ;
      }   
      xxyy += ppx  ; xxpyy += ppx ; xxyyp += ppx ; xxpyyp += ppx ;
    }
  }
}



void MG::setFlow(Tensor3d& dx,Tensor3d& dy,Tensor3d& idx,Tensor3d& idy){
  int x0, y0, z0, cx0, cy0, x,y,z,level;
  int len_x=2*_len_x;
  int len_y=2*_len_y;
  double tw;

  Tensor3d pdx,pdy,pidx,pidy,td;
  pdx=dx;
  pdy=dy;
  pidx=idx;
  pidy=idy;
  vector< vector< Tensore3dVI> > neb;
  neb.resize(_depth);
  
  for ( level=0; level<_depth; level++){
    len_x=len_x/2;
    len_y=len_y/2;
    neb[level].resize(_perms_num);
    
    for (int p=0; p<_perms_num;p++){
      neb[level][p].set(len_x,len_y,_len_z);
      
      for ( z=0; z<_len_z; z++){ 
	for ( y=0; y<len_y; y++){
	  for ( x=0; x<len_x; x++){
	    neb[level][p](x,y,z).reserve( _perms_len);
	  }
	}
      }
    
      for ( z=0; z<_len_z; z++){ 
	for ( y=0; y<len_y; y++){
	  for ( x=0; x<len_x; x++){
       
	    for (int q=0; q<_perms_len; q++){
	      x0=x+_perms[p][q][0];
	      y0=y+_perms[p][q][1];
	      z0=z+_perms[p][q][2];
	      
	      if ((x0<0)|(y0<0)|(z0<0)|(x0>=len_x)|(y0>=len_y)|(z0>=_len_z)){
		continue;
	      }
	      if (z0<z){
		 cx0=int(x0-pdx(x0,y0,z0)+0.5);
		 cy0=int(y0-pdy(x0,y0,z0)+0.5);
	      }
	      if (z0>z){
		 cx0=int(x0-pidx(x0,y0,z)+0.5);
		 cy0=int(y0-pidy(x0,y0,z)+0.5);
	      }
	      if (z0==z){
		cx0=x0; cy0=y0;
	      }
	      if ((cx0<0)|(cy0<0)|(z0<0)|(cx0>=len_x)|(cy0>=len_y)|(z0>=_len_z)){
		continue;
	      } 
	      
	      neb[level][p](x,y,z).push_back(cx0+cy0*len_x+z0*len_x*len_y);
	   
	    }  
	  }
	}
      }
    }


    restrict(pdx,td);
    pdx=td;
    restrict(pdy,td);
    pdy=td;
    restrict(pidx,td);
    pidx=td;
    restrict(pidy,td);
    pidy=td;
  }
  



  vector<int> tlist, tneb;
  vector<int>::iterator tneb_itr,tlist_itr,end_itr;
  
  vector<pair<index,float> > cnebl;
  vector<pair<index,float> > *pcnebl;
  pair<index,float> tpair;
  int prev_ind;
  len_x=2*_len_x; len_y=2*_len_y;
  
  for ( level=0; level<_depth; level++){
    len_x=len_x/2;
    len_y=len_y/2;
    _nebl[level].set(len_x,len_y,_len_z);
 
    for (int z=0; z<_len_z; z++){ 
      for (int y=0; y<len_y; y++){
	for (int x=0; x<len_x; x++){
	  
          tlist.resize(0);
	  for (int p=0; p<_perms_num;p++){
	    tneb=neb[level][p](x,y,z);
	    for (tneb_itr=tneb.begin(); tneb_itr!=tneb.end();tneb_itr++){
	      tlist.push_back(*tneb_itr); 
	    }
	    
	  }
	  
          sort(tlist.begin(),tlist.end());
	
 
	  if ( _len_z==1){
	    _nebl[level](x,y,z).reserve(9);
	  }else{
	    _nebl[level](x,y,z).reserve(27);
	  }
	  
 
	  pcnebl=&_nebl[level](x,y,z);
	  
	  prev_ind=-1;
	  for(tlist_itr=tlist.begin(); tlist_itr!=tlist.end(); tlist_itr++){
	    if (prev_ind< (*tlist_itr)){
              tpair.first=&(_P[level][*tlist_itr]);
	      tpair.second=0;		   
	      pcnebl->push_back(tpair);
	      prev_ind= (*tlist_itr);   
	    }
	  }
	 
	  
	}

      }
    }
    
  }

  
  
   
  double var, mean, g_val, sum_w, t_val;
  vector<double> g_vec,w_vec,b_g_vec;
  vector<index> p_vec;
  vector<pair<index, pair<double,double> > > t_vec;
  vector<pair<index, pair<double,double> > >::iterator t_vec_itr;
  pair<index, pair<double,double> > t_data;
  vector<pair<index,float> >::iterator cnebl_itr;
  len_x=2*_len_x; len_y=2*_len_y;
  bool first_nan=1;
  
  
  for ( level=0; level<_depth; level++){
    len_x=len_x/2;
    len_y=len_y/2;
    
    for (int z=0; z<_len_z; z++){ 
      for (int y=0; y<len_y; y++){
	for (int x=0; x<len_x; x++){
	 
	  for (int p=0; p<_perms_num;p++){
	   
	    tneb=neb[level][p](x,y,z);
	   
	    sort(tneb.begin(),tneb.end());
	    end_itr=unique(tneb.begin(),tneb.end());

	   
	    
	    double csig;
	    int i;
            var=0; t_val=_G[level][1](x,y,z);
	    
	   
	    var=0; mean=0; sum_w=0;
	    g_vec.resize(0);
	    tneb_itr=tneb.begin();
	    for (i=0; tneb_itr!=end_itr;tneb_itr++, i++){
	      g_val=_G[level][1][*tneb_itr];
	      g_vec.push_back((g_val-t_val)*(g_val-t_val)); 
	      sum_w+=1;
	      var+=g_val*g_val;
	      mean+=g_val;
	    }

	    if (g_vec.size()<2){
	      continue;
	    }
	    
	    var/=sum_w;
	    mean/=sum_w;
	    var-=mean*mean;
  
	    sort(g_vec.begin(),g_vec.end());
	    csig=var*0.6;
	    
	    if (csig<(-g_vec[1]/log(0.01))){
	      csig=-g_vec[1]/log(0.01);
	    }
	    if (csig<0.000002){
	      csig=0.000002;
	    }
            sum_w=0;
	    for(i=0; i<g_vec.size(); i++){
	      sum_w+=exp(-g_vec[i]/csig);
	    }
	 
	    t_vec.resize(0);
	    tneb_itr=tneb.begin();   
	    
	    for (i=0; tneb_itr!=end_itr;tneb_itr++, i++){	
	      g_val=_G[level][1][*tneb_itr];
	       
	      tw=exp(-(g_val-t_val)*(g_val-t_val)/csig)/sum_w;
	      
	      if(  (&_P[level][tneb[i]])==(&_P[level](x,y,z))){
		tw-=1;
	      }
	      t_data.first=&_P[level][tneb[i]];
	      t_data.second.first=g_val;
	      t_data.second.second=tw;
	      t_vec.push_back(t_data); 
	
	    }
  
            sort(t_vec.begin(),t_vec.end());
	    
	    pcnebl=&_nebl[level](x,y,z);
	    cnebl_itr=pcnebl->begin();
	  
	    for (t_vec_itr=t_vec.begin();t_vec_itr!=t_vec.end();t_vec_itr++){
	      for(;cnebl_itr->first<t_vec_itr->first;++cnebl_itr);	
	
	      cnebl_itr->second+=(t_vec_itr->second.second);
	      cnebl_itr++; 
	    }
	     
	  }
	   
	  
	}
      }
    }
  }
  
  index cp;
  vector<pair<index,float> >::iterator pnebl_itr;
  len_x=2*_len_x; len_y=2*_len_y;
  for (level=0; level<_depth; level++){
    len_x=len_x/2;
    len_y=len_y/2;
    
    for (int z=0; z<_len_z; z++){ 
      for (int y=0; y<len_y; y++){
	for (int x=0; x<len_x; x++){
	  pcnebl=&_nebl[level](x,y,z);
	  cp=&_P[level](x,y,z);
	 
	  for (cnebl_itr=pcnebl->begin(); cnebl_itr->first!=cp; cnebl_itr++);
	  tpair=*cnebl_itr;
	  pnebl_itr=cnebl_itr;
	   
	  for (; cnebl_itr!=pcnebl->begin();--cnebl_itr){
	    --pnebl_itr;
	    *cnebl_itr=*pnebl_itr;
	  }
	   
	  *(pcnebl->begin())=tpair;
	}

      }
    }
  }  
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -