libgphoto2 photo camera library (libgphoto2) Internals  2.5.23
bayer.c
Go to the documentation of this file.
1 
31 #include "config.h"
32 #include "bayer.h"
33 
34 #include <gphoto2/gphoto2-result.h>
35 
36 static const int tile_colours[8][4] = {
37  {0, 1, 1, 2},
38  {1, 0, 2, 1},
39  {2, 1, 1, 0},
40  {1, 2, 0, 1},
41  {0, 1, 1, 2},
42  {1, 0, 2, 1},
43  {2, 1, 1, 0},
44  {1, 2, 0, 1}};
45 
46 #define RED 0
47 #define GREEN 1
48 #define BLUE 2
49 
50 static int
51 gp_bayer_accrue (unsigned char *image, int w, int h, int x0, int y0,
52  int x1, int y1, int x2, int y2, int x3, int y3, int colour);
53 
73 int
74 gp_bayer_expand (unsigned char *input, int w, int h, unsigned char *output,
75  BayerTile tile)
76 {
77  int x, y, i;
78  int colour, bayer;
79  unsigned char *ptr = input;
80 
81  switch (tile) {
82 
83  case BAYER_TILE_RGGB:
84  case BAYER_TILE_GRBG:
85  case BAYER_TILE_BGGR:
86  case BAYER_TILE_GBRG:
87 
88  for (y = 0; y < h; ++y)
89  for (x = 0; x < w; ++x, ++ptr) {
90  bayer = (x&1?0:1) + (y&1?0:2);
91 
92  colour = tile_colours[tile][bayer];
93 
94  i = (y * w + x) * 3;
95 
96  output[i+RED] = 0;
97  output[i+GREEN] = 0;
98  output[i+BLUE] = 0;
99  output[i+colour] = *ptr;
100  }
101  break;
102 
107 
108 
109  for (y = 0; y < h; ++y, ptr+=w)
110  for (x = 0; x < w; ++x) {
111  bayer = (x&1?0:1) + (y&1?0:2);
112 
113  colour = tile_colours[tile][bayer];
114 
115  i = (y * w + x) * 3;
116 
117  output[i+RED] = 0;
118  output[i+GREEN] = 0;
119  output[i+BLUE] = 0;
120  output[i+colour] = (x&1)? ptr[x>>1]:ptr[(w>>1)+(x>>1)];
121  }
122  break;
123  }
124 
125  return (GP_OK);
126 }
127 
128 #define AD(x, y, w) ((y)*(w)*3+3*(x))
129 
144 int
145 gp_bayer_interpolate (unsigned char *image, int w, int h, BayerTile tile)
146 {
147  int x, y, bayer;
148  int p0, p1, p2;
149  int value, div ;
150 
151  switch (tile) {
152  default:
153  case BAYER_TILE_RGGB:
155  p0 = 0; p1 = 1; p2 = 2;
156  break;
157  case BAYER_TILE_GRBG:
159  p0 = 1; p1 = 0; p2 = 3;
160  break;
161  case BAYER_TILE_BGGR:
163  p0 = 3; p1 = 2; p2 = 1;
164  break;
165  case BAYER_TILE_GBRG:
167  p0 = 2; p1 = 3; p2 = 0;
168  break;
169  }
170 
171  for (y = 0; y < h; y++)
172  for (x = 0; x < w; x++) {
173  bayer = (x&1?0:1) + (y&1?0:2);
174 
175  if ( bayer == p0 ) {
176 
177  /* red. green lrtb, blue diagonals */
178  image[AD(x,y,w)+GREEN] =
179  gp_bayer_accrue(image, w, h, x-1, y, x+1, y, x, y-1, x, y+1, GREEN) ;
180 
181  image[AD(x,y,w)+BLUE] =
182  gp_bayer_accrue(image, w, h, x+1, y+1, x-1, y-1, x-1, y+1, x+1, y-1, BLUE) ;
183 
184  } else if (bayer == p1) {
185 
186  /* green. red lr, blue tb */
187  div = value = 0;
188  if (x < (w - 1)) {
189  value += image[AD(x+1,y,w)+RED];
190  div++;
191  }
192  if (x) {
193  value += image[AD(x-1,y,w)+RED];
194  div++;
195  }
196  image[AD(x,y,w)+RED] = value / div;
197 
198  div = value = 0;
199  if (y < (h - 1)) {
200  value += image[AD(x,y+1,w)+BLUE];
201  div++;
202  }
203  if (y) {
204  value += image[AD(x,y-1,w)+BLUE];
205  div++;
206  }
207  image[AD(x,y,w)+BLUE] = value / div;
208 
209  } else if ( bayer == p2 ) {
210 
211  /* green. blue lr, red tb */
212  div = value = 0;
213 
214  if (x < (w - 1)) {
215  value += image[AD(x+1,y,w)+BLUE];
216  div++;
217  }
218  if (x) {
219  value += image[AD(x-1,y,w)+BLUE];
220  div++;
221  }
222  image[AD(x,y,w)+BLUE] = value / div;
223 
224  div = value = 0;
225  if (y < (h - 1)) {
226  value += image[AD(x,y+1,w)+RED];
227  div++;
228  }
229  if (y) {
230  value += image[AD(x,y-1,w)+RED];
231  div++;
232  }
233  image[AD(x,y,w)+RED] = value / div;
234 
235  } else {
236 
237  /* blue. green lrtb, red diagonals */
238  image[AD(x,y,w)+GREEN] =
239  gp_bayer_accrue (image, w, h, x-1, y, x+1, y, x, y-1, x, y+1, GREEN) ;
240 
241  image[AD(x,y,w)+RED] =
242  gp_bayer_accrue (image, w, h, x+1, y+1, x-1, y-1, x-1, y+1, x+1, y-1, RED) ;
243  }
244  }
245 
246  return (GP_OK);
247 }
258 static int
259 gp_bayer_accrue (unsigned char *image, int w, int h, int x0, int y0,
260  int x1, int y1, int x2, int y2, int x3, int y3, int colour)
261 { int x [4] ;
262  int y [4] ;
263  int value [4] ;
264  int above [4] ;
265  int counter ;
266  int sum_of_values;
267  int average ;
268  int i ;
269  x[0] = x0 ; x[1] = x1 ; x[2] = x2 ; x[3] = x3 ;
270  y[0] = y0 ; y[1] = y1 ; y[2] = y2 ; y[3] = y3 ;
271 
272  /* special treatment for green */
273  counter = sum_of_values = 0 ;
274  if(colour == GREEN)
275  {
276  /* We need to make sure that horizontal or vertical lines
277  * become horizontal and vertical lines even in this
278  * interpolation procedure. Therefore, we determine whether
279  * we might have such a line structure.
280  */
281 
282  for (i = 0 ; i < 4 ; i++)
283  { if ((x[i] >= 0) && (x[i] < w) && (y[i] >= 0) && (y[i] < h))
284  {
285  value [i] = image[AD(x[i],y[i],w) + colour] ;
286  counter++;
287  }
288  else
289  {
290  value [i] = -1 ;
291  }
292  }
293  if(counter == 4)
294  {
295  /* It is assumed that x0,y0 and x1,y1 are on a
296  * horizontal line and
297  * x2,y2 and x3,y3 are on a vertical line
298  */
299  int hdiff ;
300  int vdiff ;
301  hdiff = value [1] - value [0] ;
302  hdiff *= hdiff ; /* Make value positive by squaring */
303  vdiff = value [3] - value [2] ;
304  vdiff *= vdiff ; /* Make value positive by squaring */
305  if(hdiff > 2*vdiff)
306  {
307  /* We might have a vertical structure here */
308  return (value [3] + value [2])/2 ;
309  }
310  if(vdiff > 2*hdiff)
311  {
312  /* we might have a horizontal structure here */
313  return (value [1] + value [0])/2 ;
314  }
315  /* else we proceed as with blue and red */
316  }
317  /* if we do not have four points then we proceed as we do for
318  * blue and red */
319  }
320 
321  /* for blue and red */
322  counter = sum_of_values = 0 ;
323  for (i = 0 ; i < 4 ; i++)
324  { if ((x[i] >= 0) && (x[i] < w) && (y[i] >= 0) && (y[i] < h))
325  { value [i] = image[AD(x[i],y[i],w) + colour] ;
326  sum_of_values += value [i] ;
327  counter++ ;
328  }
329  }
330  average = sum_of_values / counter ;
331  if (counter < 4) return average ;
332  /* Less than four surrounding - just take average */
333  counter = 0 ;
334  for (i = 0 ; i < 4 ; i++)
335  { above[i] = value[i] > average ;
336  if (above[i]) counter++ ;
337  }
338  /* Note: counter == 0 indicates all values the same */
339  if ((counter == 2) || (counter == 0)) return average ;
340  sum_of_values = 0 ;
341  for (i = 0 ; i < 4 ; i++)
342  { if ((counter == 3) == above[i])
343  { sum_of_values += value[i] ; }
344  }
345  return sum_of_values / 3 ;
346 }
347 
366 int
367 gp_bayer_decode (unsigned char *input, int w, int h, unsigned char *output,
368  BayerTile tile)
369 {
370  gp_bayer_expand (input, w, h, output, tile);
371  gp_bayer_interpolate (output, w, h, tile);
372 
373  return (GP_OK);
374 }
gp_bayer_decode
int gp_bayer_decode(unsigned char *input, int w, int h, unsigned char *output, BayerTile tile)
Convert a bayer raster style image to a RGB raster.
Definition: bayer.c:367
gp_bayer_interpolate
int gp_bayer_interpolate(unsigned char *image, int w, int h, BayerTile tile)
Interpolate a expanded bayer array into an RGB image.
Definition: bayer.c:145
BAYER_TILE_RGGB
@ BAYER_TILE_RGGB
raster is RG,GN
Definition: bayer.h:33
GREEN
#define GREEN
Definition: bayer.c:47
BAYER_TILE_RGGB_INTERLACED
@ BAYER_TILE_RGGB_INTERLACED
scanline order: R1,G1,R2,G2,...,G1,B1,G2,B2,...
Definition: bayer.h:37
BAYER_TILE_GRBG
@ BAYER_TILE_GRBG
raster is GR,BG
Definition: bayer.h:34
gphoto2-result.h
BAYER_TILE_GBRG_INTERLACED
@ BAYER_TILE_GBRG_INTERLACED
scanline order: G1,B1,G2,B2,...,R1,G1,R2,G2,...
Definition: bayer.h:40
GP_OK
#define GP_OK
Everything is OK.
Definition: gphoto2-port-result.h:30
BAYER_TILE_GBRG
@ BAYER_TILE_GBRG
raster is RG,GB
Definition: bayer.h:36
BAYER_TILE_BGGR
@ BAYER_TILE_BGGR
raster is BG,GR
Definition: bayer.h:35
AD
#define AD(x, y, w)
Definition: bayer.c:128
BAYER_TILE_BGGR_INTERLACED
@ BAYER_TILE_BGGR_INTERLACED
scanline order: B1,G1,R2,G2,...,G1,R1,G2,R2,...
Definition: bayer.h:39
BayerTile
BayerTile
how the bayer CCD array is layed out
Definition: bayer.h:32
gp_bayer_expand
int gp_bayer_expand(unsigned char *input, int w, int h, unsigned char *output, BayerTile tile)
Expand a bayer raster style image to a RGB raster.
Definition: bayer.c:74
BLUE
#define BLUE
Definition: bayer.c:48
tile_colours
static const int tile_colours[8][4]
Definition: bayer.c:36
BAYER_TILE_GRBG_INTERLACED
@ BAYER_TILE_GRBG_INTERLACED
scanline order: G1,R1,R2,G2,...,B1,G1,B2,G2,...
Definition: bayer.h:38
RED
#define RED
Definition: bayer.c:46
bayer.h
gp_bayer_accrue
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)
interpolate one pixel from a bayer 2x2 raster
Definition: bayer.c:259