edge_aware.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 * 
00004 *  Copyright (c) 2008, Willow Garage, Inc.
00005 *  All rights reserved.
00006 * 
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 * 
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 * 
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 #include "edge_aware.h"
00035 
00036 #define AVG(a,b) (((int)(a) + (int)(b)) >> 1)
00037 #define AVG3(a,b,c) (((int)(a) + (int)(b) + (int)(c)) / 3)
00038 #define AVG4(a,b,c,d) (((int)(a) + (int)(b) + (int)(c) + (int)(d)) >> 2)
00039 #define WAVG4(a,b,c,d,x,y)  ( ( ((int)(a) + (int)(b)) * (int)(x) + ((int)(c) + (int)(d)) * (int)(y) ) / ( 2 * ((int)(x) + (int(y))) ) )
00040 using namespace std;
00041 
00042 namespace image_proc {
00043 
00044 void debayerEdgeAware(const cv::Mat& bayer, cv::Mat& color)
00045 {
00046   unsigned width = bayer.cols;
00047   unsigned height = bayer.rows;
00048   unsigned rgb_line_step = color.step[0];
00049   unsigned rgb_line_skip = rgb_line_step - width * 3;
00050   int bayer_line_step = bayer.step[0];
00051   int bayer_line_step2 = bayer_line_step * 2;
00052 
00053   unsigned char* rgb_buffer = color.datastart;
00054   unsigned char* bayer_pixel = bayer.datastart;
00055   unsigned yIdx, xIdx;
00056 
00057   int dh, dv;
00058 
00059   // first two pixel values for first two lines
00060   // Bayer         0 1 2
00061   //         0     G r g
00062   // line_step     b g b
00063   // line_step2    g r g
00064 
00065   rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
00066   rgb_buffer[1] = bayer_pixel[0]; // green pixel
00067   rgb_buffer[rgb_line_step + 2] = rgb_buffer[2] = bayer_pixel[bayer_line_step]; // blue;
00068 
00069   // Bayer         0 1 2
00070   //         0     g R g
00071   // line_step     b g b
00072   // line_step2    g r g
00073   //rgb_pixel[3] = bayer_pixel[1];
00074   rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1]);
00075   rgb_buffer[rgb_line_step + 5] = rgb_buffer[5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00076 
00077   // BGBG line
00078   // Bayer         0 1 2
00079   //         0     g r g
00080   // line_step     B g b
00081   // line_step2    g r g
00082   rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00083   rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[bayer_line_step2]);
00084   //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
00085 
00086   // pixel (1, 1)  0 1 2
00087   //         0     g r g
00088   // line_step     b G b
00089   // line_step2    g r g
00090   //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
00091   rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00092   //rgb_pixel[rgb_line_step + 5] = AVG( bayer_pixel[line_step] , bayer_pixel[line_step+2] );
00093 
00094   rgb_buffer += 6;
00095   bayer_pixel += 2;
00096   // rest of the first two lines
00097   for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
00098   {
00099     // GRGR line
00100     // Bayer        -1 0 1 2
00101     //           0   r G r g
00102     //   line_step   g b g b
00103     // line_step2    r g r g
00104     rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00105     rgb_buffer[1] = bayer_pixel[0];
00106     rgb_buffer[2] = bayer_pixel[bayer_line_step + 1];
00107 
00108     // Bayer        -1 0 1 2
00109     //          0    r g R g
00110     //  line_step    g b g b
00111     // line_step2    r g r g
00112     rgb_buffer[3] = bayer_pixel[1];
00113     rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1]);
00114     rgb_buffer[rgb_line_step + 5] = rgb_buffer[5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00115 
00116     // BGBG line
00117     // Bayer         -1 0 1 2
00118     //         0      r g r g
00119     // line_step      g B g b
00120     // line_step2     r g r g
00121     rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
00122     rgb_buffer[rgb_line_step + 1] = AVG4 (bayer_pixel[0], bayer_pixel[bayer_line_step2], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00123     rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00124 
00125     // Bayer         -1 0 1 2
00126     //         0      r g r g
00127     // line_step      g b G b
00128     // line_step2     r g r g
00129     rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00130     rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00131     //rgb_pixel[rgb_line_step + 5] = AVG( bayer_pixel[line_step] , bayer_pixel[line_step+2] );
00132   }
00133 
00134   // last two pixel values for first two lines
00135   // GRGR line
00136   // Bayer        -1 0 1
00137   //           0   r G r
00138   //   line_step   g b g
00139   // line_step2    r g r
00140   rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00141   rgb_buffer[1] = bayer_pixel[0];
00142   rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = rgb_buffer[5] = rgb_buffer[2] = bayer_pixel[bayer_line_step];
00143 
00144   // Bayer        -1 0 1
00145   //          0    r g R
00146   //  line_step    g b g
00147   // line_step2    r g r
00148   rgb_buffer[3] = bayer_pixel[1];
00149   rgb_buffer[4] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
00150   //rgb_pixel[5] = bayer_pixel[line_step];
00151 
00152   // BGBG line
00153   // Bayer        -1 0 1
00154   //          0    r g r
00155   //  line_step    g B g
00156   // line_step2    r g r
00157   rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
00158   rgb_buffer[rgb_line_step + 1] = AVG4 (bayer_pixel[0], bayer_pixel[bayer_line_step2], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00159   //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
00160 
00161   // Bayer         -1 0 1
00162   //         0      r g r
00163   // line_step      g b G
00164   // line_step2     r g r
00165   rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00166   rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00167   //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
00168 
00169   bayer_pixel += bayer_line_step + 2;
00170   rgb_buffer += rgb_line_step + 6 + rgb_line_skip;
00171   // main processing
00172   for (yIdx = 2; yIdx < height - 2; yIdx += 2)
00173   {
00174     // first two pixel values
00175     // Bayer         0 1 2
00176     //        -1     b g b
00177     //         0     G r g
00178     // line_step     b g b
00179     // line_step2    g r g
00180     
00181     rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
00182     rgb_buffer[1] = bayer_pixel[0]; // green pixel
00183     rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]); // blue;
00184     
00185     // Bayer         0 1 2
00186     //        -1     b g b
00187     //         0     g R g
00188     // line_step     b g b
00189     // line_step2    g r g
00190     //rgb_pixel[3] = bayer_pixel[1];
00191     rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
00192     rgb_buffer[5] = AVG4 (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2], bayer_pixel[-bayer_line_step], bayer_pixel[2 - bayer_line_step]);
00193     
00194     // BGBG line
00195     // Bayer         0 1 2
00196     //         0     g r g
00197     // line_step     B g b
00198     // line_step2    g r g
00199     rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00200     rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[bayer_line_step2]);
00201     rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00202     
00203     // pixel (1, 1)  0 1 2
00204     //         0     g r g
00205     // line_step     b G b
00206     // line_step2    g r g
00207     //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
00208     rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00209     rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00210     
00211     rgb_buffer += 6;
00212     bayer_pixel += 2;
00213     // continue with rest of the line
00214     for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
00215     {
00216       // GRGR line
00217       // Bayer        -1 0 1 2
00218       //          -1   g b g b
00219       //           0   r G r g
00220       //   line_step   g b g b
00221       // line_step2    r g r g
00222       rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00223       rgb_buffer[1] = bayer_pixel[0];
00224       rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
00225       
00226       // Bayer        -1 0 1 2
00227       //          -1   g b g b
00228       //          0    r g R g
00229       //  line_step    g b g b
00230       // line_step2    r g r g
00231       
00232       dh = abs (bayer_pixel[0] - bayer_pixel[2]);
00233       dv = abs (bayer_pixel[-bayer_line_step + 1] - bayer_pixel[bayer_line_step + 1]);
00234       
00235       if (dh > dv)
00236         rgb_buffer[4] = AVG (bayer_pixel[-bayer_line_step + 1], bayer_pixel[bayer_line_step + 1]);
00237       else if (dv > dh)
00238         rgb_buffer[4] = AVG (bayer_pixel[0], bayer_pixel[2]);
00239       else
00240         rgb_buffer[4] = AVG4 (bayer_pixel[-bayer_line_step + 1], bayer_pixel[bayer_line_step + 1], bayer_pixel[0], bayer_pixel[2]);
00241       
00242       rgb_buffer[3] = bayer_pixel[1];
00243       rgb_buffer[5] = AVG4 (bayer_pixel[-bayer_line_step], bayer_pixel[2 - bayer_line_step], bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00244       
00245       // BGBG line
00246       // Bayer         -1 0 1 2
00247       //         -1     g b g b
00248       //          0     r g r g
00249       // line_step      g B g b
00250       // line_step2     r g r g
00251       rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
00252       rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00253       
00254       dv = abs (bayer_pixel[0] - bayer_pixel[bayer_line_step2]);
00255       dh = abs (bayer_pixel[bayer_line_step - 1] - bayer_pixel[bayer_line_step + 1]);
00256       
00257       if (dv > dh)
00258         rgb_buffer[rgb_line_step + 1] = AVG (bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00259       else if (dh > dv)
00260         rgb_buffer[rgb_line_step + 1] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step2]);
00261       else
00262         rgb_buffer[rgb_line_step + 1] = AVG4 (bayer_pixel[0], bayer_pixel[bayer_line_step2], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00263       
00264       // Bayer         -1 0 1 2
00265       //         -1     g b g b
00266       //          0     r g r g
00267       // line_step      g b G b
00268       // line_step2     r g r g
00269       rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00270       rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00271       rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00272     }
00273     
00274     // last two pixels of the line
00275     // last two pixel values for first two lines
00276     // GRGR line
00277     // Bayer        -1 0 1
00278     //           0   r G r
00279     //   line_step   g b g
00280     // line_step2    r g r
00281     rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00282     rgb_buffer[1] = bayer_pixel[0];
00283     rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = rgb_buffer[5] = rgb_buffer[2] = bayer_pixel[bayer_line_step];
00284     
00285     // Bayer        -1 0 1
00286     //          0    r g R
00287     //  line_step    g b g
00288     // line_step2    r g r
00289     rgb_buffer[3] = bayer_pixel[1];
00290     rgb_buffer[4] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
00291     //rgb_pixel[5] = bayer_pixel[line_step];
00292     
00293     // BGBG line
00294     // Bayer        -1 0 1
00295     //          0    r g r
00296     //  line_step    g B g
00297     // line_step2    r g r
00298     rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
00299     rgb_buffer[rgb_line_step + 1] = AVG4 (bayer_pixel[0], bayer_pixel[bayer_line_step2], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00300     //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
00301     
00302     // Bayer         -1 0 1
00303     //         0      r g r
00304     // line_step      g b G
00305     // line_step2     r g r
00306     rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00307     rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00308     //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
00309     
00310     bayer_pixel += bayer_line_step + 2;
00311     rgb_buffer += rgb_line_step + 6 + rgb_line_skip;
00312   }
00313   
00314   //last two lines
00315   // Bayer         0 1 2
00316   //        -1     b g b
00317   //         0     G r g
00318   // line_step     b g b
00319   
00320   rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
00321   rgb_buffer[1] = bayer_pixel[0]; // green pixel
00322   rgb_buffer[rgb_line_step + 2] = rgb_buffer[2] = bayer_pixel[bayer_line_step]; // blue;
00323   
00324   // Bayer         0 1 2
00325   //        -1     b g b
00326   //         0     g R g
00327   // line_step     b g b
00328   //rgb_pixel[3] = bayer_pixel[1];
00329   rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
00330   rgb_buffer[5] = AVG4 (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2], bayer_pixel[-bayer_line_step], bayer_pixel[2 - bayer_line_step]);
00331   
00332   // BGBG line
00333   // Bayer         0 1 2
00334   //        -1     b g b
00335   //         0     g r g
00336   // line_step     B g b
00337   //rgb_pixel[rgb_line_step    ] = bayer_pixel[1];
00338   rgb_buffer[rgb_line_step + 1] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
00339   rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00340   
00341   // Bayer         0 1 2
00342   //        -1     b g b
00343   //         0     g r g
00344   // line_step     b G b
00345   //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
00346   rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00347   rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00348   
00349   rgb_buffer += 6;
00350   bayer_pixel += 2;
00351   // rest of the last two lines
00352   for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
00353   {
00354     // GRGR line
00355     // Bayer       -1 0 1 2
00356     //        -1    g b g b
00357     //         0    r G r g
00358     // line_step    g b g b
00359     rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00360     rgb_buffer[1] = bayer_pixel[0];
00361     rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
00362     
00363     // Bayer       -1 0 1 2
00364     //        -1    g b g b
00365     //         0    r g R g
00366     // line_step    g b g b
00367     rgb_buffer[rgb_line_step + 3] = rgb_buffer[3] = bayer_pixel[1];
00368     rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
00369     rgb_buffer[5] = AVG4 (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2], bayer_pixel[-bayer_line_step], bayer_pixel[-bayer_line_step + 2]);
00370     
00371     // BGBG line
00372     // Bayer       -1 0 1 2
00373     //        -1    g b g b
00374     //         0    r g r g
00375     // line_step    g B g b
00376     rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[-1], bayer_pixel[1]);
00377     rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00378     rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00379     
00380     
00381     // Bayer       -1 0 1 2
00382     //        -1    g b g b
00383     //         0    r g r g
00384     // line_step    g b G b
00385     //rgb_pixel[rgb_line_step + 3] = bayer_pixel[1];
00386     rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00387     rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00388   }
00389   
00390   // last two pixel values for first two lines
00391   // GRGR line
00392   // Bayer       -1 0 1
00393   //        -1    g b g
00394   //         0    r G r
00395   // line_step    g b g
00396   rgb_buffer[rgb_line_step ] = rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00397   rgb_buffer[1] = bayer_pixel[0];
00398   rgb_buffer[5] = rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
00399   
00400   // Bayer       -1 0 1
00401   //        -1    g b g
00402   //         0    r g R
00403   // line_step    g b g
00404   rgb_buffer[rgb_line_step + 3] = rgb_buffer[3] = bayer_pixel[1];
00405   rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[-bayer_line_step + 1]);
00406   //rgb_pixel[5] = AVG( bayer_pixel[line_step], bayer_pixel[-line_step] );
00407   
00408   // BGBG line
00409   // Bayer       -1 0 1
00410   //        -1    g b g
00411   //         0    r g r
00412   // line_step    g B g
00413   //rgb_pixel[rgb_line_step    ] = AVG2( bayer_pixel[-1], bayer_pixel[1] );
00414   rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00415   rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00416   
00417   // Bayer       -1 0 1
00418   //        -1    g b g
00419   //         0    r g r
00420   // line_step    g b G
00421   //rgb_pixel[rgb_line_step + 3] = bayer_pixel[1];
00422   rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00423   //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
00424 }
00425 
00426 void debayerEdgeAwareWeighted(const cv::Mat& bayer, cv::Mat& color)
00427 {
00428   unsigned width = bayer.cols;
00429   unsigned height = bayer.rows;
00430   unsigned rgb_line_step = color.step[0];
00431   unsigned rgb_line_skip = rgb_line_step - width * 3;
00432   int bayer_line_step = bayer.step[0];
00433   int bayer_line_step2 = bayer_line_step * 2;
00434 
00435   unsigned char* rgb_buffer = color.datastart;
00436   unsigned char* bayer_pixel = bayer.datastart;
00437   unsigned yIdx, xIdx;
00438 
00439   int dh, dv;
00440 
00441   // first two pixel values for first two lines
00442   // Bayer         0 1 2
00443   //         0     G r g
00444   // line_step     b g b
00445   // line_step2    g r g
00446 
00447   rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
00448   rgb_buffer[1] = bayer_pixel[0]; // green pixel
00449   rgb_buffer[rgb_line_step + 2] = rgb_buffer[2] = bayer_pixel[bayer_line_step]; // blue;
00450   
00451   // Bayer         0 1 2
00452   //         0     g R g
00453   // line_step     b g b
00454   // line_step2    g r g
00455   //rgb_pixel[3] = bayer_pixel[1];
00456   rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1]);
00457   rgb_buffer[rgb_line_step + 5] = rgb_buffer[5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00458   
00459   // BGBG line
00460   // Bayer         0 1 2
00461   //         0     g r g
00462   // line_step     B g b
00463   // line_step2    g r g
00464   rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00465   rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[bayer_line_step2]);
00466   //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
00467   
00468   // pixel (1, 1)  0 1 2
00469   //         0     g r g
00470   // line_step     b G b
00471   // line_step2    g r g
00472   //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
00473   rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00474   //rgb_pixel[rgb_line_step + 5] = AVG( bayer_pixel[line_step] , bayer_pixel[line_step+2] );
00475   
00476   rgb_buffer += 6;
00477   bayer_pixel += 2;
00478   // rest of the first two lines
00479   for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
00480   {
00481     // GRGR line
00482     // Bayer        -1 0 1 2
00483     //           0   r G r g
00484     //   line_step   g b g b
00485     // line_step2    r g r g
00486     rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00487     rgb_buffer[1] = bayer_pixel[0];
00488     rgb_buffer[2] = bayer_pixel[bayer_line_step + 1];
00489     
00490     // Bayer        -1 0 1 2
00491     //          0    r g R g
00492     //  line_step    g b g b
00493     // line_step2    r g r g
00494     rgb_buffer[3] = bayer_pixel[1];
00495     rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1]);
00496     rgb_buffer[rgb_line_step + 5] = rgb_buffer[5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00497     
00498     // BGBG line
00499     // Bayer         -1 0 1 2
00500     //         0      r g r g
00501     // line_step      g B g b
00502     // line_step2     r g r g
00503     rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
00504     rgb_buffer[rgb_line_step + 1] = AVG4 (bayer_pixel[0], bayer_pixel[bayer_line_step2], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00505     rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00506     
00507     // Bayer         -1 0 1 2
00508     //         0      r g r g
00509     // line_step      g b G b
00510     // line_step2     r g r g
00511     rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00512     rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00513     //rgb_pixel[rgb_line_step + 5] = AVG( bayer_pixel[line_step] , bayer_pixel[line_step+2] );
00514   }
00515   
00516   // last two pixel values for first two lines
00517   // GRGR line
00518   // Bayer        -1 0 1
00519   //           0   r G r
00520   //   line_step   g b g
00521   // line_step2    r g r
00522   rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00523   rgb_buffer[1] = bayer_pixel[0];
00524   rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = rgb_buffer[5] = rgb_buffer[2] = bayer_pixel[bayer_line_step];
00525   
00526   // Bayer        -1 0 1
00527   //          0    r g R
00528   //  line_step    g b g
00529   // line_step2    r g r
00530   rgb_buffer[3] = bayer_pixel[1];
00531   rgb_buffer[4] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
00532   //rgb_pixel[5] = bayer_pixel[line_step];
00533   
00534   // BGBG line
00535   // Bayer        -1 0 1
00536   //          0    r g r
00537   //  line_step    g B g
00538   // line_step2    r g r
00539   rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
00540   rgb_buffer[rgb_line_step + 1] = AVG4 (bayer_pixel[0], bayer_pixel[bayer_line_step2], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00541   //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
00542   
00543   // Bayer         -1 0 1
00544   //         0      r g r
00545   // line_step      g b G
00546   // line_step2     r g r
00547   rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00548   rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00549   //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
00550   
00551   bayer_pixel += bayer_line_step + 2;
00552   rgb_buffer += rgb_line_step + 6 + rgb_line_skip;
00553   // main processing
00554   for (yIdx = 2; yIdx < height - 2; yIdx += 2)
00555   {
00556     // first two pixel values
00557     // Bayer         0 1 2
00558     //        -1     b g b
00559     //         0     G r g
00560     // line_step     b g b
00561     // line_step2    g r g
00562     
00563     rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
00564     rgb_buffer[1] = bayer_pixel[0]; // green pixel
00565     rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]); // blue;
00566     
00567     // Bayer         0 1 2
00568     //        -1     b g b
00569     //         0     g R g
00570     // line_step     b g b
00571     // line_step2    g r g
00572     //rgb_pixel[3] = bayer_pixel[1];
00573     rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
00574     rgb_buffer[5] = AVG4 (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2], bayer_pixel[-bayer_line_step], bayer_pixel[2 - bayer_line_step]);
00575     
00576     // BGBG line
00577     // Bayer         0 1 2
00578     //         0     g r g
00579     // line_step     B g b
00580     // line_step2    g r g
00581     rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00582     rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[bayer_line_step2]);
00583     rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00584     
00585     // pixel (1, 1)  0 1 2
00586     //         0     g r g
00587     // line_step     b G b
00588     // line_step2    g r g
00589     //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
00590     rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00591     rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00592     
00593     rgb_buffer += 6;
00594     bayer_pixel += 2;
00595     // continue with rest of the line
00596     for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
00597     {
00598       // GRGR line
00599       // Bayer        -1 0 1 2
00600       //          -1   g b g b
00601       //           0   r G r g
00602       //   line_step   g b g b
00603       // line_step2    r g r g
00604       rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00605       rgb_buffer[1] = bayer_pixel[0];
00606       rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
00607       
00608       // Bayer        -1 0 1 2
00609       //          -1   g b g b
00610       //          0    r g R g
00611       //  line_step    g b g b
00612       // line_step2    r g r g
00613       
00614       dh = abs (bayer_pixel[0] - bayer_pixel[2]);
00615       dv = abs (bayer_pixel[-bayer_line_step + 1] - bayer_pixel[bayer_line_step + 1]);
00616       
00617       if (dv == 0 && dh == 0)
00618         rgb_buffer[4] = AVG4 (bayer_pixel[1 - bayer_line_step], bayer_pixel[1 + bayer_line_step], bayer_pixel[0], bayer_pixel[2]);
00619       else
00620         rgb_buffer[4] = WAVG4 (bayer_pixel[1 - bayer_line_step], bayer_pixel[1 + bayer_line_step], bayer_pixel[0], bayer_pixel[2], dh, dv);
00621       rgb_buffer[3] = bayer_pixel[1];
00622       rgb_buffer[5] = AVG4 (bayer_pixel[-bayer_line_step], bayer_pixel[2 - bayer_line_step], bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00623       
00624       // BGBG line
00625       // Bayer         -1 0 1 2
00626       //         -1     g b g b
00627       //          0     r g r g
00628       // line_step      g B g b
00629       // line_step2     r g r g
00630       rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
00631       rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00632       
00633       dv = abs (bayer_pixel[0] - bayer_pixel[bayer_line_step2]);
00634       dh = abs (bayer_pixel[bayer_line_step - 1] - bayer_pixel[bayer_line_step + 1]);
00635       
00636       if (dv == 0 && dh == 0)
00637         rgb_buffer[rgb_line_step + 1] = AVG4 (bayer_pixel[0], bayer_pixel[bayer_line_step2], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00638       else
00639         rgb_buffer[rgb_line_step + 1] = WAVG4 (bayer_pixel[0], bayer_pixel[bayer_line_step2], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1], dh, dv);
00640       
00641       // Bayer         -1 0 1 2
00642       //         -1     g b g b
00643       //          0     r g r g
00644       // line_step      g b G b
00645       // line_step2     r g r g
00646       rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00647       rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00648       rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00649     }
00650     
00651     // last two pixels of the line
00652     // last two pixel values for first two lines
00653     // GRGR line
00654     // Bayer        -1 0 1
00655     //           0   r G r
00656     //   line_step   g b g
00657     // line_step2    r g r
00658     rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00659     rgb_buffer[1] = bayer_pixel[0];
00660     rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = rgb_buffer[5] = rgb_buffer[2] = bayer_pixel[bayer_line_step];
00661     
00662     // Bayer        -1 0 1
00663     //          0    r g R
00664     //  line_step    g b g
00665     // line_step2    r g r
00666     rgb_buffer[3] = bayer_pixel[1];
00667     rgb_buffer[4] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
00668     //rgb_pixel[5] = bayer_pixel[line_step];
00669     
00670     // BGBG line
00671     // Bayer        -1 0 1
00672     //          0    r g r
00673     //  line_step    g B g
00674     // line_step2    r g r
00675     rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
00676     rgb_buffer[rgb_line_step + 1] = AVG4 (bayer_pixel[0], bayer_pixel[bayer_line_step2], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00677     //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
00678     
00679     // Bayer         -1 0 1
00680     //         0      r g r
00681     // line_step      g b G
00682     // line_step2     r g r
00683     rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
00684     rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00685     //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
00686     
00687     bayer_pixel += bayer_line_step + 2;
00688     rgb_buffer += rgb_line_step + 6 + rgb_line_skip;
00689   }
00690   
00691   //last two lines
00692   // Bayer         0 1 2
00693   //        -1     b g b
00694   //         0     G r g
00695   // line_step     b g b
00696   
00697   rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
00698   rgb_buffer[1] = bayer_pixel[0]; // green pixel
00699   rgb_buffer[rgb_line_step + 2] = rgb_buffer[2] = bayer_pixel[bayer_line_step]; // blue;
00700   
00701   // Bayer         0 1 2
00702   //        -1     b g b
00703   //         0     g R g
00704   // line_step     b g b
00705   //rgb_pixel[3] = bayer_pixel[1];
00706   rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
00707   rgb_buffer[5] = AVG4 (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2], bayer_pixel[-bayer_line_step], bayer_pixel[2 - bayer_line_step]);
00708   
00709   // BGBG line
00710   // Bayer         0 1 2
00711   //        -1     b g b
00712   //         0     g r g
00713   // line_step     B g b
00714   //rgb_pixel[rgb_line_step    ] = bayer_pixel[1];
00715   rgb_buffer[rgb_line_step + 1] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
00716   rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00717 
00718   // Bayer         0 1 2
00719   //        -1     b g b
00720   //         0     g r g
00721   // line_step     b G b
00722   //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
00723   rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00724   rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00725   
00726   rgb_buffer += 6;
00727   bayer_pixel += 2;
00728   // rest of the last two lines
00729   for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
00730   {
00731     // GRGR line
00732     // Bayer       -1 0 1 2
00733     //        -1    g b g b
00734     //         0    r G r g
00735     // line_step    g b g b
00736     rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00737     rgb_buffer[1] = bayer_pixel[0];
00738     rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
00739     
00740     // Bayer       -1 0 1 2
00741     //        -1    g b g b
00742     //         0    r g R g
00743     // line_step    g b g b
00744     rgb_buffer[rgb_line_step + 3] = rgb_buffer[3] = bayer_pixel[1];
00745     rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
00746     rgb_buffer[5] = AVG4 (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2], bayer_pixel[-bayer_line_step], bayer_pixel[-bayer_line_step + 2]);
00747 
00748     // BGBG line
00749     // Bayer       -1 0 1 2
00750     //        -1    g b g b
00751     //         0    r g r g
00752     // line_step    g B g b
00753     rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[-1], bayer_pixel[1]);
00754     rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00755     rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00756     
00757     
00758     // Bayer       -1 0 1 2
00759     //        -1    g b g b
00760     //         0    r g r g
00761     // line_step    g b G b
00762     //rgb_pixel[rgb_line_step + 3] = bayer_pixel[1];
00763     rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00764     rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
00765   }
00766   
00767   // last two pixel values for first two lines
00768   // GRGR line
00769   // Bayer       -1 0 1
00770   //        -1    g b g
00771   //         0    r G r
00772   // line_step    g b g
00773   rgb_buffer[rgb_line_step ] = rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
00774   rgb_buffer[1] = bayer_pixel[0];
00775   rgb_buffer[5] = rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
00776   
00777   // Bayer       -1 0 1
00778   //        -1    g b g
00779   //         0    r g R
00780   // line_step    g b g
00781   rgb_buffer[rgb_line_step + 3] = rgb_buffer[3] = bayer_pixel[1];
00782   rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[-bayer_line_step + 1]);
00783   //rgb_pixel[5] = AVG( bayer_pixel[line_step], bayer_pixel[-line_step] );
00784   
00785   // BGBG line
00786   // Bayer       -1 0 1
00787   //        -1    g b g
00788   //         0    r g r
00789   // line_step    g B g
00790   //rgb_pixel[rgb_line_step    ] = AVG2( bayer_pixel[-1], bayer_pixel[1] );
00791   rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
00792   rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
00793   
00794   // Bayer       -1 0 1
00795   //        -1    g b g
00796   //         0    r g r
00797   // line_step    g b G
00798   //rgb_pixel[rgb_line_step + 3] = bayer_pixel[1];
00799   rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
00800   //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
00801 
00802 }
00803 
00804 } // namespace image_proc


image_proc
Author(s): Patrick Mihelich, Kurt Konolige, Jeremy Leibs
autogenerated on Wed Aug 26 2015 11:57:28