⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dc1394_bayer.c

📁 This library provides functionality to control any camera that conforms to the 1394-Based Digital C
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * 1394-Based Digital Camera Control Library * Bayer pattern decoding functions * Copyright (C) Damien Douxchamps <ddouxchamps@users.sf.net> *  * Written by Damien Douxchamps and Frederic Devernay * * The original VNG Bayer decoding is from Dave Coffin's DCRAW. *  * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <limits.h>#include "dc1394_conversions.h"#define CLIP(in, out)\   in = in < 0 ? 0 : in;\   in = in > 255 ? 255 : in;\   out=in;  #define CLIP16(in, out, bits)\   in = in < 0 ? 0 : in;\   in = in > ((1<<bits)-1) ? ((1<<bits)-1) : in;\   out=in;  voidClearBorders(uchar_t *rgb, int sx, int sy, int w){    int i, j;    // black edges are added with a width w:    i = 3 * sx * w - 1;    j = 3 * sx * sy - 1;    while (i >= 0) {	rgb[i--] = 0;	rgb[j--] = 0;    }    i = sx * (sy - 1) * 3 - 1 + w * 3;    while (i > sx) {	j = 6 * w;	while (j > 0) {	    rgb[i--] = 0;	    j--;	}	i -= (sx - 2 * w) * 3;    }}voidClearBorders_uint16(uint16_t * rgb, int sx, int sy, int w){    int i, j;    // black edges:    i = 3 * sx * w - 1;    j = 3 * sx * sy - 1;    while (i >= 0) {	rgb[i--] = 0;	rgb[j--] = 0;    }    i = sx * (sy - 1) * 3 - 1 + w * 3;    while (i > sx) {	j = 6 * w;	while (j > 0) {	    rgb[i--] = 0;	    j--;	}	i -= (sx - 2 * w) * 3;    }}/************************************************************** *     Color conversion functions for cameras that can        *  * output raw-Bayer pattern images, such as some Basler and   * * Point Grey camera. Most of the algos presented here come   * * from http://www-ise.stanford.edu/~tingchen/ and have been  * * converted from Matlab to C and extended to all elementary  * * patterns.                                                  * **************************************************************//* 8-bits versions *//* insprired by OpenCV's Bayer decoding */voiddc1394_bayer_NearestNeighbor(const uchar_t *restrict bayer, uchar_t *restrict rgb, int sx, int sy, int tile){    const int bayerStep = sx;    const int rgbStep = 3 * sx;    int width = sx;    int height = sy;    int blue = tile == DC1394_COLOR_FILTER_BGGR	|| tile == DC1394_COLOR_FILTER_GBRG ? -1 : 1;    int start_with_green = tile == DC1394_COLOR_FILTER_GBRG	|| tile == DC1394_COLOR_FILTER_GRBG;    int i, imax, iinc;    /* add black border */    imax = sx * sy * 3;    for (i = sx * (sy - 1) * 3; i < imax; i++) {	rgb[i] = 0;    }    iinc = (sx - 1) * 3;    for (i = (sx - 1) * 3; i < imax; i += iinc) {	rgb[i++] = 0;	rgb[i++] = 0;	rgb[i++] = 0;    }    rgb += 1;    width -= 1;    height -= 1;    for (; height--; bayer += bayerStep, rgb += rgbStep) {      //int t0, t1;	const uchar_t *bayerEnd = bayer + width;        if (start_with_green) {            rgb[-blue] = bayer[1];            rgb[0] = bayer[bayerStep + 1];            rgb[blue] = bayer[bayerStep];            bayer++;            rgb += 3;        }        if (blue > 0) {            for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) {                rgb[-1] = bayer[0];                rgb[0] = bayer[1];                rgb[1] = bayer[bayerStep + 1];                rgb[2] = bayer[2];                rgb[3] = bayer[bayerStep + 2];                rgb[4] = bayer[bayerStep + 1];            }        } else {            for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) {                rgb[1] = bayer[0];                rgb[0] = bayer[1];                rgb[-1] = bayer[bayerStep + 1];                rgb[4] = bayer[2];                rgb[3] = bayer[bayerStep + 2];                rgb[2] = bayer[bayerStep + 1];            }        }        if (bayer < bayerEnd) {            rgb[-blue] = bayer[0];            rgb[0] = bayer[1];            rgb[blue] = bayer[bayerStep + 1];            bayer++;            rgb += 3;        }	bayer -= width;	rgb -= width * 3;	blue = -blue;	start_with_green = !start_with_green;    }}/* OpenCV's Bayer decoding */voiddc1394_bayer_Bilinear(const uchar_t *restrict bayer, uchar_t *restrict rgb, int sx, int sy, int tile){    const int bayerStep = sx;    const int rgbStep = 3 * sx;    int width = sx;    int height = sy;    /*       the two letters  of the OpenCV name are respectively       the 4th and 3rd letters from the blinky name,       and we also have to switch R and B (OpenCV is BGR)       CV_BayerBG2BGR <-> DC1394_COLOR_FILTER_BGGR       CV_BayerGB2BGR <-> DC1394_COLOR_FILTER_GBRG       CV_BayerGR2BGR <-> DC1394_COLOR_FILTER_GRBG       int blue = tile == CV_BayerBG2BGR || tile == CV_BayerGB2BGR ? -1 : 1;       int start_with_green = tile == CV_BayerGB2BGR || tile == CV_BayerGR2BGR;     */    int blue = tile == DC1394_COLOR_FILTER_BGGR	|| tile == DC1394_COLOR_FILTER_GBRG ? -1 : 1;    int start_with_green = tile == DC1394_COLOR_FILTER_GBRG	|| tile == DC1394_COLOR_FILTER_GRBG;    ClearBorders(rgb, sx, sy, 1);    rgb += rgbStep + 3 + 1;    height -= 2;    width -= 2;    for (; height--; bayer += bayerStep, rgb += rgbStep) {	int t0, t1;	const uchar_t *bayerEnd = bayer + width;	if (start_with_green) {	    /* OpenCV has a bug in the next line, which was	       t0 = (bayer[0] + bayer[bayerStep * 2] + 1) >> 1; */	    t0 = (bayer[1] + bayer[bayerStep * 2 + 1] + 1) >> 1;	    t1 = (bayer[bayerStep] + bayer[bayerStep + 2] + 1) >> 1;	    rgb[-blue] = (uchar_t) t0;	    rgb[0] = bayer[bayerStep + 1];	    rgb[blue] = (uchar_t) t1;	    bayer++;	    rgb += 3;	}	if (blue > 0) {	    for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) {		t0 = (bayer[0] + bayer[2] + bayer[bayerStep * 2] +		      bayer[bayerStep * 2 + 2] + 2) >> 2;		t1 = (bayer[1] + bayer[bayerStep] +		      bayer[bayerStep + 2] + bayer[bayerStep * 2 + 1] +		      2) >> 2;		rgb[-1] = (uchar_t) t0;		rgb[0] = (uchar_t) t1;		rgb[1] = bayer[bayerStep + 1];		t0 = (bayer[2] + bayer[bayerStep * 2 + 2] + 1) >> 1;		t1 = (bayer[bayerStep + 1] + bayer[bayerStep + 3] +		      1) >> 1;		rgb[2] = (uchar_t) t0;		rgb[3] = bayer[bayerStep + 2];		rgb[4] = (uchar_t) t1;	    }	} else {	    for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) {		t0 = (bayer[0] + bayer[2] + bayer[bayerStep * 2] +		      bayer[bayerStep * 2 + 2] + 2) >> 2;		t1 = (bayer[1] + bayer[bayerStep] +		      bayer[bayerStep + 2] + bayer[bayerStep * 2 + 1] +		      2) >> 2;		rgb[1] = (uchar_t) t0;		rgb[0] = (uchar_t) t1;		rgb[-1] = bayer[bayerStep + 1];		t0 = (bayer[2] + bayer[bayerStep * 2 + 2] + 1) >> 1;		t1 = (bayer[bayerStep + 1] + bayer[bayerStep + 3] +		      1) >> 1;		rgb[4] = (uchar_t) t0;		rgb[3] = bayer[bayerStep + 2];		rgb[2] = (uchar_t) t1;	    }	}	if (bayer < bayerEnd) {	    t0 = (bayer[0] + bayer[2] + bayer[bayerStep * 2] +		  bayer[bayerStep * 2 + 2] + 2) >> 2;	    t1 = (bayer[1] + bayer[bayerStep] +		  bayer[bayerStep + 2] + bayer[bayerStep * 2 + 1] +		  2) >> 2;	    rgb[-blue] = (uchar_t) t0;	    rgb[0] = (uchar_t) t1;	    rgb[blue] = bayer[bayerStep + 1];	    bayer++;	    rgb += 3;	}	bayer -= width;	rgb -= width * 3;	blue = -blue;	start_with_green = !start_with_green;    }}/* High-Quality Linear Interpolation For Demosaicing Of   Bayer-Patterned Color Images, by Henrique S. Malvar, Li-wei He, and   Ross Cutler, in ICASSP'04 */voiddc1394_bayer_HQLinear(const uchar_t *restrict bayer, uchar_t *restrict rgb, int sx, int sy, int tile){    const int bayerStep = sx;    const int rgbStep = 3 * sx;    int width = sx;    int height = sy;    int blue = tile == DC1394_COLOR_FILTER_BGGR	|| tile == DC1394_COLOR_FILTER_GBRG ? -1 : 1;    int start_with_green = tile == DC1394_COLOR_FILTER_GBRG	|| tile == DC1394_COLOR_FILTER_GRBG;    ClearBorders(rgb, sx, sy, 2);    rgb += 2 * rgbStep + 6 + 1;    height -= 4;    width -= 4;    /* We begin with a (+1 line,+1 column) offset with respect to bilinear decoding, so start_with_green is the same, but blue is opposite */    blue = -blue;    for (; height--; bayer += bayerStep, rgb += rgbStep) {	int t0, t1;	const uchar_t *bayerEnd = bayer + width;	const int bayerStep2 = bayerStep * 2;	const int bayerStep3 = bayerStep * 3;	const int bayerStep4 = bayerStep * 4;	if (start_with_green) {	    /* at green pixel */	    rgb[0] = bayer[bayerStep2 + 2];	    t0 = rgb[0] * 5		+ ((bayer[bayerStep + 2] + bayer[bayerStep3 + 2]) << 2)		- bayer[2]		- bayer[bayerStep + 1]		- bayer[bayerStep + 3]		- bayer[bayerStep3 + 1]		- bayer[bayerStep3 + 3]		- bayer[bayerStep4 + 2]		+ ((bayer[bayerStep2] + bayer[bayerStep2 + 4] + 1) >> 1);	    t1 = rgb[0] * 5 +		((bayer[bayerStep2 + 1] + bayer[bayerStep2 + 3]) << 2)		- bayer[bayerStep2]		- bayer[bayerStep + 1]		- bayer[bayerStep + 3]		- bayer[bayerStep3 + 1]		- bayer[bayerStep3 + 3]		- bayer[bayerStep2 + 4]		+ ((bayer[2] + bayer[bayerStep4 + 2] + 1) >> 1);	    t0 = (t0 + 4) >> 3;	    CLIP(t0, rgb[-blue]);	    t1 = (t1 + 4) >> 3;	    CLIP(t1, rgb[blue]);	    bayer++;	    rgb += 3;	}	if (blue > 0) {	    for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) {		/* B at B */		rgb[1] = bayer[bayerStep2 + 2];		/* R at B */		t0 = ((bayer[bayerStep + 1] + bayer[bayerStep + 3] +		       bayer[bayerStep3 + 1] + bayer[bayerStep3 + 3]) << 1)		    -		    (((bayer[2] + bayer[bayerStep2] +		       bayer[bayerStep2 + 4] + bayer[bayerStep4 +						     2]) * 3 + 1) >> 1)		    + rgb[1] * 6;		/* G at B */		t1 = ((bayer[bayerStep + 2] + bayer[bayerStep2 + 1] +		       bayer[bayerStep2 + 3] + bayer[bayerStep3 + 2]) << 1)		    - (bayer[2] + bayer[bayerStep2] +		       bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2])		    + (rgb[1] << 2);		t0 = (t0 + 4) >> 3;		CLIP(t0, rgb[-1]);		t1 = (t1 + 4) >> 3;		CLIP(t1, rgb[0]);		/* at green pixel */		rgb[3] = bayer[bayerStep2 + 3];		t0 = rgb[3] * 5		    + ((bayer[bayerStep + 3] + bayer[bayerStep3 + 3]) << 2)		    - bayer[3]		    - bayer[bayerStep + 2]		    - bayer[bayerStep + 4]		    - bayer[bayerStep3 + 2]		    - bayer[bayerStep3 + 4]		    - bayer[bayerStep4 + 3]		    +		    ((bayer[bayerStep2 + 1] + bayer[bayerStep2 + 5] +		      1) >> 1);		t1 = rgb[3] * 5 +		    ((bayer[bayerStep2 + 2] + bayer[bayerStep2 + 4]) << 2)		    - bayer[bayerStep2 + 1]		    - bayer[bayerStep + 2]		    - bayer[bayerStep + 4]		    - bayer[bayerStep3 + 2]		    - bayer[bayerStep3 + 4]		    - bayer[bayerStep2 + 5]		    + ((bayer[3] + bayer[bayerStep4 + 3] + 1) >> 1);		t0 = (t0 + 4) >> 3;		CLIP(t0, rgb[2]);		t1 = (t1 + 4) >> 3;		CLIP(t1, rgb[4]);	    }	} else {	    for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) {		/* R at R */		rgb[-1] = bayer[bayerStep2 + 2];		/* B at R */		t0 = ((bayer[bayerStep + 1] + bayer[bayerStep + 3] +		       bayer[bayerStep3 + 1] + bayer[bayerStep3 + 3]) << 1)		    -		    (((bayer[2] + bayer[bayerStep2] +		       bayer[bayerStep2 + 4] + bayer[bayerStep4 +						     2]) * 3 + 1) >> 1)		    + rgb[-1] * 6;		/* G at R */		t1 = ((bayer[bayerStep + 2] + bayer[bayerStep2 + 1] +		       bayer[bayerStep2 + 3] + bayer[bayerStep * 3 +						     2]) << 1)		    - (bayer[2] + bayer[bayerStep2] +		       bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2])		    + (rgb[-1] << 2);		t0 = (t0 + 4) >> 3;		CLIP(t0, rgb[1]);		t1 = (t1 + 4) >> 3;		CLIP(t1, rgb[0]);		/* at green pixel */		rgb[3] = bayer[bayerStep2 + 3];		t0 = rgb[3] * 5		    + ((bayer[bayerStep + 3] + bayer[bayerStep3 + 3]) << 2)		    - bayer[3]		    - bayer[bayerStep + 2]		    - bayer[bayerStep + 4]		    - bayer[bayerStep3 + 2]		    - bayer[bayerStep3 + 4]		    - bayer[bayerStep4 + 3]		    +		    ((bayer[bayerStep2 + 1] + bayer[bayerStep2 + 5] +		      1) >> 1);		t1 = rgb[3] * 5 +		    ((bayer[bayerStep2 + 2] + bayer[bayerStep2 + 4]) << 2)		    - bayer[bayerStep2 + 1]		    - bayer[bayerStep + 2]		    - bayer[bayerStep + 4]		    - bayer[bayerStep3 + 2]		    - bayer[bayerStep3 + 4]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -