图形图像处理-之-误差扩散 下篇

  [email protected]    2008.04.22
 
tag: 误差扩散,真彩色到高彩色转换
  
摘要: 在图像的颜色转换过程中,由于颜色值域的不同,转换过程中可能会产生误差;
误差扩散算法通过将误差传递到周围像素而减轻其造成的视觉误差。
       
正文:
  代码使用C++,编译器:VC2005
  测试平台:(CPU:AMD64x2 4200+(2.37G); 内存:DDR2 677(双通道); 编译器:VC2005)
  
(请先参看文章的上篇)
 
 
E: 将误差扩散的浮点实现改写为一个整数的定点数实现:
     struct  TErrorColor{
        
long  dR;
        
long  dG;
        
long  dB;
    };

    inline 
long  getBestRGB16_555Color( const   long  wantColor){
        
const   long  rMax = ( 1 << 5 ) - 1 ;
        
if  (wantColor <= 0
            
return   0 ;
        
else   if  (wantColor >= (rMax << 3 ))
            
return  rMax;
        
else
            
return  wantColor >> 3 ;
    }
    inline 
long  getC8Color( const   long  rColor){
        
return  rColor * ((( 1 << 16 ) * 255 + 30 ) / 31 >> 16 ;
    }
    
void  CvsPic32To16_ErrorDiffuse_Line_1(TUInt16 *  pDst, const  TARGB32 *  pSrc, long  width,TErrorColor *  PHLineErr){
        TErrorColor HErr;
        HErr.dR
= 0 ; HErr.dG = 0 ; HErr.dB = 0 ;
        PHLineErr[
- 1 ].dB = 0 ; PHLineErr[ - 1 ].dG = 0 ; PHLineErr[ - 1 ].dR = 0
        
for  ( long  x = 0 ;x < width; ++ x)
        {
            
long  cB = (pSrc[x].b + HErr.dB * 2 + PHLineErr[x].dB + PHLineErr[x - 1 ].dB);
            
long  cG = (pSrc[x].g + HErr.dG * 2 + PHLineErr[x].dG + PHLineErr[x - 1 ].dG);
            
long  cR = (pSrc[x].r + HErr.dR * 2 + PHLineErr[x].dR + PHLineErr[x - 1 ].dR);
            
long  rB = getBestRGB16_555Color(cB);
            
long  rG = getBestRGB16_555Color(cG);
            
long  rR = getBestRGB16_555Color(cR);
            pDst[x]
=  rB | (rG << 5 ) | (rR << 10 );

            HErr.dB
= (cB - getC8Color(rB)) >> 2 ;
            HErr.dG
= (cG - getC8Color(rG)) >> 2 ;
            HErr.dR
= (cR - getC8Color(rR)) >> 2 ;

            PHLineErr[x
- 1 ].dB += HErr.dB;
            PHLineErr[x
- 1 ].dG += HErr.dG;
            PHLineErr[x
- 1 ].dR += HErr.dR;

            PHLineErr[x]
= HErr;
        }
    }

void  CvsPic32To16_ErrorDiffuse_1( const  TPicRegion_RGB16_555 &  dst, const  TPicRegion &  src){
    TUInt16
*  pDst = (TUInt16 * )dst.pdata;
    
const  TARGB32 *  pSrc = src.pdata;
    
const   long  width = src.width;

    TErrorColor
*  _HLineErr = new  TErrorColor[width + 2 ]; 
    
for  ( long  x = 0 ;x < width + 2 ; ++ x){
        _HLineErr[x].dR
= 0 ;
        _HLineErr[x].dG
= 0 ;
        _HLineErr[x].dB
= 0 ;
    }
    TErrorColor
*  HLineErr =& _HLineErr[ 1 ];

    
for  ( long  y = 0 ;y < src.height; ++ y){
        CvsPic32To16_ErrorDiffuse_Line_1(pDst,pSrc,width,HLineErr);
        (TUInt8
*& )pDst += dst.byte_width;
        (TUInt8
*& )pSrc += src.byte_width;
    }

    delete[]_HLineErr;
}


速度测试:
//////////////////////////////////////////////////////////////
//CvsPic32To16_ErrorDiffuse_1     154.4  FPS
//////////////////////////////////////////////////////////////
 
F:继续优化
 getBestRGB16_555Color函数有条件分支,建立一个查找表来代替,完整的实现如下:
 (CvsPic32To16_ErrorDiffuse_Line_2和CvsPic32To16_ErrorDiffuse_Line_1完成的功能一致)

     static  TUInt8 _BestRGB16_555Color_Table[ 256 * 5 ];
    
const  TUInt8 *  BestRGB16_555Color_Table =& _BestRGB16_555Color_Table[ 256 * 2 ];
    
struct  _TAutoInit_BestRGB16_555Color_Table{
        _TAutoInit_BestRGB16_555Color_Table(){
            
for  ( long  i = 0 ;i < 256 * 5 ; ++ i){
                _BestRGB16_555Color_Table[i]
= getBestRGB16_555Color(i - 256 * 2 );
            }
        }
    };
    
static  _TAutoInit_BestRGB16_555Color_Table _AutoInit_BestRGB16_555Color_Table;

    
void  CvsPic32To16_ErrorDiffuse_Line_2(TUInt16 *  pDst, const  TARGB32 *  pSrc, long  width,TErrorColor *  PHLineErr){
        TErrorColor HErr;
        HErr.dR
= 0 ; HErr.dG = 0 ; HErr.dB = 0 ;
        PHLineErr[
- 1 ].dB = 0 ; PHLineErr[ - 1 ].dG = 0 ; PHLineErr[ - 1 ].dR = 0
        
for  ( long  x = 0 ;x < width; ++ x)
        {
            
long  cB = (pSrc[x].b + HErr.dB * 2 + PHLineErr[x].dB + PHLineErr[x - 1 ].dB);
            
long  cG = (pSrc[x].g + HErr.dG * 2 + PHLineErr[x].dG + PHLineErr[x - 1 ].dG);
            
long  cR = (pSrc[x].r + HErr.dR * 2 + PHLineErr[x].dR + PHLineErr[x - 1 ].dR);
            
long  rB = BestRGB16_555Color_Table[cB];
            
long  rG = BestRGB16_555Color_Table[cG];
            
long  rR = BestRGB16_555Color_Table[cR];
            pDst[x]
=  rB | (rG << 5 ) | (rR << 10 );

            HErr.dB
= (cB - getC8Color(rB)) >> 2 ;
            HErr.dG
= (cG - getC8Color(rG)) >> 2 ;
            HErr.dR
= (cR - getC8Color(rR)) >> 2 ;

            PHLineErr[x
- 1 ].dB += HErr.dB;
            PHLineErr[x
- 1 ].dG += HErr.dG;
            PHLineErr[x
- 1 ].dR += HErr.dR;

            PHLineErr[x]
= HErr;
        }
    }
 
void  CvsPic32To16_ErrorDiffuse_2( const  TPicRegion_RGB16_555 &  dst, const  TPicRegion &  src){
    TUInt16
*  pDst = (TUInt16 * )dst.pdata;
    
const  TARGB32 *  pSrc = src.pdata;
    
const   long  width = src.width;

    TErrorColor
*  _HLineErr = new  TErrorColor[width + 2 ]; 
    
for  ( long  x = 0 ;x < width + 2 ; ++ x){
        _HLineErr[x].dR
= 0 ;
        _HLineErr[x].dG
= 0 ;
        _HLineErr[x].dB
= 0 ;
    }
    TErrorColor
*  HLineErr =& _HLineErr[ 1 ];

    
for  ( long  y = 0 ;y < src.height; ++ y){
        CvsPic32To16_ErrorDiffuse_Line_2(pDst,pSrc,width,HLineErr);
        (TUInt8
*& )pDst += dst.byte_width;
        (TUInt8
*& )pSrc += src.byte_width;
    }

    delete[]_HLineErr;
}

 
速度测试:
//////////////////////////////////////////////////////////////
//CvsPic32To16_ErrorDiffuse_2     166.8  FPS
//////////////////////////////////////////////////////////////

函数效果:

图形图像处理-之-误差扩散 下篇_第1张图片

你可能感兴趣的:(测试,table,delete,图形,编译器,图像处理)