zoukankan      html  css  js  c++  java
  • Bayer转换算法[转]

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

    /* 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= {   
        {
    0112},   
        {
    1021},   
        {
    2110},   
        {
    1201},   
        {
    0112},   
        {
    1021},   
        {
    2110},   
        {
    1201}};   
       
    #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 < 4return 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);   
    }
  • 相关阅读:
    python-web微信实现
    Python---BeautifulSoup模块
    Python—requests模块详解
    KindEditor编辑器
    Django实现瀑布流,组合搜索
    利用(CMD)在Django中创建文件
    ppt插入声音
    高性能mysql 第1,2,3章。
    mysql复制
    最长DNA重复序列长度,并输出该序列。 JAVA
  • 原文地址:https://www.cnblogs.com/lin1270/p/1893654.html
Copyright © 2011-2022 走看看