Image Demosaicking with Contour Stencils
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
dmbilinear.c
Go to the documentation of this file.
1 
16 #include "dmbilinear.h"
17 
18 
26 void CfaFlatten(float *Flat, const float *Input, int Width, int Height,
27  int RedX, int RedY)
28 {
29  const float *InputRed = Input;
30  const float *InputGreen = Input + Width*Height;
31  const float *InputBlue = Input + 2*Width*Height;
32  const int Green = 1 - ((RedX + RedY) & 1);
33  int i, x, y;
34 
35 
36  for(y = 0, i = 0; y < Height; y++)
37  for(x = 0; x < Width; x++, i++)
38  {
39  if(((x + y) & 1) == Green)
40  Flat[i] = InputGreen[i];
41  else if((y & 1) == RedY)
42  Flat[i] = InputRed[i];
43  else
44  Flat[i] = InputBlue[i];
45  }
46 }
47 
48 
74 void BilinearDifference(float *Output, const float *Diff,
75  int Width, int Height, int RedX, int RedY)
76 {
77  const int NumPixels = Width*Height;
78  const int Green = 1 - ((RedX + RedY) & 1);
79  float *OutputRed = Output;
80  float *OutputGreen = Output + NumPixels;
81  float *OutputBlue = Output + 2*NumPixels;
82  float AverageH, AverageV, AverageX;
83  int x, y, i;
84 
85 
86  for(y = 0, i = 0; y < Height; y++)
87  {
88  for(x = 0; x < Width; x++, i++)
89  {
90  /* The following computes three quantities:
91  * AverageH: average of the horizontal neighbors
92  * AverageV: average of the vertical neighbors
93  * AverageX: average of the diagonal neighbors
94  *
95  * Near a boundary, the average is computed using only those
96  * samples which are defined in the image. For example on the left
97  * boundary of the image, the left neighbors are omitted and
98  * AverageH is simply set to the value of the right neighbor.
99  */
100  if(y == 0)
101  {
102  AverageV = Diff[i + Width];
103 
104  if(x == 0)
105  {
106  AverageH = Diff[i + 1];
107  AverageX = Diff[i + 1 + Width];
108  }
109  else if(x < Width - 1)
110  {
111  AverageH = (Diff[i - 1] + Diff[i + 1]) / 2;
112  AverageX = (Diff[i - 1 + Width] + Diff[i + 1 + Width]) / 2;
113  }
114  else
115  {
116  AverageH = Diff[i - 1];
117  AverageX = Diff[i - 1 + Width];
118  }
119 
120  }
121  else if(y < Height - 1)
122  {
123  AverageV = (Diff[i - Width] + Diff[i + Width]) / 2;
124 
125  if(x == 0)
126  {
127  AverageH = Diff[i + 1];
128  AverageX = (Diff[i + 1 - Width] + Diff[i + 1 + Width]) / 2;
129  }
130  else if(x < Width - 1)
131  {
132  AverageH = (Diff[i - 1] + Diff[i + 1]) / 2;
133  AverageX = (Diff[i - 1 - Width] + Diff[i + 1 - Width]
134  + Diff[i - 1 + Width] + Diff[i + 1 + Width]) / 4;
135  }
136  else
137  {
138  AverageH = Diff[i - 1];
139  AverageX = (Diff[i - 1 - Width] + Diff[i - 1 + Width]) / 2;
140  }
141  }
142  else
143  {
144  AverageV = Diff[i - Width];
145 
146  if(x == 0)
147  {
148  AverageH = Diff[i + 1];
149  AverageX = Diff[i + 1 - Width];
150  }
151  else if(x < Width - 1)
152  {
153  AverageH = (Diff[i - 1] + Diff[i + 1]) / 2;
154  AverageX = (Diff[i - 1 - Width] + Diff[i + 1 - Width]) / 2;
155  }
156  else
157  {
158  AverageH = Diff[i - 1];
159  AverageX = Diff[i - 1 - Width];
160  }
161  }
162 
163  if(((x + y) & 1) == Green)
164  {
165  if((y & 1) == RedY)
166  {
167  /* Left and right neighbors are red */
168  OutputRed[i] = OutputGreen[i] + AverageH;
169  OutputBlue[i] = OutputGreen[i] + AverageV;
170  }
171  else
172  {
173  /* Left and right neighbors are blue */
174  OutputRed[i] = OutputGreen[i] + AverageV;
175  OutputBlue[i] = OutputGreen[i] + AverageH;
176  }
177  }
178  else
179  {
180  if((y & 1) == RedY)
181  {
182  /* Center pixel is red */
183  OutputRed[i] = OutputGreen[i] + Diff[i];
184  OutputBlue[i] = OutputGreen[i] + AverageX;
185  }
186  else
187  {
188  /* Center pixel is blue */
189  OutputRed[i] = OutputGreen[i] + AverageX;
190  OutputBlue[i] = OutputGreen[i] + Diff[i];
191  }
192  }
193  }
194  }
195 }
196 
197 
212 void BilinearDemosaic(float *Output, const float *Input, int Width, int Height,
213  int RedX, int RedY)
214 {
215  float *OutputRed = Output;
216  float *OutputGreen = Output + Width*Height;
217  float *OutputBlue = Output + 2*Width*Height;
218  const int Green = 1 - ((RedX + RedY) & 1);
219  float AverageH, AverageV, AverageC, AverageX;
220  int i, x, y;
221 
222 
223  for(y = 0, i = 0; y < Height; y++)
224  {
225  for(x = 0; x < Width; x++, i++)
226  {
227  /* The following computes four quantities:
228  * AverageH: average of the horizontal neighbors
229  * AverageV: average of the vertical neighbors
230  * AverageC: average of the axial neighbors
231  * AverageX: average of the diagonal neighbors
232  *
233  * Near a boundary, the average is computed using only those
234  * samples which are defined in the image. For example on the left
235  * boundary of the image, the left neighbors are omitted and
236  * AverageH is simply set to the value of the right neighbor.
237  */
238  if(y == 0)
239  {
240  AverageV = Input[i + Width];
241 
242  if(x == 0)
243  {
244  AverageH = Input[i + 1];
245  AverageC = (Input[i + 1] + Input[i + Width])/2;
246  AverageX = Input[i + 1 + Width];
247  }
248  else if(x < Width - 1)
249  {
250  AverageH = (Input[i - 1] + Input[i + 1]) / 2;
251  AverageC = (Input[i - 1] + Input[i + 1]
252  + Input[i + Width])/3;
253  AverageX = (Input[i - 1 + Width]
254  + Input[i + 1 + Width]) / 2;
255  }
256  else
257  {
258  AverageH = Input[i - 1];
259  AverageC = (Input[i - 1] + Input[i + Width])/2;
260  AverageX = Input[i - 1 + Width];
261  }
262  }
263  else if(y < Height - 1)
264  {
265  AverageV = (Input[i - Width] + Input[i + Width]) / 2;
266 
267  if(x == 0)
268  {
269  AverageH = Input[i + 1];
270  AverageC = (Input[i + 1] +
271  Input[i - Width] + Input[i + Width]) / 3;
272  AverageX = (Input[i + 1 - Width]
273  + Input[i + 1 + Width]) / 2;
274  }
275  else if(x < Width - 1)
276  {
277  AverageH = (Input[i - 1] + Input[i + 1]) / 2;
278  AverageC = (AverageH + AverageV) / 2;
279  AverageX = (Input[i - 1 - Width] + Input[i + 1 - Width]
280  + Input[i - 1 + Width] + Input[i + 1 + Width]) / 4;
281  }
282  else
283  {
284  AverageH = Input[i - 1];
285  AverageC = (Input[i - 1] +
286  Input[i - Width] + Input[i + Width]) / 3;
287  AverageX = (Input[i - 1 - Width]
288  + Input[i - 1 + Width]) / 2;
289  }
290  }
291  else
292  {
293  AverageV = Input[i - Width];
294 
295  if(x == 0)
296  {
297  AverageH = Input[i + 1];
298  AverageC = (Input[i + 1] + Input[i - Width]) / 2;
299  AverageX = Input[i + 1 - Width];
300  }
301  else if(x < Width - 1)
302  {
303  AverageH = (Input[i - 1] + Input[i + 1]) / 2;
304  AverageC = (Input[i - 1]
305  + Input[i + 1] + Input[i - Width]) / 3;
306  AverageX = (Input[i - 1 - Width]
307  + Input[i + 1 - Width]) / 2;
308  }
309  else
310  {
311  AverageH = Input[i - 1];
312  AverageC = (Input[i - 1] + Input[i - Width]) / 2;
313  AverageX = Input[i - 1 - Width];
314  }
315  }
316 
317  if(((x + y) & 1) == Green)
318  {
319  /* Center pixel is green */
320  OutputGreen[i] = Input[i];
321 
322  if((y & 1) == RedY)
323  {
324  /* Left and right neighbors are red */
325  OutputRed[i] = AverageH;
326  OutputBlue[i] = AverageV;
327  }
328  else
329  {
330  /* Left and right neighbors are blue */
331  OutputRed[i] = AverageV;
332  OutputBlue[i] = AverageH;
333  }
334  }
335  else
336  {
337  OutputGreen[i] = AverageC;
338 
339  if((y & 1) == RedY)
340  {
341  /* Center pixel is red */
342  OutputRed[i] = Input[i];
343  OutputBlue[i] = AverageX;
344  }
345  else
346  {
347  /* Center pixel is blue */
348  OutputRed[i] = AverageX;
349  OutputBlue[i] = Input[i];
350  }
351  }
352  }
353  }
354 }