edge_aware.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2008, Willow Garage, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34 #include "edge_aware.h"
35 
36 #define AVG(a,b) (((int)(a) + (int)(b)) >> 1)
37 #define AVG3(a,b,c) (((int)(a) + (int)(b) + (int)(c)) / 3)
38 #define AVG4(a,b,c,d) (((int)(a) + (int)(b) + (int)(c) + (int)(d)) >> 2)
39 #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))) ) )
40 using namespace std;
41 
42 namespace image_proc {
43 
44 void debayerEdgeAware(const cv::Mat& bayer, cv::Mat& color)
45 {
46  unsigned width = bayer.cols;
47  unsigned height = bayer.rows;
48  unsigned rgb_line_step = color.step[0];
49  unsigned rgb_line_skip = rgb_line_step - width * 3;
50  int bayer_line_step = bayer.step[0];
51  int bayer_line_step2 = bayer_line_step * 2;
52 
53  unsigned char* rgb_buffer = color.data;
54  unsigned char* bayer_pixel = bayer.data;
55  unsigned yIdx, xIdx;
56 
57  int dh, dv;
58 
59  // first two pixel values for first two lines
60  // Bayer 0 1 2
61  // 0 G r g
62  // line_step b g b
63  // line_step2 g r g
64 
65  rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
66  rgb_buffer[1] = bayer_pixel[0]; // green pixel
67  rgb_buffer[rgb_line_step + 2] = rgb_buffer[2] = bayer_pixel[bayer_line_step]; // blue;
68 
69  // Bayer 0 1 2
70  // 0 g R g
71  // line_step b g b
72  // line_step2 g r g
73  //rgb_pixel[3] = bayer_pixel[1];
74  rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1]);
75  rgb_buffer[rgb_line_step + 5] = rgb_buffer[5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
76 
77  // BGBG line
78  // Bayer 0 1 2
79  // 0 g r g
80  // line_step B g b
81  // line_step2 g r g
82  rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
83  rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[bayer_line_step2]);
84  //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
85 
86  // pixel (1, 1) 0 1 2
87  // 0 g r g
88  // line_step b G b
89  // line_step2 g r g
90  //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
91  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
92  //rgb_pixel[rgb_line_step + 5] = AVG( bayer_pixel[line_step] , bayer_pixel[line_step+2] );
93 
94  rgb_buffer += 6;
95  bayer_pixel += 2;
96  // rest of the first two lines
97  for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
98  {
99  // GRGR line
100  // Bayer -1 0 1 2
101  // 0 r G r g
102  // line_step g b g b
103  // line_step2 r g r g
104  rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
105  rgb_buffer[1] = bayer_pixel[0];
106  rgb_buffer[2] = bayer_pixel[bayer_line_step + 1];
107 
108  // Bayer -1 0 1 2
109  // 0 r g R g
110  // line_step g b g b
111  // line_step2 r g r g
112  rgb_buffer[3] = bayer_pixel[1];
113  rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1]);
114  rgb_buffer[rgb_line_step + 5] = rgb_buffer[5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
115 
116  // BGBG line
117  // Bayer -1 0 1 2
118  // 0 r g r g
119  // line_step g B g b
120  // line_step2 r g r g
121  rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
122  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]);
123  rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
124 
125  // Bayer -1 0 1 2
126  // 0 r g r g
127  // line_step g b G b
128  // line_step2 r g r g
129  rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
130  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
131  //rgb_pixel[rgb_line_step + 5] = AVG( bayer_pixel[line_step] , bayer_pixel[line_step+2] );
132  }
133 
134  // last two pixel values for first two lines
135  // GRGR line
136  // Bayer -1 0 1
137  // 0 r G r
138  // line_step g b g
139  // line_step2 r g r
140  rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
141  rgb_buffer[1] = bayer_pixel[0];
142  rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = rgb_buffer[5] = rgb_buffer[2] = bayer_pixel[bayer_line_step];
143 
144  // Bayer -1 0 1
145  // 0 r g R
146  // line_step g b g
147  // line_step2 r g r
148  rgb_buffer[3] = bayer_pixel[1];
149  rgb_buffer[4] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
150  //rgb_pixel[5] = bayer_pixel[line_step];
151 
152  // BGBG line
153  // Bayer -1 0 1
154  // 0 r g r
155  // line_step g B g
156  // line_step2 r g r
157  rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
158  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]);
159  //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
160 
161  // Bayer -1 0 1
162  // 0 r g r
163  // line_step g b G
164  // line_step2 r g r
165  rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
166  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
167  //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
168 
169  bayer_pixel += bayer_line_step + 2;
170  rgb_buffer += rgb_line_step + 6 + rgb_line_skip;
171  // main processing
172  for (yIdx = 2; yIdx < height - 2; yIdx += 2)
173  {
174  // first two pixel values
175  // Bayer 0 1 2
176  // -1 b g b
177  // 0 G r g
178  // line_step b g b
179  // line_step2 g r g
180 
181  rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
182  rgb_buffer[1] = bayer_pixel[0]; // green pixel
183  rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]); // blue;
184 
185  // Bayer 0 1 2
186  // -1 b g b
187  // 0 g R g
188  // line_step b g b
189  // line_step2 g r g
190  //rgb_pixel[3] = bayer_pixel[1];
191  rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
192  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]);
193 
194  // BGBG line
195  // Bayer 0 1 2
196  // 0 g r g
197  // line_step B g b
198  // line_step2 g r g
199  rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
200  rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[bayer_line_step2]);
201  rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
202 
203  // pixel (1, 1) 0 1 2
204  // 0 g r g
205  // line_step b G b
206  // line_step2 g r g
207  //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
208  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
209  rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
210 
211  rgb_buffer += 6;
212  bayer_pixel += 2;
213  // continue with rest of the line
214  for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
215  {
216  // GRGR line
217  // Bayer -1 0 1 2
218  // -1 g b g b
219  // 0 r G r g
220  // line_step g b g b
221  // line_step2 r g r g
222  rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
223  rgb_buffer[1] = bayer_pixel[0];
224  rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
225 
226  // Bayer -1 0 1 2
227  // -1 g b g b
228  // 0 r g R g
229  // line_step g b g b
230  // line_step2 r g r g
231 
232  dh = abs (bayer_pixel[0] - bayer_pixel[2]);
233  dv = abs (bayer_pixel[-bayer_line_step + 1] - bayer_pixel[bayer_line_step + 1]);
234 
235  if (dh > dv)
236  rgb_buffer[4] = AVG (bayer_pixel[-bayer_line_step + 1], bayer_pixel[bayer_line_step + 1]);
237  else if (dv > dh)
238  rgb_buffer[4] = AVG (bayer_pixel[0], bayer_pixel[2]);
239  else
240  rgb_buffer[4] = AVG4 (bayer_pixel[-bayer_line_step + 1], bayer_pixel[bayer_line_step + 1], bayer_pixel[0], bayer_pixel[2]);
241 
242  rgb_buffer[3] = bayer_pixel[1];
243  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]);
244 
245  // BGBG line
246  // Bayer -1 0 1 2
247  // -1 g b g b
248  // 0 r g r g
249  // line_step g B g b
250  // line_step2 r g r g
251  rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
252  rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
253 
254  dv = abs (bayer_pixel[0] - bayer_pixel[bayer_line_step2]);
255  dh = abs (bayer_pixel[bayer_line_step - 1] - bayer_pixel[bayer_line_step + 1]);
256 
257  if (dv > dh)
258  rgb_buffer[rgb_line_step + 1] = AVG (bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
259  else if (dh > dv)
260  rgb_buffer[rgb_line_step + 1] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step2]);
261  else
262  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]);
263 
264  // Bayer -1 0 1 2
265  // -1 g b g b
266  // 0 r g r g
267  // line_step g b G b
268  // line_step2 r g r g
269  rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
270  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
271  rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
272  }
273 
274  // last two pixels of the line
275  // last two pixel values for first two lines
276  // GRGR line
277  // Bayer -1 0 1
278  // 0 r G r
279  // line_step g b g
280  // line_step2 r g r
281  rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
282  rgb_buffer[1] = bayer_pixel[0];
283  rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = rgb_buffer[5] = rgb_buffer[2] = bayer_pixel[bayer_line_step];
284 
285  // Bayer -1 0 1
286  // 0 r g R
287  // line_step g b g
288  // line_step2 r g r
289  rgb_buffer[3] = bayer_pixel[1];
290  rgb_buffer[4] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
291  //rgb_pixel[5] = bayer_pixel[line_step];
292 
293  // BGBG line
294  // Bayer -1 0 1
295  // 0 r g r
296  // line_step g B g
297  // line_step2 r g r
298  rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
299  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]);
300  //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
301 
302  // Bayer -1 0 1
303  // 0 r g r
304  // line_step g b G
305  // line_step2 r g r
306  rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
307  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
308  //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
309 
310  bayer_pixel += bayer_line_step + 2;
311  rgb_buffer += rgb_line_step + 6 + rgb_line_skip;
312  }
313 
314  //last two lines
315  // Bayer 0 1 2
316  // -1 b g b
317  // 0 G r g
318  // line_step b g b
319 
320  rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
321  rgb_buffer[1] = bayer_pixel[0]; // green pixel
322  rgb_buffer[rgb_line_step + 2] = rgb_buffer[2] = bayer_pixel[bayer_line_step]; // blue;
323 
324  // Bayer 0 1 2
325  // -1 b g b
326  // 0 g R g
327  // line_step b g b
328  //rgb_pixel[3] = bayer_pixel[1];
329  rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
330  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]);
331 
332  // BGBG line
333  // Bayer 0 1 2
334  // -1 b g b
335  // 0 g r g
336  // line_step B g b
337  //rgb_pixel[rgb_line_step ] = bayer_pixel[1];
338  rgb_buffer[rgb_line_step + 1] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
339  rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
340 
341  // Bayer 0 1 2
342  // -1 b g b
343  // 0 g r g
344  // line_step b G b
345  //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
346  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
347  rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
348 
349  rgb_buffer += 6;
350  bayer_pixel += 2;
351  // rest of the last two lines
352  for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
353  {
354  // GRGR line
355  // Bayer -1 0 1 2
356  // -1 g b g b
357  // 0 r G r g
358  // line_step g b g b
359  rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
360  rgb_buffer[1] = bayer_pixel[0];
361  rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
362 
363  // Bayer -1 0 1 2
364  // -1 g b g b
365  // 0 r g R g
366  // line_step g b g b
367  rgb_buffer[rgb_line_step + 3] = rgb_buffer[3] = bayer_pixel[1];
368  rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
369  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]);
370 
371  // BGBG line
372  // Bayer -1 0 1 2
373  // -1 g b g b
374  // 0 r g r g
375  // line_step g B g b
376  rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[-1], bayer_pixel[1]);
377  rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
378  rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
379 
380 
381  // Bayer -1 0 1 2
382  // -1 g b g b
383  // 0 r g r g
384  // line_step g b G b
385  //rgb_pixel[rgb_line_step + 3] = bayer_pixel[1];
386  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
387  rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
388  }
389 
390  // last two pixel values for first two lines
391  // GRGR line
392  // Bayer -1 0 1
393  // -1 g b g
394  // 0 r G r
395  // line_step g b g
396  rgb_buffer[rgb_line_step ] = rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
397  rgb_buffer[1] = bayer_pixel[0];
398  rgb_buffer[5] = rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
399 
400  // Bayer -1 0 1
401  // -1 g b g
402  // 0 r g R
403  // line_step g b g
404  rgb_buffer[rgb_line_step + 3] = rgb_buffer[3] = bayer_pixel[1];
405  rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[-bayer_line_step + 1]);
406  //rgb_pixel[5] = AVG( bayer_pixel[line_step], bayer_pixel[-line_step] );
407 
408  // BGBG line
409  // Bayer -1 0 1
410  // -1 g b g
411  // 0 r g r
412  // line_step g B g
413  //rgb_pixel[rgb_line_step ] = AVG2( bayer_pixel[-1], bayer_pixel[1] );
414  rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
415  rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
416 
417  // Bayer -1 0 1
418  // -1 g b g
419  // 0 r g r
420  // line_step g b G
421  //rgb_pixel[rgb_line_step + 3] = bayer_pixel[1];
422  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
423  //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
424 }
425 
426 void debayerEdgeAwareWeighted(const cv::Mat& bayer, cv::Mat& color)
427 {
428  unsigned width = bayer.cols;
429  unsigned height = bayer.rows;
430  unsigned rgb_line_step = color.step[0];
431  unsigned rgb_line_skip = rgb_line_step - width * 3;
432  int bayer_line_step = bayer.step[0];
433  int bayer_line_step2 = bayer_line_step * 2;
434 
435  unsigned char* rgb_buffer = color.data;
436  unsigned char* bayer_pixel = bayer.data;
437  unsigned yIdx, xIdx;
438 
439  int dh, dv;
440 
441  // first two pixel values for first two lines
442  // Bayer 0 1 2
443  // 0 G r g
444  // line_step b g b
445  // line_step2 g r g
446 
447  rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
448  rgb_buffer[1] = bayer_pixel[0]; // green pixel
449  rgb_buffer[rgb_line_step + 2] = rgb_buffer[2] = bayer_pixel[bayer_line_step]; // blue;
450 
451  // Bayer 0 1 2
452  // 0 g R g
453  // line_step b g b
454  // line_step2 g r g
455  //rgb_pixel[3] = bayer_pixel[1];
456  rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1]);
457  rgb_buffer[rgb_line_step + 5] = rgb_buffer[5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
458 
459  // BGBG line
460  // Bayer 0 1 2
461  // 0 g r g
462  // line_step B g b
463  // line_step2 g r g
464  rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
465  rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[bayer_line_step2]);
466  //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
467 
468  // pixel (1, 1) 0 1 2
469  // 0 g r g
470  // line_step b G b
471  // line_step2 g r g
472  //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
473  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
474  //rgb_pixel[rgb_line_step + 5] = AVG( bayer_pixel[line_step] , bayer_pixel[line_step+2] );
475 
476  rgb_buffer += 6;
477  bayer_pixel += 2;
478  // rest of the first two lines
479  for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
480  {
481  // GRGR line
482  // Bayer -1 0 1 2
483  // 0 r G r g
484  // line_step g b g b
485  // line_step2 r g r g
486  rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
487  rgb_buffer[1] = bayer_pixel[0];
488  rgb_buffer[2] = bayer_pixel[bayer_line_step + 1];
489 
490  // Bayer -1 0 1 2
491  // 0 r g R g
492  // line_step g b g b
493  // line_step2 r g r g
494  rgb_buffer[3] = bayer_pixel[1];
495  rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1]);
496  rgb_buffer[rgb_line_step + 5] = rgb_buffer[5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
497 
498  // BGBG line
499  // Bayer -1 0 1 2
500  // 0 r g r g
501  // line_step g B g b
502  // line_step2 r g r g
503  rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
504  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]);
505  rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
506 
507  // Bayer -1 0 1 2
508  // 0 r g r g
509  // line_step g b G b
510  // line_step2 r g r g
511  rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
512  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
513  //rgb_pixel[rgb_line_step + 5] = AVG( bayer_pixel[line_step] , bayer_pixel[line_step+2] );
514  }
515 
516  // last two pixel values for first two lines
517  // GRGR line
518  // Bayer -1 0 1
519  // 0 r G r
520  // line_step g b g
521  // line_step2 r g r
522  rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
523  rgb_buffer[1] = bayer_pixel[0];
524  rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = rgb_buffer[5] = rgb_buffer[2] = bayer_pixel[bayer_line_step];
525 
526  // Bayer -1 0 1
527  // 0 r g R
528  // line_step g b g
529  // line_step2 r g r
530  rgb_buffer[3] = bayer_pixel[1];
531  rgb_buffer[4] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
532  //rgb_pixel[5] = bayer_pixel[line_step];
533 
534  // BGBG line
535  // Bayer -1 0 1
536  // 0 r g r
537  // line_step g B g
538  // line_step2 r g r
539  rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
540  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]);
541  //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
542 
543  // Bayer -1 0 1
544  // 0 r g r
545  // line_step g b G
546  // line_step2 r g r
547  rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
548  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
549  //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
550 
551  bayer_pixel += bayer_line_step + 2;
552  rgb_buffer += rgb_line_step + 6 + rgb_line_skip;
553  // main processing
554  for (yIdx = 2; yIdx < height - 2; yIdx += 2)
555  {
556  // first two pixel values
557  // Bayer 0 1 2
558  // -1 b g b
559  // 0 G r g
560  // line_step b g b
561  // line_step2 g r g
562 
563  rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
564  rgb_buffer[1] = bayer_pixel[0]; // green pixel
565  rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]); // blue;
566 
567  // Bayer 0 1 2
568  // -1 b g b
569  // 0 g R g
570  // line_step b g b
571  // line_step2 g r g
572  //rgb_pixel[3] = bayer_pixel[1];
573  rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
574  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]);
575 
576  // BGBG line
577  // Bayer 0 1 2
578  // 0 g r g
579  // line_step B g b
580  // line_step2 g r g
581  rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
582  rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[bayer_line_step2]);
583  rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
584 
585  // pixel (1, 1) 0 1 2
586  // 0 g r g
587  // line_step b G b
588  // line_step2 g r g
589  //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
590  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
591  rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
592 
593  rgb_buffer += 6;
594  bayer_pixel += 2;
595  // continue with rest of the line
596  for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
597  {
598  // GRGR line
599  // Bayer -1 0 1 2
600  // -1 g b g b
601  // 0 r G r g
602  // line_step g b g b
603  // line_step2 r g r g
604  rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
605  rgb_buffer[1] = bayer_pixel[0];
606  rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
607 
608  // Bayer -1 0 1 2
609  // -1 g b g b
610  // 0 r g R g
611  // line_step g b g b
612  // line_step2 r g r g
613 
614  dh = abs (bayer_pixel[0] - bayer_pixel[2]);
615  dv = abs (bayer_pixel[-bayer_line_step + 1] - bayer_pixel[bayer_line_step + 1]);
616 
617  if (dv == 0 && dh == 0)
618  rgb_buffer[4] = AVG4 (bayer_pixel[1 - bayer_line_step], bayer_pixel[1 + bayer_line_step], bayer_pixel[0], bayer_pixel[2]);
619  else
620  rgb_buffer[4] = WAVG4 (bayer_pixel[1 - bayer_line_step], bayer_pixel[1 + bayer_line_step], bayer_pixel[0], bayer_pixel[2], dh, dv);
621  rgb_buffer[3] = bayer_pixel[1];
622  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]);
623 
624  // BGBG line
625  // Bayer -1 0 1 2
626  // -1 g b g b
627  // 0 r g r g
628  // line_step g B g b
629  // line_step2 r g r g
630  rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
631  rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
632 
633  dv = abs (bayer_pixel[0] - bayer_pixel[bayer_line_step2]);
634  dh = abs (bayer_pixel[bayer_line_step - 1] - bayer_pixel[bayer_line_step + 1]);
635 
636  if (dv == 0 && dh == 0)
637  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]);
638  else
639  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);
640 
641  // Bayer -1 0 1 2
642  // -1 g b g b
643  // 0 r g r g
644  // line_step g b G b
645  // line_step2 r g r g
646  rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
647  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
648  rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
649  }
650 
651  // last two pixels of the line
652  // last two pixel values for first two lines
653  // GRGR line
654  // Bayer -1 0 1
655  // 0 r G r
656  // line_step g b g
657  // line_step2 r g r
658  rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
659  rgb_buffer[1] = bayer_pixel[0];
660  rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = rgb_buffer[5] = rgb_buffer[2] = bayer_pixel[bayer_line_step];
661 
662  // Bayer -1 0 1
663  // 0 r g R
664  // line_step g b g
665  // line_step2 r g r
666  rgb_buffer[3] = bayer_pixel[1];
667  rgb_buffer[4] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
668  //rgb_pixel[5] = bayer_pixel[line_step];
669 
670  // BGBG line
671  // Bayer -1 0 1
672  // 0 r g r
673  // line_step g B g
674  // line_step2 r g r
675  rgb_buffer[rgb_line_step ] = AVG4 (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1], bayer_pixel[-1], bayer_pixel[bayer_line_step2 - 1]);
676  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]);
677  //rgb_pixel[rgb_line_step + 2] = bayer_pixel[line_step];
678 
679  // Bayer -1 0 1
680  // 0 r g r
681  // line_step g b G
682  // line_step2 r g r
683  rgb_buffer[rgb_line_step + 3] = AVG (bayer_pixel[1], bayer_pixel[bayer_line_step2 + 1]);
684  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
685  //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
686 
687  bayer_pixel += bayer_line_step + 2;
688  rgb_buffer += rgb_line_step + 6 + rgb_line_skip;
689  }
690 
691  //last two lines
692  // Bayer 0 1 2
693  // -1 b g b
694  // 0 G r g
695  // line_step b g b
696 
697  rgb_buffer[rgb_line_step + 3] = rgb_buffer[rgb_line_step ] = rgb_buffer[3] = rgb_buffer[0] = bayer_pixel[1]; // red pixel
698  rgb_buffer[1] = bayer_pixel[0]; // green pixel
699  rgb_buffer[rgb_line_step + 2] = rgb_buffer[2] = bayer_pixel[bayer_line_step]; // blue;
700 
701  // Bayer 0 1 2
702  // -1 b g b
703  // 0 g R g
704  // line_step b g b
705  //rgb_pixel[3] = bayer_pixel[1];
706  rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
707  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]);
708 
709  // BGBG line
710  // Bayer 0 1 2
711  // -1 b g b
712  // 0 g r g
713  // line_step B g b
714  //rgb_pixel[rgb_line_step ] = bayer_pixel[1];
715  rgb_buffer[rgb_line_step + 1] = AVG (bayer_pixel[0], bayer_pixel[bayer_line_step + 1]);
716  rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
717 
718  // Bayer 0 1 2
719  // -1 b g b
720  // 0 g r g
721  // line_step b G b
722  //rgb_pixel[rgb_line_step + 3] = AVG( bayer_pixel[1] , bayer_pixel[line_step2+1] );
723  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
724  rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
725 
726  rgb_buffer += 6;
727  bayer_pixel += 2;
728  // rest of the last two lines
729  for (xIdx = 2; xIdx < width - 2; xIdx += 2, rgb_buffer += 6, bayer_pixel += 2)
730  {
731  // GRGR line
732  // Bayer -1 0 1 2
733  // -1 g b g b
734  // 0 r G r g
735  // line_step g b g b
736  rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
737  rgb_buffer[1] = bayer_pixel[0];
738  rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
739 
740  // Bayer -1 0 1 2
741  // -1 g b g b
742  // 0 r g R g
743  // line_step g b g b
744  rgb_buffer[rgb_line_step + 3] = rgb_buffer[3] = bayer_pixel[1];
745  rgb_buffer[4] = AVG4 (bayer_pixel[0], bayer_pixel[2], bayer_pixel[bayer_line_step + 1], bayer_pixel[1 - bayer_line_step]);
746  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]);
747 
748  // BGBG line
749  // Bayer -1 0 1 2
750  // -1 g b g b
751  // 0 r g r g
752  // line_step g B g b
753  rgb_buffer[rgb_line_step ] = AVG (bayer_pixel[-1], bayer_pixel[1]);
754  rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
755  rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
756 
757 
758  // Bayer -1 0 1 2
759  // -1 g b g b
760  // 0 r g r g
761  // line_step g b G b
762  //rgb_pixel[rgb_line_step + 3] = bayer_pixel[1];
763  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
764  rgb_buffer[rgb_line_step + 5] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[bayer_line_step + 2]);
765  }
766 
767  // last two pixel values for first two lines
768  // GRGR line
769  // Bayer -1 0 1
770  // -1 g b g
771  // 0 r G r
772  // line_step g b g
773  rgb_buffer[rgb_line_step ] = rgb_buffer[0] = AVG (bayer_pixel[1], bayer_pixel[-1]);
774  rgb_buffer[1] = bayer_pixel[0];
775  rgb_buffer[5] = rgb_buffer[2] = AVG (bayer_pixel[bayer_line_step], bayer_pixel[-bayer_line_step]);
776 
777  // Bayer -1 0 1
778  // -1 g b g
779  // 0 r g R
780  // line_step g b g
781  rgb_buffer[rgb_line_step + 3] = rgb_buffer[3] = bayer_pixel[1];
782  rgb_buffer[4] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step + 1], bayer_pixel[-bayer_line_step + 1]);
783  //rgb_pixel[5] = AVG( bayer_pixel[line_step], bayer_pixel[-line_step] );
784 
785  // BGBG line
786  // Bayer -1 0 1
787  // -1 g b g
788  // 0 r g r
789  // line_step g B g
790  //rgb_pixel[rgb_line_step ] = AVG2( bayer_pixel[-1], bayer_pixel[1] );
791  rgb_buffer[rgb_line_step + 1] = AVG3 (bayer_pixel[0], bayer_pixel[bayer_line_step - 1], bayer_pixel[bayer_line_step + 1]);
792  rgb_buffer[rgb_line_step + 5] = rgb_buffer[rgb_line_step + 2] = bayer_pixel[bayer_line_step];
793 
794  // Bayer -1 0 1
795  // -1 g b g
796  // 0 r g r
797  // line_step g b G
798  //rgb_pixel[rgb_line_step + 3] = bayer_pixel[1];
799  rgb_buffer[rgb_line_step + 4] = bayer_pixel[bayer_line_step + 1];
800  //rgb_pixel[rgb_line_step + 5] = bayer_pixel[line_step];
801 
802 }
803 
804 } // namespace image_proc
AVG
#define AVG(a, b)
Definition: edge_aware.cpp:36
image_proc::debayerEdgeAware
void debayerEdgeAware(const cv::Mat &bayer, cv::Mat &color)
Definition: edge_aware.cpp:44
image_proc::debayerEdgeAwareWeighted
void debayerEdgeAwareWeighted(const cv::Mat &bayer, cv::Mat &color)
Definition: edge_aware.cpp:426
AVG4
#define AVG4(a, b, c, d)
Definition: edge_aware.cpp:38
edge_aware.h
image_proc
Definition: advertisement_checker.h:39
std
AVG3
#define AVG3(a, b, c)
Definition: edge_aware.cpp:37
WAVG4
#define WAVG4(a, b, c, d, x, y)
Definition: edge_aware.cpp:39


image_proc
Author(s): Patrick Mihelich, Kurt Konolige, Jeremy Leibs
autogenerated on Wed Jan 24 2024 03:57:17