Bayer格式转RGB的代码,好像是来自于v4l
/* bayer第一行 adjacent_bayer第二行 */ static void convert_border_bayer_line_to_bgr24(const unsigned char *bayer, const unsigned char *adjacent_bayer, unsigned char *bgr, int width, int start_with_green, int blue_line) { int t0, t1; if (start_with_green) { /* First pixel */ if (blue_line) { *bgr++ = bayer[1]; *bgr++ = bayer[0]; *bgr++ = adjacent_bayer[0]; } else { *bgr++ = adjacent_bayer[0]; *bgr++ = bayer[0]; *bgr++ = bayer[1]; } /* Second pixel */ t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3; t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1; if (blue_line) { *bgr++ = bayer[1]; *bgr++ = t0; *bgr++ = t1; } else { *bgr++ = t1; *bgr++ = t0; *bgr++ = bayer[1]; } bayer++; adjacent_bayer++; width -= 2; } else { /* First pixel */ t0 = (bayer[1] + adjacent_bayer[0] + 1) >> 1; if (blue_line) { *bgr++ = bayer[0]; *bgr++ = t0; *bgr++ = adjacent_bayer[1]; } else { *bgr++ = adjacent_bayer[1]; *bgr++ = t0; *bgr++ = bayer[0]; } width--; } if (blue_line) { for ( ; width > 2; width -= 2) { t0 = (bayer[0] + bayer[2] + 1) >> 1; *bgr++ = t0; *bgr++ = bayer[1]; *bgr++ = adjacent_bayer[1]; bayer++; adjacent_bayer++; t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3; t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1; *bgr++ = bayer[1]; *bgr++ = t0; *bgr++ = t1; bayer++; adjacent_bayer++; } } else { for ( ; width > 2; width -= 2) { t0 = (bayer[0] + bayer[2] + 1) >> 1; *bgr++ = adjacent_bayer[1]; *bgr++ = bayer[1]; *bgr++ = t0; bayer++; adjacent_bayer++; t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3; t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1; *bgr++ = t1; *bgr++ = t0; *bgr++ = bayer[1]; bayer++; adjacent_bayer++; } } if (width == 2) { /* Second to last pixel */ t0 = (bayer[0] + bayer[2] + 1) >> 1; if (blue_line) { *bgr++ = t0; *bgr++ = bayer[1]; *bgr++ = adjacent_bayer[1]; } else { *bgr++ = adjacent_bayer[1]; *bgr++ = bayer[1]; *bgr++ = t0; } /* Last pixel */ t0 = (bayer[1] + adjacent_bayer[2] + 1) >> 1; if (blue_line) { *bgr++ = bayer[2]; *bgr++ = t0; *bgr++ = adjacent_bayer[1]; } else { *bgr++ = adjacent_bayer[1]; *bgr++ = t0; *bgr++ = bayer[2]; } } else { /* Last pixel */ if (blue_line) { *bgr++ = bayer[0]; *bgr++ = bayer[1]; *bgr++ = adjacent_bayer[1]; } else { *bgr++ = adjacent_bayer[1]; *bgr++ = bayer[1]; *bgr++ = bayer[0]; } } } void ConvertBayer2RGB24(const unsigned char *bayer, unsigned char *bgr, int width, int height,int start_with_green, int blue_line) { /* render the first line */ convert_border_bayer_line_to_bgr24(bayer, bayer + width, bgr, width, start_with_green, blue_line); bgr += width * 3; /* reduce height by 2 because of the special case top/bottom line */ for (height -= 2; height; height--) { int t0, t1; /* (width - 2) because of the border */ const unsigned char *bayer_end = bayer + (width - 2); if (start_with_green) { /* OpenCV has a bug in the next line, which was t0 = (bayer[0] + bayer[width * 2] + 1) >> 1; */ t0 = (bayer[1] + bayer[width * 2 + 1] + 1) >> 1; /* Write first pixel */ t1 = (bayer[0] + bayer[width * 2] + bayer[width + 1] + 1) / 3; if (blue_line) { *bgr++ = t0; *bgr++ = t1; *bgr++ = bayer[width]; } else { *bgr++ = bayer[width]; *bgr++ = t1; *bgr++ = t0; } /* Write second pixel */ t1 = (bayer[width] + bayer[width + 2] + 1) >> 1; if (blue_line) { *bgr++ = t0; *bgr++ = bayer[width + 1]; *bgr++ = t1; } else { *bgr++ = t1; *bgr++ = bayer[width + 1]; *bgr++ = t0; } bayer++; } else { /* Write first pixel */ t0 = (bayer[0] + bayer[width * 2] + 1) >> 1; if (blue_line) { *bgr++ = t0; *bgr++ = bayer[width]; *bgr++ = bayer[width + 1]; } else { *bgr++ = bayer[width + 1]; *bgr++ = bayer[width]; *bgr++ = t0; } } if (blue_line) { for (; bayer <= bayer_end - 2; bayer += 2) { t0 = (bayer[0] + bayer[2] + bayer[width * 2] + bayer[width * 2 + 2] + 2) >> 2; t1 = (bayer[1] + bayer[width] + bayer[width + 2] + bayer[width * 2 + 1] + 2) >> 2; *bgr++ = t0; *bgr++ = t1; *bgr++ = bayer[width + 1]; t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1; t1 = (bayer[width + 1] + bayer[width + 3] + 1) >> 1; *bgr++ = t0; *bgr++ = bayer[width + 2]; *bgr++ = t1; } } else { for (; bayer <= bayer_end - 2; bayer += 2) { t0 = (bayer[0] + bayer[2] + bayer[width * 2] + bayer[width * 2 + 2] + 2) >> 2; t1 = (bayer[1] + bayer[width] + bayer[width + 2] + bayer[width * 2 + 1] + 2) >> 2; *bgr++ = bayer[width + 1]; *bgr++ = t1; *bgr++ = t0; t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1; t1 = (bayer[width + 1] + bayer[width + 3] + 1) >> 1; *bgr++ = t1; *bgr++ = bayer[width + 2]; *bgr++ = t0; } } if (bayer < bayer_end) { /* write second to last pixel */ t0 = (bayer[0] + bayer[2] + bayer[width * 2] + bayer[width * 2 + 2] + 2) >> 2; t1 = (bayer[1] + bayer[width] + bayer[width + 2] + bayer[width * 2 + 1] + 2) >> 2; if (blue_line) { *bgr++ = t0; *bgr++ = t1; *bgr++ = bayer[width + 1]; } else { *bgr++ = bayer[width + 1]; *bgr++ = t1; *bgr++ = t0; } /* write last pixel */ t0 = (bayer[2] + bayer[width * 2 + 2] + 1) >> 1; if (blue_line) { *bgr++ = t0; *bgr++ = bayer[width + 2]; *bgr++ = bayer[width + 1]; } else { *bgr++ = bayer[width + 1]; *bgr++ = bayer[width + 2]; *bgr++ = t0; } bayer++; } else { /* write last pixel */ t0 = (bayer[0] + bayer[width * 2] + 1) >> 1; t1 = (bayer[1] + bayer[width * 2 + 1] + bayer[width] + 1) / 3; if (blue_line) { *bgr++ = t0; *bgr++ = t1; *bgr++ = bayer[width + 1]; } else { *bgr++ = bayer[width + 1]; *bgr++ = t1; *bgr++ = t0; } } /* skip 2 border pixels */ bayer += 2; blue_line = !blue_line; start_with_green = !start_with_green; } /* render the last line */ convert_border_bayer_line_to_bgr24(bayer + width, bayer, bgr, width, !start_with_green, !blue_line); }
两个关键参数start_with_green和blue_line,我用的BayerBG格式start_with_green=0,blue_line=0。

浙公网安备 33010602011771号