Bayer转换算法[转]

ExpandedBlockStart.gif 代码
注: 本代码非本人所作, 如他人用于其它任何用途均与本人无关.

/*  raw.h  */
#ifndef __RAW_H__ 
#define  __RAW_H__ 
 
#define  GP_OK 1 
 
typedef 
enum  { 
    BAYER_TILE_RGGB 
=   0
    BAYER_TILE_GRBG 
=   1
    BAYER_TILE_BGGR 
=   2
    BAYER_TILE_GBRG 
=   3
    BAYER_TILE_RGGB_INTERLACED 
=   4
    BAYER_TILE_GRBG_INTERLACED 
=   5
    BAYER_TILE_BGGR_INTERLACED 
=   6
    BAYER_TILE_GBRG_INTERLACED 
=   7
} BayerTile; 
 
int  gp_bayer_expand (unsigned  char   * input,  int  w,  int  h, unsigned  char   * output, 
                     BayerTile tile); 
int  gp_bayer_decode (unsigned  char   * input,  int  w,  int  h, unsigned  char   * output, 
             BayerTile tile); 
int  gp_bayer_interpolate (unsigned  char   * image,  int  w,  int  h, BayerTile tile); 
#endif  

/*  raw.c  */
#include 
" raw.h "     
   
static   const   int  tile_colours[ 8 ][ 4 =  {   
    {
0 1 1 2 },   
    {
1 0 2 1 },   
    {
2 1 1 0 },   
    {
1 2 0 1 },   
    {
0 1 1 2 },   
    {
1 0 2 1 },   
    {
2 1 1 0 },   
    {
1 2 0 1 }};   
   
#define  RED 0    
#define  GREEN 1    
#define  BLUE 2    
   
static   int    
gp_bayer_accrue (unsigned 
char   * image,  int  w,  int  h,  int  x0,  int  y0,   
        
int  x1,  int  y1,  int  x2,  int  y2,  int  x3,  int  y3,  int  colour);   
   
int    
gp_bayer_expand (unsigned 
char   * input,  int  w,  int  h, unsigned  char   * output,   
         BayerTile tile)   
{   
    
int  x, y, i;   
    
int  colour, bayer;   
    unsigned 
char   * ptr  =  input;   
   
    
switch  (tile) {   
   
        
case  BAYER_TILE_RGGB:   
        
case  BAYER_TILE_GRBG:   
        
case  BAYER_TILE_BGGR:   
        
case  BAYER_TILE_GBRG:   
   
            
for  (y  =   0 ; y  <  h;  ++ y)   
                
for  (x  =   0 ; x  <  w;  ++ x,  ++ ptr)    
                {   
                    bayer 
=  (x & 1 ? 0 : 1 +  (y & 1 ? 0 : 2 );   
   
                    colour 
=  tile_colours[tile][bayer];   
   
                    i 
=  (y  *  w  +  x)  *   3 ;   
   
                    output[i
+ RED]     =   0 ;   
                    output[i
+ GREEN]   =   0 ;   
                    output[i
+ BLUE]    =   0 ;   
                    output[i
+ colour]  =   * ptr;   
                }   
            
break ;   
   
        
case  BAYER_TILE_RGGB_INTERLACED:   
        
case  BAYER_TILE_GRBG_INTERLACED:   
        
case  BAYER_TILE_BGGR_INTERLACED:   
        
case  BAYER_TILE_GBRG_INTERLACED:   
   
   
            
for  (y  =   0 ; y  <  h;  ++ y, ptr += w)   
                
for  (x  =   0 ; x  <  w;  ++ x)    
                {   
                    bayer 
=  (x & 1 ? 0 : 1 +  (y & 1 ? 0 : 2 );   
   
                    colour 
=  tile_colours[tile][bayer];   
       
                    i 
=  (y  *  w  +  x)  *   3 ;   
   
                    output[i
+ RED]     =   0 ;   
                    output[i
+ GREEN]   =   0 ;   
                    output[i
+ BLUE]    =   0 ;   
                    output[i
+ colour]  =  (x & 1 ) ?  ptr[x >> 1 ]:ptr[(w >> 1 ) + (x >> 1 )];   
                }   
            
break ;   
    }   
   
    
return  (GP_OK);   
}   
   
#define  AD(x, y, w) ((y)*(w)*3+3*(x))    
   
int    
gp_bayer_interpolate (unsigned 
char   * image,  int  w,  int  h, BayerTile tile)   
{   
    
int  x, y, bayer;   
    
int  p0, p1, p2, p3;   
    
int  value, div ;   
   
    
switch  (tile) {   
    
default :   
    
case  BAYER_TILE_RGGB:   
    
case  BAYER_TILE_RGGB_INTERLACED:   
        p0 
=   0 ; p1  =   1 ; p2  =   2 ; p3  =   3 ;   
        
break ;   
    
case  BAYER_TILE_GRBG:   
    
case  BAYER_TILE_GRBG_INTERLACED:   
        p0 
=   1 ; p1  =   0 ; p2  =   3 ; p3  =   2 ;   
        
break ;   
    
case  BAYER_TILE_BGGR:   
    
case  BAYER_TILE_BGGR_INTERLACED:   
        p0 
=   3 ; p1  =   2 ; p2  =   1 ; p3  =   0 ;   
        
break ;   
    
case  BAYER_TILE_GBRG:   
    
case  BAYER_TILE_GBRG_INTERLACED:   
        p0 
=   2 ; p1  =   3 ; p2  =   0 ; p3  =   1 ;   
        
break ;   
    }   
   
    
for  (y  =   0 ; y  <  h; y ++ )   
        
for  (x  =   0 ; x  <  w; x ++ ) {   
            bayer 
=  (x & 1 ? 0 : 1 +  (y & 1 ? 0 : 2 );   
   
            
if  ( bayer  ==  p0 ) {   
   
                
/*  red. green lrtb, blue diagonals  */    
                image[AD(x,y,w)
+ GREEN]  =    
                    gp_bayer_accrue(image, w, h, x
- 1 , y, x + 1 , y, x, y - 1 , x, y + 1 , GREEN) ;   
   
                image[AD(x,y,w)
+ BLUE]  =    
                    gp_bayer_accrue(image, w, h, x
+ 1 , y + 1 , x - 1 , y - 1 , x - 1 , y + 1 , x + 1 , y - 1 , BLUE) ;   
   
            } 
else   if  (bayer  ==  p1) {   
   
                
/*  green. red lr, blue tb  */    
                div 
=  value  =   0 ;   
                
if  (x  <  (w  -   1 )) {   
                    value 
+=  image[AD(x + 1 ,y,w) + RED];   
                    div
++ ;   
                }   
                
if  (x) {   
                    value 
+=  image[AD(x - 1 ,y,w) + RED];   
                    div
++ ;   
                }   
                image[AD(x,y,w)
+ RED]  =  value  /  div;   
   
                div 
=  value  =   0 ;   
                
if  (y  <  (h  -   1 )) {   
                    value 
+=  image[AD(x,y + 1 ,w) + BLUE];   
                    div
++ ;   
                }   
                
if  (y) {   
                    value 
+=  image[AD(x,y - 1 ,w) + BLUE];   
                    div
++ ;   
                }   
                image[AD(x,y,w)
+ BLUE]  =  value  /  div;   
   
            } 
else   if  ( bayer  ==  p2 ) {   
   
                
/*  green. blue lr, red tb  */    
                div 
=  value  =   0 ;   
   
                
if  (x  <  (w  -   1 )) {   
                    value 
+=  image[AD(x + 1 ,y,w) + BLUE];   
                    div
++ ;   
                }   
                
if  (x) {   
                    value 
+=  image[AD(x - 1 ,y,w) + BLUE];   
                    div
++ ;   
                }   
                image[AD(x,y,w)
+ BLUE]  =  value  /  div;   
   
                div 
=  value  =   0 ;   
                
if  (y  <  (h  -   1 )) {   
                    value 
+=  image[AD(x,y + 1 ,w) + RED];   
                    div
++ ;   
                }   
                
if  (y) {   
                    value 
+=  image[AD(x,y - 1 ,w) + RED];   
                    div
++ ;   
                }   
                image[AD(x,y,w)
+ RED]  =  value  /  div;   
   
            } 
else  {   
   
                
/*  blue. green lrtb, red diagonals  */    
                image[AD(x,y,w)
+ GREEN]  =    
                    gp_bayer_accrue (image, w, h, x
- 1 , y, x + 1 , y, x, y - 1 , x, y + 1 , GREEN) ;   
   
                image[AD(x,y,w)
+ RED]  =    
                    gp_bayer_accrue (image, w, h, x
+ 1 , y + 1 , x - 1 , y - 1 , x - 1 , y + 1 , x + 1 , y - 1 , RED) ;   
            }   
        }   
   
    
return  (GP_OK);   
}   
   
static   int    
gp_bayer_accrue (unsigned 
char   * image,  int  w,  int  h,  int  x0,  int  y0,   
        
int  x1,  int  y1,  int  x2,  int  y2,  int  x3,  int  y3,  int  colour)   
{   
int  x [ 4 ] ;   
    
int  y [ 4 ] ;   
    
int  value [ 4 ] ;   
    
int  above [ 4 ] ;   
    
int  counter   ;   
    
int  sum_of_values;   
    
int  average ;   
    
int  i ;   
    x[
0 =  x0 ; x[ 1 =  x1 ; x[ 2 =  x2 ; x[ 3 =  x3 ;   
    y[
0 =  y0 ; y[ 1 =  y1 ; y[ 2 =  y2 ; y[ 3 =  y3 ;   
       
    counter 
=  sum_of_values  =   0  ;   
    
if (colour  ==  GREEN)   
    {   
        
for  (i  =   0  ; i  <   4  ; i ++ )   
        {   
if  ((x[i]  >=   0 &&  (x[i]  <  w)  &&  (y[i]  >=   0 &&  (y[i]  <  h))   
            {   
                value [i] 
=  image[AD(x[i],y[i],w)  +  colour] ;   
                counter
++ ;   
            }   
            
else    
            {   
                value [i] 
=   - 1  ;   
            }   
        }   
        
if (counter  ==   4 )   
        {      
            
int  hdiff ;   
            
int  vdiff ;   
            hdiff 
=  value [ 1 -  value [ 0 ] ;   
            hdiff 
*=  hdiff ;     /*  Make value positive by squaring  */    
            vdiff 
=  value [ 3 -  value [ 2 ] ;   
            vdiff 
*=  vdiff ;     /*  Make value positive by squaring  */    
            
if (hdiff  >   2 * vdiff)   
            {   
                
return  (value [ 3 +  value [ 2 ]) / 2  ;   
            }   
            
if (vdiff  >   2 * hdiff)   
            {   
                
return  (value [ 1 +  value [ 0 ]) / 2  ;   
            }   
        }   
    }   
       
    
/*  for blue and red  */    
    counter 
=  sum_of_values  =   0  ;   
    
for  (i  =   0  ; i  <   4  ; i ++ )   
    {   
if  ((x[i]  >=   0 &&  (x[i]  <  w)  &&  (y[i]  >=   0 &&  (y[i]  <  h))   
        {   value [i] 
=  image[AD(x[i],y[i],w)  +  colour] ;   
            sum_of_values 
+=  value [i] ;   
            counter
++  ;   
        }   
    }   
    average 
=  sum_of_values  /  counter ;   
    
if  (counter  <   4 return  average ;   
    
/*  Less than four surrounding - just take average  */    
    counter 
=   0  ;   
    
for  (i  =   0  ; i  <   4  ; i ++ )   
    {   above[i] 
=  value[i]  >  average ;   
        
if  (above[i]) counter ++  ;   
    }   
    
/*  Note: counter == 0 indicates all values the same  */    
    
if  ((counter  ==   2 ||  (counter  ==   0 ))  return  average ;   
    sum_of_values 
=   0  ;   
    
for  (i  =   0  ; i  <   4  ; i ++ )   
    {   
if  ((counter  ==   3 ==  above[i])   
        {   sum_of_values 
+=  value[i] ; }   
    }   
    
return  sum_of_values  /   3  ;   
}   
   
int    
gp_bayer_decode (unsigned 
char   * input,  int  w,  int  h, unsigned  char   * output,   
         BayerTile tile)   
{   
    gp_bayer_expand (input, w, h, output, tile);   
    gp_bayer_interpolate (output, w, h, tile);   
   
    
return  (GP_OK);   
}

 

转载于:https://www.cnblogs.com/lin1270/archive/2010/12/01/1893654.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值