From a0f501fa5650d0b6062cc8f26b34bce11137643d Mon Sep 17 00:00:00 2001 From: Patrick Roth Date: Fri, 4 Oct 2019 11:51:48 +0200 Subject: initial commit import from github --- debayer.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 debayer.c (limited to 'debayer.c') diff --git a/debayer.c b/debayer.c new file mode 100644 index 0000000..1733496 --- /dev/null +++ b/debayer.c @@ -0,0 +1,243 @@ +/** +* @file debayer.c +* @brief demosaicing algorithms +* @author Patrick Roth - roth@stettbacher.ch +* @version 1.0 +* @date 2015-08-20 +* @copyright 2012-2016 Stettbacher Signal Processing AG +* +* @remarks +* +*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+* 
+* +*/ + +#include +#include "color_pipe_private.h" + + +/** + * Return bayer pattern type of next line. + * + * @param pattern current pattern type + * @param offset_height height offset in number of lines + * @param offset_width width offset in numbers of rows + * @return pattern type of next line + */ +static inline enum enumBayerPattern_t getBayerType(enum enumBayerPattern_t pattern, int offset_height, int offset_width) { + + int offset_y = offset_height%2; + int offset_x = offset_width%2; + + if(offset_y == 0 && offset_x == 0) { + // do nothing + } + else if(offset_y == 0 && offset_x == 1) { + if(pattern == BP_GR) { + pattern = BP_RG; + } + else if(pattern == BP_RG) { + pattern = BP_GR; + } + else if(pattern == BP_BG) { + pattern = BP_GB; + } + else if(pattern == BP_GB) { + pattern = BP_BG; + } + } + else if(offset_y == 1 && offset_x == 0) { + if(pattern == BP_GR) { + pattern = BP_BG; + } + else if(pattern == BP_RG) { + pattern = BP_GB; + } + else if(pattern == BP_BG) { + pattern = BP_GR; + } + else if(pattern == BP_GB) { + pattern = BP_RG; + } + } + else if(offset_y == 1 && offset_x == 1) { + if(pattern == BP_GR) { + pattern = BP_GB; + } + else if(pattern == BP_RG) { + pattern = BP_BG; + } + else if(pattern == BP_BG) { + pattern = BP_RG; + } + else if(pattern == BP_GB) { + pattern = BP_GR; + } + } + return pattern; +} + + +/** + * Calculate RGB value depening on 9 pixel value from bayer pattern. + * + * @param p11 upper left pixel + * @param p12 upper center pixel + * @param p13 upper right pixel + * @param p21 center left pixel + * @param p22 center center pixel + * @param p23 center right pixel + * @param p31 lower left pixel + * @param p32 lower center pixel + * @param p33 lower right pixel + * @param pattern current bayer pattern type, this value is adjusted to next expected type after return + * @param red On return: red pixel value + * @param green On return: green pixel value + * @param blue On return: blue pixel value + */ +static inline void calc_bilinear(int p11, int p12, int p13, + int p21, int p22, int p23, + int p31, int p32, int p33, + enum enumBayerPattern_t *pattern, + int *red, int *green, int *blue) { + + switch(*pattern) { + case BP_GR: // green-red-green-red-... + *red = (p21 + p23) >> 1; + *green = (p11 + p13 + p22*4 + p31 + p33) >> 3; + *blue = (p12 + p32) >> 1; + *pattern = BP_RG; + break; + + case BP_RG: // red-green-red-green-... + *red = p22; + *green = (p12 + p21 + p23 + p32) >> 2; + *blue = (p11 + p13 + p31 + p33) >> 2; + *pattern = BP_GR; + break; + + case BP_BG: // blue-green-blue-green-... + *red = (p11 + p13 + p31 + p33) >> 2; + *green = (p12 + p21 + p23 + p32) >> 2; + *blue = p22; + *pattern = BP_GB; + break; + + case BP_GB: // green-blue-green-blue-... + *red = (p12 + p32) >> 1; + *green = (p11 + p13 + p22*4 + p31 + p33) >> 3; + *blue = (p21 + p23) >> 1; + *pattern = BP_BG; + break; + } +} + + +/** + * Bilinear demosaicing algorithm for RGB image (16 bit per color channel). + * + * @param img_rgb On return: RGB image in R-G-B order + * @param img_bayer bayer image + * @param height image height in number of pixels + * @param width image width in number of pixels + * @param bayer_pattern first pixel starts with this pixel + * @return 0 on success otherwise -1 + */ +static void bilinear16(uint16_t *img_rgb, const uint16_t *img_bayer, const int height, const int width, const enum enumBayerPattern_t bayer_pattern) +#include "alg_debayer_bilinear.h" + + +/** + * Bilinear demosaicing algorithm for RGB image (8 bit per color channel). + * + * @param img_rgb On return: RGB image in R-G-B order + * @param img_bayer bayer image + * @param height image height in number of pixels + * @param width image width in number of pixels + * @param bayer_pattern first pixel starts with this pixel + * @return 0 on success otherwise -1 + */ +static void bilinear8(uint8_t *img_rgb, const uint8_t *img_bayer, const int height, const int width, const enum enumBayerPattern_t bayer_pattern) +#include "alg_debayer_bilinear.h" + + +/** + * Bilinear demosaicing wrapper function used to select pixel-bit-depth dependet algrotihm. + * + * @param img_rgb On return: RGB image in R-G-B order + * @param img_bayer bayer image + * @param height image height in number of pixels + * @param width image width in number of pixels + * @param data_format image data format + * @param bayer_pattern first pixel starts with this pixel + * @return 0 on success otherwise -1 + */ +static int bilinear_wrapper(void *img_rgb, const void *img_bayer, const int height, const int width, + const enum enumDataFormat_t data_format, const enum enumBayerPattern_t bayer_pattern) { + if(data_format == DF_RAW_BAYER_8) { + bilinear8(img_rgb, img_bayer, height, width, bayer_pattern); + } + else if(data_format == DF_RAW_BAYER_12 || data_format == DF_HDR_BAYER_20_COMP) { + bilinear16(img_rgb, img_bayer, height, width, bayer_pattern); + } + else { + printf("%s: image data format %d unknown\n", __func__, data_format); + return -1; + } + return 0; +} + + +/** + * Bayer to RGB image conversion algrithm (demosaicing) + * + * @param debayer_data required data for debayering + * @return 0 on success otherwise -1 + */ +int debayer(struct debayer_data_t *debayer_data) { + + void *img_rgb, *img_raw; + int ret, height, width; + enum enumDataFormat_t data_format; + enum enumBayerPattern_t bayer_pattern; + enum bayer_alg_t alg; + + ret = 0; + img_rgb = debayer_data->img_rgb; + img_raw = debayer_data->img_raw; + height = debayer_data->height; + width = debayer_data->width; + data_format = debayer_data->format; + bayer_pattern = debayer_data->start_pattern; + alg = debayer_data->alg; + + if(data_format == DF_RAW_MONO_8 || data_format == DF_RAW_MONO_12 || data_format == DF_HDR_MONO_20_COMP) { + printf("%s: No debayering is done on monochrome image (image data format %d)\n", __func__, data_format); + return -1; + } + + switch(alg) { + case BAYER_ALG_BILINEAR: + ret = bilinear_wrapper(img_rgb, img_raw, height, width, data_format, bayer_pattern); + break; + + default: + printf("%s: Debayer algorithm %d not implemented yet\n", __func__, alg); + ret = -1; + } + return ret; +} \ No newline at end of file -- cgit v1.2.1