Sensor+ISP专栏-Demosaic

Sensor+ISP专栏-Demosaic

1.what is raw

raw图指的是从cmos sensor直接输出的原始图像,它本身没有颜色分量。

在CMOS Sensor中使用彩色滤镜阵列(color filter array,CFA) 的方式捕获彩色图像,每个感光像素的上面覆盖一个语物理像素相同面积大小,但分别只让红,绿,蓝光线透过的滤镜,这样RGB的领域的RGB信息都得到了保留,如下图,以最常见的RGGB pattern为例:
Sensor+ISP专栏-Demosaic_第1张图片
不同CFA来通过不同波长的光,最终通过插值来还原当前的颜色信息,极大的降低成本。

2.how to make a raw image to rgb img?

demoasic,即解马赛克
由RGB的分量的能量以及量子效率不同,最终pixel输出的AD值也不一样,raw图使用Image J打开之后看起来像一张加了马赛克的图像,如下图所示:
Sensor+ISP专栏-Demosaic_第2张图片
为了将raw图还原成带有颜色信息的rgb图像,一般会使用差值的方法将当前pixel的rgb信息还原。opencv中默认已经内置demosic函数。
笔者使用gpu写了一个简单的插值kernel,如下:

template<class pixel_t>
__global__ void demosic(pixel_t* raw, pixel_t* r, pixel_t* g, pixel_t* b, cfa_e cfa, int iw, int ih)
{
	int idx = blockDim.x * blockIdx.x + threadIdx.x;
	int idy = blockDim.y * blockIdx.y + threadIdx.y;

	if (idx < 1 || idy < 1 || idx > (iw - 2) || idy > (ih - 2)) {
		return;
	}

	int id = idy * iw + idx;

	pixel_t p0 = raw[(idy - 1) * iw + idx - 1];
	pixel_t p1 = raw[(idy - 1) * iw + idx];
	pixel_t p2 = raw[(idy - 1) * iw + idx + 1];
	pixel_t p3 = raw[(idy    ) * iw + idx - 1];
	pixel_t p4 = raw[(idy    ) * iw + idx];
	pixel_t p5 = raw[(idy    ) * iw + idx + 1];
	pixel_t p6 = raw[(idy + 1) * iw + idx - 1];
	pixel_t p7 = raw[(idy + 1) * iw + idx];
	pixel_t p8 = raw[(idy + 1) * iw + idx + 1];

	switch (pixel_pattern_lut[(uint8_t)cfa][idx % 2][idy % 2])
	{
	case p_raw_e::R:
		b[id] = (p0 + p2 + p6 + p8) >> 2;
		g[id] = (p1 + p3 + p5 + p7) >> 2;
		r[id] = p4;
		break;
	case p_raw_e::GR:
		b[id] = (p1 + p7) >> 1; 
		g[id] = p4;
		r[id] = (p3 + p5) >> 1;
		break;
	case p_raw_e::GB:
		b[id] = (p3 + p5) >> 1;
		g[id] = p4;
		r[id] = (p1 + p7) >> 1;
		break;
	case p_raw_e::B:
		b[id] = p4;
		g[id] = (p1 + p3 + p5 + p7) >> 2;
		r[id] = (p0 + p2 + p6 + p8) >> 2;
		break;
	default:
		break;
	}
}

3. others

其实还写了其他gpu isp kernel,暂不开源~~

你可能感兴趣的:(Sensor+Isp,车载CMOS,接口隔离原则,计算机视觉,opencv)