00001 /*!@file Raster/DebayerREG.C is the debayer class without use sse */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Zhicheng Li <zhicheng@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Raster/DeBayerREG.C $ 00035 // $Id: DeBayerREG.C 10794 2009-02-08 06:21:09Z itti $ 00036 // 00037 #include "Raster/DeBayerREG.H" 00038 #include "Component/ModelManager.H" 00039 #include "Image/Image.H" 00040 #include "Image/Pixels.H" 00041 #include "Raster/Raster.H" 00042 #include "Util/StringUtil.H" 00043 #include "Util/FileUtil.H" 00044 00045 template <class T> Image<PixRGB<T> > 00046 debayerREG (Image<T> src, 00047 BayerFormat format) 00048 { 00049 int w = src.getWidth(); 00050 int h = src.getHeight(); 00051 ASSERT(w % 2 == 0); 00052 ASSERT(h % 2 == 0); 00053 00054 Image<PixRGB<float> > res(src.getDims(), NO_INIT); 00055 Image<float> srcF = src; 00056 Image<float>::const_iterator sptr = srcF.begin(); 00057 Image<PixRGB<float> >::iterator dptr = res.beginw(); 00058 00059 if(format == BAYER_GBRG || format == BAYER_GBRG12) 00060 for (int y = 0; y < h; y += 2){ 00061 for (int x = 0; x < w; x += 2){ 00062 if (x < 2 || x >= w-2 || y < 2 || y >= h-2) 00063 { 00064 const float r = sptr[w]; 00065 const float g = 0.5f * (sptr[0] + sptr[w+1]); 00066 const float b = sptr[1]; 00067 00068 dptr[0].p[0] = r; 00069 dptr[1].p[0] = r; 00070 dptr[w].p[0] = r; 00071 dptr[w+1].p[0] = r; 00072 00073 dptr[0].p[1] = g; 00074 dptr[1].p[1] = g; 00075 dptr[w].p[1] = g; 00076 dptr[w+1].p[1] = g; 00077 00078 dptr[0].p[2] = b; 00079 dptr[1].p[2] = b; 00080 dptr[w].p[2] = b; 00081 dptr[w+1].p[2] = b; 00082 } 00083 else 00084 { 00085 /* 00086 +------+------+------+------+ 00087 :-w-1 :-w :-w+1 :-w+2 : 00088 : : : : : 00089 : G : R : G : R : 00090 +------+======+======+------+ 00091 :-1 |0 |1 |2 : 00092 : | | | : 00093 : B | G | B | G : 00094 +------+======+======+------+ 00095 :w-1 |w |w+1 |w+2 : 00096 : | | | : 00097 : G | R | G | R : 00098 +------+======+======+------+ 00099 :w*2-1 :w*2 :w*2+1 :w*2+2 : 00100 : : : : : 00101 : B : G : B : G : 00102 +------+------+------+------+ 00103 */ 00104 00105 dptr[0].p[0] = 0.5f * (sptr[-w] + sptr[w]); 00106 dptr[1].p[0] = 0.25f * (sptr[-w] + sptr[-w+2] + sptr[w] + sptr[w+2]); 00107 dptr[w].p[0] = sptr[w]; 00108 dptr[w+1].p[0] = 0.5f * (sptr[w] + sptr[w+2]); 00109 00110 dptr[0].p[1] = 0.5f * sptr[0] + 0.125f * (sptr[-w-1] + sptr[-w+1] + sptr[w-1] + sptr[w+1]); 00111 dptr[1].p[1] = 0.25f * (sptr[-w+1] + sptr[0] + sptr[2] + sptr[w+1]); 00112 dptr[w].p[1] = 0.25f * (sptr[0] + sptr[w-1] + sptr[w+1] + sptr[w*2]); 00113 dptr[w+1].p[1] = 0.5f * sptr[w+1] + 0.125f * (sptr[0] + sptr[2] + sptr[w*2] + sptr[w*2+2]); 00114 00115 dptr[0].p[2] = 0.5f * (sptr[-1] + sptr[1]); 00116 dptr[1].p[2] = sptr[1]; 00117 dptr[w].p[2] = 0.25f * (sptr[-1] + sptr[1] + sptr[w*2-1] + sptr[w*2+1]); 00118 dptr[w+1].p[2] = 0.5f * (sptr[1] + sptr[w*2+1]); 00119 } 00120 00121 sptr += 2; 00122 dptr += 2; 00123 } 00124 00125 sptr += w; 00126 dptr += w; 00127 } 00128 00129 // case BAYER_GRBG: 00130 else if(format == BAYER_GRBG || format == BAYER_GRBG12) 00131 for (int y = 0; y < h; y += 2){ 00132 for (int x = 0; x < w; x += 2){ 00133 if (x < 2 || x >= w-2 || y < 2 || y >= h-2) 00134 { 00135 const float r = sptr[1]; 00136 const float g = 0.5f * (sptr[0] + sptr[w+1]); 00137 const float b = sptr[w]; 00138 00139 dptr[0].p[0] = r; 00140 dptr[1].p[0] = r; 00141 dptr[w].p[0] = r; 00142 dptr[w+1].p[0] = r; 00143 00144 dptr[0].p[1] = g; 00145 dptr[1].p[1] = g; 00146 dptr[w].p[1] = g; 00147 dptr[w+1].p[1] = g; 00148 00149 dptr[0].p[2] = b; 00150 dptr[1].p[2] = b; 00151 dptr[w].p[2] = b; 00152 dptr[w+1].p[2] = b; 00153 } 00154 else 00155 { 00156 /* 00157 +------+------+------+------+ 00158 :-w-1 :-w :-w+1 :-w+2 : 00159 : : : : : 00160 : G : B : G : B : 00161 +------+======+======+------+ 00162 :-1 |0 |1 |2 : 00163 : | | | : 00164 : R | G | R | G : 00165 +------+======+======+------+ 00166 :w-1 |w |w+1 |w+2 : 00167 : | | | : 00168 : G | B | G | B : 00169 +------+======+======+------+ 00170 :w*2-1 :w*2 :w*2+1 :w*2+2 : 00171 : : : : : 00172 : R : G : R : G : 00173 +------+------+------+------+ 00174 */ 00175 00176 dptr[0].p[0] = 0.5f * (sptr[-1] + sptr[1]); 00177 dptr[1].p[0] = sptr[1]; 00178 dptr[w].p[0] = 0.25f * (sptr[-1] + sptr[1] + sptr[w*2-1] + sptr[w*2+1]); 00179 dptr[w+1].p[0] = 0.5f * (sptr[1] + sptr[w*2+1]); 00180 00181 dptr[0].p[1] = 0.5f * sptr[0] + 0.125f * (sptr[-w-1] + sptr[-w+1] + sptr[w-1] + sptr[w+1]); 00182 dptr[1].p[1] = 0.25f * (sptr[-w+1] + sptr[0] + sptr[2] + sptr[w+1]); 00183 dptr[w].p[1] = 0.25f * (sptr[0] + sptr[w-1] + sptr[w+1] + sptr[w*2]); 00184 dptr[w+1].p[1] = 0.5f * sptr[w+1] + 0.125f * (sptr[0] + sptr[2] + sptr[w*2] + sptr[w*2+2]); 00185 00186 dptr[0].p[2] = 0.5f * (sptr[-w] + sptr[w]); 00187 dptr[1].p[2] = 0.25f * (sptr[-w] + sptr[-w+2] + sptr[w] + sptr[w+2]); 00188 dptr[w].p[2] = sptr[w]; 00189 dptr[w+1].p[2] = 0.5f * (sptr[w] + sptr[w+2]); 00190 } 00191 00192 sptr += 2; 00193 dptr += 2; 00194 } 00195 00196 sptr += w; 00197 dptr += w; 00198 } 00199 00200 00201 //case BAYER_RGGB: 00202 else if(format == BAYER_RGGB || format == BAYER_RGGB12) 00203 for (int y = 0; y < h; y += 2){ 00204 for (int x = 0; x < w; x += 2){ 00205 if (x < 2 || x >= w-2 || y < 2 || y >= h-2) 00206 { 00207 const float r = sptr[0]; 00208 const float g = 0.5f * (sptr[1] + sptr[w]); 00209 const float b = sptr[w+1]; 00210 00211 dptr[0].p[0] = r; 00212 dptr[1].p[0] = r; 00213 dptr[w].p[0] = r; 00214 dptr[w+1].p[0] = r; 00215 00216 dptr[0].p[1] = g; 00217 dptr[1].p[1] = g; 00218 dptr[w].p[1] = g; 00219 dptr[w+1].p[1] = g; 00220 00221 dptr[0].p[2] = b; 00222 dptr[1].p[2] = b; 00223 dptr[w].p[2] = b; 00224 dptr[w+1].p[2] = b; 00225 } 00226 else 00227 { 00228 /* 00229 +------+------+------+------+ 00230 :-w-1 :-w :-w+1 :-w+2 : 00231 : : : : : 00232 : B : G : B : G : 00233 +------+======+======+------+ 00234 :-1 |0 |1 |2 : 00235 : | | | : 00236 : G | R | G | R : 00237 +------+======+======+------+ 00238 :w-1 |w |w+1 |w+2 : 00239 : | | | : 00240 : B | G | B | G : 00241 +------+======+======+------+ 00242 :w*2-1 :w*2 :w*2+1 :w*2+2 : 00243 : : : : : 00244 : G : R : G : R : 00245 +------+------+------+------+ 00246 */ 00247 00248 dptr[0].p[0] = sptr[0]; 00249 dptr[1].p[0] = 0.5f * (sptr[0] + sptr[2]); 00250 dptr[w].p[0] = 0.5f * (sptr[0] + sptr[w*2]); 00251 dptr[w+1].p[0] = 0.25f * (sptr[0] + sptr[2] + sptr[w*2] + sptr[w*2+2]); 00252 00253 dptr[0].p[1] = 0.25f * (sptr[-w] + sptr[-1] + sptr[1] + sptr[w]); 00254 dptr[1].p[1] = 0.5f * sptr[1] + 0.125f * (sptr[-w] + sptr[-w+2] + sptr[w] + sptr[w+2]); 00255 dptr[w].p[1] = 0.5f * sptr[w] + 0.125f * (sptr[-1] + sptr[1] + sptr[w*2-1] + sptr[w*2+1]); 00256 dptr[w+1].p[1] = 0.25f * (sptr[1] + sptr[w] + sptr[w+2] + sptr[w*2+1]); 00257 00258 dptr[0].p[2] = 0.25f * (sptr[-w-1] + sptr[-w+1] + sptr[w-1] + sptr[w+1]); 00259 dptr[1].p[2] = 0.5f * (sptr[-w+1] + sptr[w+1]); 00260 dptr[w].p[2] = 0.5f * (sptr[w-1] + sptr[w+1]); 00261 dptr[w+1].p[2] = sptr[w+1]; 00262 } 00263 00264 sptr += 2; 00265 dptr += 2; 00266 } 00267 00268 sptr += w; 00269 dptr += w; 00270 } 00271 00272 //case BAYER_BGGR: 00273 else if(format == BAYER_BGGR || format == BAYER_BGGR) 00274 for (int y = 0; y < h; y += 2){ 00275 for (int x = 0; x < w; x += 2){ 00276 if (x < 2 || x >= w-2 || y < 2 || y >= h-2) 00277 { 00278 const float r = sptr[w+1]; 00279 const float g = 0.5f * (sptr[1] + sptr[w]); 00280 const float b = sptr[0]; 00281 00282 dptr[0].p[0] = r; 00283 dptr[1].p[0] = r; 00284 dptr[w].p[0] = r; 00285 dptr[w+1].p[0] = r; 00286 00287 dptr[0].p[1] = g; 00288 dptr[1].p[1] = g; 00289 dptr[w].p[1] = g; 00290 dptr[w+1].p[1] = g; 00291 00292 dptr[0].p[2] = b; 00293 dptr[1].p[2] = b; 00294 dptr[w].p[2] = b; 00295 dptr[w+1].p[2] = b; 00296 } 00297 else 00298 { 00299 /* 00300 +------+------+------+------+ 00301 :-w-1 :-w :-w+1 :-w+2 : 00302 : : : : : 00303 : R : G : R : G : 00304 +------+======+======+------+ 00305 :-1 |0 |1 |2 : 00306 : | | | : 00307 : G | B | G | B : 00308 +------+======+======+------+ 00309 :w-1 |w |w+1 |w+2 : 00310 : | | | : 00311 : R | G | R | G : 00312 +------+======+======+------+ 00313 :w*2-1 :w*2 :w*2+1 :w*2+2 : 00314 : : : : : 00315 : G : B : G : B : 00316 +------+------+------+------+ 00317 */ 00318 00319 dptr[0].p[0] = 0.25f * (sptr[-w-1] + sptr[-w+1] + sptr[w-1] + sptr[w+1]); 00320 dptr[1].p[0] = 0.5f * (sptr[-w+1] + sptr[w+1]); 00321 dptr[w].p[0] = 0.5f * (sptr[w-1] + sptr[w+1]); 00322 dptr[w+1].p[0] = sptr[w+1]; 00323 00324 dptr[0].p[1] = 0.25f * (sptr[-w] + sptr[-1] + sptr[1] + sptr[w]); 00325 dptr[1].p[1] = 0.5f * sptr[1] + 0.125f * (sptr[-w] + sptr[-w+2] + sptr[w] + sptr[w+2]); 00326 dptr[w].p[1] = 0.5f * sptr[w] + 0.125f * (sptr[-1] + sptr[1] + sptr[w*2-1] + sptr[w*2+1]); 00327 dptr[w+1].p[1] = 0.25f * (sptr[1] + sptr[w] + sptr[w+2] + sptr[w*2+1]); 00328 00329 dptr[0].p[2] = sptr[0]; 00330 dptr[1].p[2] = 0.5f * (sptr[0] + sptr[2]); 00331 dptr[w].p[2] = 0.5f * (sptr[0] + sptr[w*2]); 00332 dptr[w+1].p[2] = 0.25f * (sptr[0] + sptr[2] + sptr[w*2] + sptr[w*2+2]); 00333 } 00334 00335 sptr += 2; 00336 dptr += 2; 00337 } 00338 00339 sptr += w; 00340 dptr += w; 00341 } 00342 else 00343 { 00344 LFATAL("error in bayer format math"); 00345 } 00346 00347 return res; 00348 } 00349 00350 template Image<PixRGB<byte> > debayerREG(Image<byte> src, BayerFormat format); 00351 template Image<PixRGB<uint16> > debayerREG (Image<uint16> src, BayerFormat format); 00352 00353 /* So things look consistent in everyone's emacs... */ 00354 /* Local Variables: */ 00355 /* indent-tabs-mode: nil */ 00356 /* End: */