Malvar-He-Cutler Linear Image Demosaicking
|
00001 00016 #include "dmbilinear.h" 00017 00018 00026 void CfaFlatten(float *Flat, const float *Input, int Width, int Height, 00027 int RedX, int RedY) 00028 { 00029 const float *InputRed = Input; 00030 const float *InputGreen = Input + Width*Height; 00031 const float *InputBlue = Input + 2*Width*Height; 00032 const int Green = 1 - ((RedX + RedY) & 1); 00033 int i, x, y; 00034 00035 00036 for(y = 0, i = 0; y < Height; y++) 00037 for(x = 0; x < Width; x++, i++) 00038 { 00039 if(((x + y) & 1) == Green) 00040 Flat[i] = InputGreen[i]; 00041 else if((y & 1) == RedY) 00042 Flat[i] = InputRed[i]; 00043 else 00044 Flat[i] = InputBlue[i]; 00045 } 00046 } 00047 00048 00056 void BilinearDifference(float *Output, const float *Diff, 00057 int Width, int Height, int RedX, int RedY) 00058 { 00059 const int NumPixels = Width*Height; 00060 const int Green = 1 - ((RedX + RedY) & 1); 00061 float *OutputRed = Output; 00062 float *OutputGreen = Output + NumPixels; 00063 float *OutputBlue = Output + 2*NumPixels; 00064 float AverageH, AverageV, AverageX; 00065 int x, y, i; 00066 00067 00068 for(y = 0, i = 0; y < Height; y++) 00069 { 00070 for(x = 0; x < Width; x++, i++) 00071 { 00072 if(y == 0) 00073 { 00074 AverageV = Diff[i + Width]; 00075 00076 if(x == 0) 00077 { 00078 AverageH = Diff[i + 1]; 00079 AverageX = Diff[i + 1 + Width]; 00080 } 00081 else if(x < Width - 1) 00082 { 00083 AverageH = (Diff[i - 1] + Diff[i + 1]) / 2; 00084 AverageX = (Diff[i - 1 + Width] + Diff[i + 1 + Width]) / 2; 00085 } 00086 else 00087 { 00088 AverageH = Diff[i - 1]; 00089 AverageX = Diff[i - 1 + Width]; 00090 } 00091 00092 } 00093 else if(y < Height - 1) 00094 { 00095 AverageV = (Diff[i - Width] + Diff[i + Width]) / 2; 00096 00097 if(x == 0) 00098 { 00099 AverageH = Diff[i + 1]; 00100 AverageX = (Diff[i + 1 - Width] + Diff[i + 1 + Width]) / 2; 00101 } 00102 else if(x < Width - 1) 00103 { 00104 AverageH = (Diff[i - 1] + Diff[i + 1]) / 2; 00105 AverageX = (Diff[i - 1 - Width] + Diff[i + 1 - Width] 00106 + Diff[i - 1 + Width] + Diff[i + 1 + Width]) / 4; 00107 } 00108 else 00109 { 00110 AverageH = Diff[i - 1]; 00111 AverageX = (Diff[i - 1 - Width] + Diff[i - 1 + Width]) / 2; 00112 } 00113 } 00114 else 00115 { 00116 AverageV = Diff[i - Width]; 00117 00118 if(x == 0) 00119 { 00120 AverageH = Diff[i + 1]; 00121 AverageX = Diff[i + 1 - Width]; 00122 } 00123 else if(x < Width - 1) 00124 { 00125 AverageH = (Diff[i - 1] + Diff[i + 1]) / 2; 00126 AverageX = (Diff[i - 1 - Width] + Diff[i + 1 - Width]) / 2; 00127 } 00128 else 00129 { 00130 AverageH = Diff[i - 1]; 00131 AverageX = Diff[i - 1 - Width]; 00132 } 00133 } 00134 00135 if(((x + y) & 1) == Green) 00136 { 00137 if((y & 1) == RedY) 00138 { 00139 /* Left and right neighbors are red */ 00140 OutputRed[i] = OutputGreen[i] + AverageH; 00141 OutputBlue[i] = OutputGreen[i] + AverageV; 00142 } 00143 else 00144 { 00145 /* Left and right neighbors are blue */ 00146 OutputRed[i] = OutputGreen[i] + AverageV; 00147 OutputBlue[i] = OutputGreen[i] + AverageH; 00148 } 00149 } 00150 else 00151 { 00152 if((y & 1) == RedY) 00153 { 00154 /* Center pixel is red */ 00155 OutputRed[i] = OutputGreen[i] + Diff[i]; 00156 OutputBlue[i] = OutputGreen[i] + AverageX; 00157 } 00158 else 00159 { 00160 /* Center pixel is blue */ 00161 OutputRed[i] = OutputGreen[i] + AverageX; 00162 OutputBlue[i] = OutputGreen[i] + Diff[i]; 00163 } 00164 } 00165 } 00166 } 00167 } 00168 00169 00184 void BilinearDemosaic(float *Output, const float *Input, int Width, int Height, 00185 int RedX, int RedY) 00186 { 00187 float *OutputRed = Output; 00188 float *OutputGreen = Output + Width*Height; 00189 float *OutputBlue = Output + 2*Width*Height; 00190 const int Green = 1 - ((RedX + RedY) & 1); 00191 float AverageH, AverageV, AverageC, AverageX; 00192 int i, x, y; 00193 00194 00195 for(y = 0, i = 0; y < Height; y++) 00196 { 00197 for(x = 0; x < Width; x++, i++) 00198 { 00199 if(y == 0) 00200 { 00201 AverageV = Input[i + Width]; 00202 00203 if(x == 0) 00204 { 00205 AverageH = Input[i + 1]; 00206 AverageC = (Input[i + 1] + Input[i + Width])/2; 00207 AverageX = Input[i + 1 + Width]; 00208 } 00209 else if(x < Width - 1) 00210 { 00211 AverageH = (Input[i - 1] + Input[i + 1]) / 2; 00212 AverageC = (Input[i - 1] + Input[i + 1] 00213 + Input[i + Width])/3; 00214 AverageX = (Input[i - 1 + Width] 00215 + Input[i + 1 + Width]) / 2; 00216 } 00217 else 00218 { 00219 AverageH = Input[i - 1]; 00220 AverageC = (Input[i - 1] + Input[i + Width])/2; 00221 AverageX = Input[i - 1 + Width]; 00222 } 00223 } 00224 else if(y < Height - 1) 00225 { 00226 AverageV = (Input[i - Width] + Input[i + Width]) / 2; 00227 00228 if(x == 0) 00229 { 00230 AverageH = Input[i + 1]; 00231 AverageC = (Input[i + 1] + 00232 Input[i - Width] + Input[i + Width]) / 3; 00233 AverageX = (Input[i + 1 - Width] 00234 + Input[i + 1 + Width]) / 2; 00235 } 00236 else if(x < Width - 1) 00237 { 00238 AverageH = (Input[i - 1] + Input[i + 1]) / 2; 00239 AverageC = (AverageH + AverageV) / 2; 00240 AverageX = (Input[i - 1 - Width] + Input[i + 1 - Width] 00241 + Input[i - 1 + Width] + Input[i + 1 + Width]) / 4; 00242 } 00243 else 00244 { 00245 AverageH = Input[i - 1]; 00246 AverageC = (Input[i - 1] + 00247 Input[i - Width] + Input[i + Width]) / 3; 00248 AverageX = (Input[i - 1 - Width] 00249 + Input[i - 1 + Width]) / 2; 00250 } 00251 } 00252 else 00253 { 00254 AverageV = Input[i - Width]; 00255 00256 if(x == 0) 00257 { 00258 AverageH = Input[i + 1]; 00259 AverageC = (Input[i + 1] + Input[i - Width]) / 2; 00260 AverageX = Input[i + 1 - Width]; 00261 } 00262 else if(x < Width - 1) 00263 { 00264 AverageH = (Input[i - 1] + Input[i + 1]) / 2; 00265 AverageC = (Input[i - 1] 00266 + Input[i + 1] + Input[i - Width]) / 3; 00267 AverageX = (Input[i - 1 - Width] 00268 + Input[i + 1 - Width]) / 2; 00269 } 00270 else 00271 { 00272 AverageH = Input[i - 1]; 00273 AverageC = (Input[i - 1] + Input[i - Width]) / 2; 00274 AverageX = Input[i - 1 - Width]; 00275 } 00276 } 00277 00278 if(((x + y) & 1) == Green) 00279 { 00280 /* Center pixel is green */ 00281 OutputGreen[i] = Input[i]; 00282 00283 if((y & 1) == RedY) 00284 { 00285 /* Left and right neighbors are red */ 00286 OutputRed[i] = AverageH; 00287 OutputBlue[i] = AverageV; 00288 } 00289 else 00290 { 00291 /* Left and right neighbors are blue */ 00292 OutputRed[i] = AverageV; 00293 OutputBlue[i] = AverageH; 00294 } 00295 } 00296 else 00297 { 00298 OutputGreen[i] = AverageC; 00299 00300 if((y & 1) == RedY) 00301 { 00302 /* Center pixel is red */ 00303 OutputRed[i] = Input[i]; 00304 OutputBlue[i] = AverageX; 00305 } 00306 else 00307 { 00308 /* Center pixel is blue */ 00309 OutputRed[i] = AverageX; 00310 OutputBlue[i] = Input[i]; 00311 } 00312 } 00313 } 00314 } 00315 }