bayer插值算法(4):边缘感应算法

目录

前言

插值算法

边缘感应插值算法

代码示例


前言

相机生成的图像一般是bayer阵列的raw图,这时候如果转换成我们需要的rgb图像,就需要对应的bayer插值算法将丢失的rgb信息通过算法补齐

插值算法

常见的插值算法一般有如下几种

  • 邻近插值算法
  • 双线性插值算法
  • 高质量线性插值算法
  • 边缘感应算法
  • VNG算法(这里暂不介绍)
  • AHD算法(这里暂不介绍)

边缘感应插值算法

由于边缘感应插值算法用很多,主要不同的点是边缘处如何检测,本文的方法依赖以下的论文,有兴趣的小伙伴可以看一下这个论文,链接在下方

依赖的论文

代码示例

void ClearBorders(uint8_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;
    }

    int low = sx * (w - 1) * 3 - 1 + w * 3;
    i = low + sx * (sy - w * 2 + 1) * 3;
    while (i > low) {
        j = 6 * w;
        while (j > 0) {
            rgb[i--] = 0;
            j--;
        }
        i -= (sx - 2 * w) * 3;
    }
}

int bayer_EdgeSense(const uint8_t *B2R_RESTRICT bayer, uint8_t *B2R_RESTRICT rgb, int sx, int sy, int tile)
{
	uint8_t *outR, *outG, *outB;
    B2R_REGISTER int i3, j3, base;
    int i, j;
    int dh, dv;
    int tmp;
	int sx3=sx*3;

    // sx and sy should be even
    switch (tile) {
    case DC1394_COLOR_FILTER_GRBG:
    case DC1394_COLOR_FILTER_BGGR:
        outR = &rgb[0];
        outG = &rgb[1];
        outB = &rgb[2];
        break;
    case DC1394_COLOR_FILTER_GBRG:
    case DC1394_COLOR_FILTER_RGGB:
        outR = &rgb[2];
        outG = &rgb[1];
        outB = &rgb[0];
        break;
    default:
		return DC1394_INVALID_COLOR_FILTER;
    }

    switch (tile) {
    case DC1394_COLOR_FILTER_GRBG:        //---------------------------------------------------------
    case DC1394_COLOR_FILTER_GBRG:
        // copy original RGB data to output images
		for (i = 0, i3=0; i < sy*sx; i += (sx<<1), i3 += (sx3<<1)) {
			for (j = 0, j3=0; j < sx; j += 2, j3+=6) {
				base=i3+j3;
				outG[base]           = bayer[i + j];
				outG[base + sx3 + 3] = bayer[i + j + sx + 1];
				outR[base + 3]       = bayer[i + j + 1];
				outB[base + sx3]     = bayer[i + j + sx];
			}
		}
		// process GREEN channel
		for (i3= 3*sx3; i3 < (sy - 2)*sx3; i3 += (sx3<<1)) {
			for (j3=6; j3 < sx3 - 9; j3+=6) {
				base=i3+j3;
				dh = abs(((outB[base - 6] +
						   outB[base + 6]) >> 1) -
						   outB[base]);
				dv = abs(((outB[base - (sx3<<1)] +
						   outB[base + (sx3<<1)]) >> 1) -
						   outB[base]);
				tmp = (((outG[base - 3]   + outG[base + 3]) >> 1) * (dh<=dv) +
					   ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh>dv));
				//tmp = (dh==dv) ? tmp>>1 : tmp;
				CLIP(tmp, outG[base]);
			}
		}
		
		for (i3=2*sx3; i3 < (sy - 3)*sx3; i3 += (sx3<<1)) {
			for (j3=9; j3 < sx3 - 6; j3+=6) {
				base=i3+j3;
				dh = abs(((outR[base - 6] +
						   outR[base + 6]) >>1 ) -
						   outR[base]);
				dv = abs(((outR[base - (sx3<<1)] +
						   outR[base + (sx3<<1)]) >>1 ) -
						   outR[base]);
				tmp = (((outG[base - 3]   + outG[base + 3]) >> 1) * (dh<=dv) +
					   ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh>dv));
				//tmp = (dh==dv) ? tmp>>1 : tmp;
				CLIP(tmp, outG[base]);
			}
		}
		// process RED channel
		for (i3=0; i3 < (sy - 1)*sx3; i3 += (sx3<<1)) {
			for (j3=6; j3 < sx3 - 3; j3+=6) {
				base=i3+j3;
				tmp = outG[base] +
					((outR[base - 3] -
					  outG[base - 3] +
					  outR[base + 3] -
					  outG[base + 3]) >> 1);
				CLIP(tmp, outR[base]);
			}
		}
		for (i3=sx3; i3 < (sy - 2)*sx3; i3 += (sx3<<1)) {
			for (j3=3; j3 < sx3; j3+=6) {
				base=i3+j3;
				tmp = outG[base] +
					((outR[base - sx3] -
					  outG[base - sx3] +
					  outR[base + sx3] -
					  outG[base + sx3]) >> 1);
				CLIP(tmp, outR[base]);
			}
			for (j3=6; j3 < sx3 - 3; j3+=6) {
				base=i3+j3;
				tmp = outG[base] +
					((outR[base - sx3 - 3] -
					  outG[base - sx3 - 3] +
					  outR[base - sx3 + 3] -
					  outG[base - sx3 + 3] +
					  outR[base + sx3 - 3] -
					  outG[base + sx3 - 3] +
					  outR[base + sx3 + 3] -
					  outG[base + sx3 + 3]) >> 2);
				CLIP(tmp, outR[base]);
			}
		}

		// process BLUE channel
		for (i3=sx3; i3 < sy*sx3; i3 += (sx3<<1)) {
			for (j3=3; j3 < sx3 - 6; j3+=6) {
				base=i3+j3;
				tmp = outG[base] +
					((outB[base - 3] -
					  outG[base - 3] +
					  outB[base + 3] -
					  outG[base + 3]) >> 1);
				CLIP(tmp, outB[base]);
			}
		}
		for (i3=2*sx3; i3 < (sy - 1)*sx3; i3 += (sx3<<1)) {
			for (j3=0; j3 < sx3 - 3; j3+=6) {
				base=i3+j3;
				tmp = outG[base] +
					((outB[base - sx3] -
					  outG[base - sx3] +
					  outB[base + sx3] -
					  outG[base + sx3]) >> 1);
				CLIP(tmp, outB[base]);
			}
			for (j3=3; j3 < sx3 - 6; j3+=6) {
				base=i3+j3;
				tmp = outG[base] +
					((outB[base - sx3 - 3] -
					  outG[base - sx3 - 3] +
					  outB[base - sx3 + 3] -
					  outG[base - sx3 + 3] +
					  outB[base + sx3 - 3] -
					  outG[base + sx3 - 3] +
					  outB[base + sx3 + 3] -
					  outG[base + sx3 + 3]) >> 2);
				CLIP(tmp, outB[base]);
			}
		}
		break;

    case DC1394_COLOR_FILTER_BGGR:        //---------------------------------------------------------
    case DC1394_COLOR_FILTER_RGGB:
        // copy original RGB data to output images
		for (i = 0, i3=0; i < sy*sx; i += (sx<<1), i3 += (sx3<<1)) {
			for (j = 0, j3=0; j < sx; j += 2, j3+=6) {
				base=i3+j3;
				outB[base] = bayer[i + j];
				outR[base + sx3 + 3] = bayer[i + sx + (j + 1)];
				outG[base + 3] = bayer[i + j + 1];
				outG[base + sx3] = bayer[i + sx + j];
			}
		}
		// process GREEN channel
		for (i3=2*sx3; i3 < (sy - 2)*sx3; i3 += (sx3<<1)) {
			for (j3=6; j3 < sx3 - 9; j3+=6) {
				base=i3+j3;
				dh = abs(((outB[base - 6] +
						   outB[base + 6]) >> 1) -
						   outB[base]);
				dv = abs(((outB[base - (sx3<<1)] +
						   outB[base + (sx3<<1)]) >> 1) -
						   outB[base]);
				tmp = (((outG[base - 3]   + outG[base + 3]) >> 1) * (dh<=dv) +
					   ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh>dv));
				//tmp = (dh==dv) ? tmp>>1 : tmp;
				CLIP(tmp, outG[base]);
			}
		}
		for (i3=3*sx3; i3 < (sy - 3)*sx3; i3 += (sx3<<1)) {
			for (j3=9; j3 < sx3 - 6; j3+=6) {
				base=i3+j3;
				dh = abs(((outR[base - 6] +
						   outR[base + 6]) >> 1) -
						   outR[base]);
				dv = abs(((outR[base - (sx3<<1)] +
						   outR[base + (sx3<<1)]) >> 1) -
						   outR[base]);
				tmp = (((outG[base - 3]   + outG[base + 3]) >> 1) * (dh<=dv) +
					   ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh>dv));
				//tmp = (dh==dv) ? tmp>>1 : tmp;
				CLIP(tmp, outG[base]);
			}
		}
		// process RED channel
		for (i3=sx3; i3 < (sy - 1)*sx3; i3 += (sx3<<1)) {        // G-points (1/2)
			for (j3=6; j3 < sx3 - 3; j3+=6) {
				base=i3+j3;
				tmp = outG[base] +
					((outR[base - 3] -
					  outG[base - 3] +
					  outR[base + 3] -
					  outG[base + 3]) >>1);
				CLIP(tmp, outR[base]);
			}
		}
		for (i3=2*sx3; i3 < (sy - 2)*sx3; i3 += (sx3<<1)) {
			for (j3=3; j3 < sx3; j3+=6) {        // G-points (2/2)
				base=i3+j3;
				tmp = outG[base] +
					((outR[base - sx3] -
					  outG[base - sx3] +
					  outR[base + sx3] -
					  outG[base + sx3]) >> 1);
				CLIP(tmp, outR[base]);
			}
			for (j3=6; j3 < sx3 - 3; j3+=6) {        // B-points
				base=i3+j3;
				tmp = outG[base] +
					((outR[base - sx3 - 3] -
					  outG[base - sx3 - 3] +
					  outR[base - sx3 + 3] -
					  outG[base - sx3 + 3] +
					  outR[base + sx3 - 3] -
					  outG[base + sx3 - 3] +
					  outR[base + sx3 + 3] -
					  outG[base + sx3 + 3]) >> 2);
				CLIP(tmp, outR[base]);
			}
		}

		// process BLUE channel
		for (i = 0,i3=0; i < sy*sx; i += (sx<<1), i3 += (sx3<<1)) {
			for (j = 1, j3=3; j < sx - 2; j += 2, j3+=6) {
				base=i3+j3;
				tmp = outG[base] +
					((outB[base - 3] -
					  outG[base - 3] +
					  outB[base + 3] -
					  outG[base + 3]) >> 1);
				CLIP(tmp, outB[base]);
			}
		}
		for (i3=sx3; i3 < (sy - 1)*sx3; i3 += (sx3<<1)) {
			for (j3=0; j3 < sx3 - 3; j3+=6) {
				base=i3+j3;
				tmp = outG[base] +
					((outB[base - sx3] -
					  outG[base - sx3] +
					  outB[base + sx3] -
					  outG[base + sx3]) >> 1);
				CLIP(tmp, outB[base]);
			}
			for (j3=3; j3 < sx3 - 6; j3+=6) {
				base=i3+j3;
				tmp = outG[base] +
					((outB[base - sx3 - 3] -
					  outG[base - sx3 - 3] +
					  outB[base - sx3 + 3] -
					  outG[base - sx3 + 3] +
					  outB[base + sx3 - 3] -
					  outG[base + sx3 - 3] +
					  outB[base + sx3 + 3] -
					  outG[base + sx3 + 3]) >> 2);
				CLIP(tmp, outB[base]);
			}
		}
		break;
    }

    ClearBorders(rgb, sx, sy, 3);

    return 0;
}

你可能感兴趣的:(编解码,图像处理,视频编解码)