马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
1. Len shading1.1 Lens CRA首先我们要明确一个概念CRA(Chief Ray Angle):CRA是Chief Ray Angle的缩写,意思是主光角。从镜头的传感器一侧,可以聚焦到像素上的光线的最大角度被定义为一个参数,称为主光角(CRA)。对于主光角的一般性定义是:此角度处的像素响应降低为零度角像素响应(此时,此像素是垂直于光线的)的80%;因为Lens CRA 的存在,所以就出现了FOV (filed of view) 所谓的视角的概念。视角大小=2*CRA。如下图所示: file:///C:\Users\CC\AppData\Local\Temp\ksohtml1988\wps1.jpg Lens CRA 拍摄镜头和传感器之间的接口是整个可拍照手机系统中最重要的接口之一。随着镜头的长度变得越来越短,光线到达传感器像素位置的角度也就会变得越来越大。每个像素上都有一个微镜头。微镜头的主要功能就是将来自不同角度的光线聚焦在此像素上。然而,随着像素位置的角度越来越大,某些光线将无法聚焦在像素上,从而导致光线损失和像素响应降低。 光线进入每一个像数的角度将依赖于该像素所处的位置,镜头轴心线附近的光线将以接近零角度进入像素中随着它与轴心线的距离曾大,角度也变大.CRA与像素在传感器中的位置是相关的 。 光线进入每个像素的角度将依赖于该像素所处的位置。镜头轴心线附近的光线将以接近零度的角度进入像素中。随着它与轴心线的距离增大,角度也将随之增大。CRA与像素在传感器中的位置是相关的,它们之间的关系与镜头的设计有关。很紧凑的镜头都具有很复杂的CRA模式。如果镜头的CRA与传感器的微镜头设计不匹配,将会出现不理想的透过传感器的光线强度(也就是“阴影”)。通过改变微镜头设计,并对拍摄到的图像进行适当处理,就可以大大降低这种现象。改变微镜头设计可以大大降低阴影现象。然而,在改变微镜头设计时,必须与镜头设计者密切配合,以便为各种拍摄镜头找到适合的CRA模式。相机的设计工程师应该确保这种技术合作得以实现,并确保传感器与镜头CRA特性可以很好地匹配。为确保成功实现此目标,美光开发了相关的仿真工具和评价工具。由于光线是沿着不同的角度入射到传感器上的,因此对于各种镜头设计而言,阴影现象都是固有的。 “cos4定律”说明,减少的光线与增大角度余弦值的四次方是成比例关系的。另外,在某些镜头设计中,镜头可能本身就会阻挡一部分光线(称为“晕光”),这也会引起阴影现象。所以,即使微镜头设计可以最小化短镜头的阴影现象,此种现象还是会多多少少地存在。
1.2 Sensor CRASensor有一个 CRA值,也就是Sensor的Micro Lens与光电二极管的位置存在一个水平误差,并不在一条直线上,做成这样有一定的目的,按通常的做法,因为Sensor的Micro Lens与光电二极管之间存在一定的距离,这样的做的目的也是为了好搭配Lens。
file:///C:\Users\CC\AppData\Local\Temp\ksohtml1988\wps2.jpg 普通的FSI的sensor都有一个类似光子井的结构用来收集光子:
当CRA增加的时候,光线会被金属电路层阻挡掉一部分,导致sensor接受光的效能降低。
那么:1 pixel越大,这种影响会越小 file:///C:\Users\CC\AppData\Local\Temp\ksohtml1988\wps3.jpg
2 对于BSI的sensor,这种影响也会更小: file:///C:\Users\CC\AppData\Local\Temp\ksohtml1988\wps4.jpg 因此对于FSI的sensor来说,通常会通过移动sensor表面的Micro Lens来收集更多的光线: file:///C:\Users\CC\AppData\Local\Temp\ksohtml1988\wps5.jpg
一般情况镜头的CRA小于sensor的CRA,且允许2-3度的误差;因为镜头的CRA过于小于sensor的CRA,就会出现图像四角偏暗的情况,由于此时光线无法达到pixel阵列的边缘。镜头的CRA大于sensor的CRA时,光线会折射到临近的pixel上,导致pixel间出现串扰,出现图像的偏色,且图像四周表现更加明显; Lens shading在ISP中处于较为重要步骤,仅随Blacklevel之后,可以lens shading对后续的相关处理的重要性;Lens Shading可细分为Luma Shading(亮度均匀性)和Color Shading(色彩均匀性)两种; 广角镜头:这时一般Lens的CRA比较大,需要选择CRA大于25度的Sensor或者BSI的Sensor;一般用于手机、安防、玩具、网络摄像头等; 2 超长焦镜头:这时一般Lens的CRA比较小,需要选择CRA为0度的Sensor;一般用于安防、机器视觉等; 3 变焦镜头:这时Lens的CRA是变化的,一般需要根据实际应用选择,最好采用大pixel,BSI的Sensor;一般用于安防等;
2. Lens shading的产生原因1.1.1 Luma Shading产生的原因: 1.由摄像头本身的机械结构导致产生。由于摄像头各模块在制作和组装的过程中,均存在一定的工艺误差,从而影响物体光线在摄像头内的传播。 2.由镜头(Lens)的光学特性引起。对于整个镜头,可将其视为一个凸透镜。由于凸透镜中心的聚光能力远大于其边缘,从而导致Sensor中心的光线强度大于四周。此种现象也称之为边缘光照度衰减。对于一个没有畸变的摄像头,图像四周的光照度衰减遵循(cosQ)^4。 1.1.2 Color shading产生的原因Color Shading的成因则要相对复杂的多。在分析其成因之前,需要对IR-Cut filter和Image Sensor有所了解。首先,可在摄像头分解示意图中清晰地看到,红外截止滤波片位于镜头和图像传感器之间。主要用于消除投射到Sensor上不必要的光线,防止Sensor产生伪色/波纹,从而提高色彩还原性。由于图像传感器上的RGB像素滤波片不能滤除红外光和紫外光,因此需要使用另外的滤波片进行滤除,否则会导致红绿蓝像素点的亮度值与人眼观察到的亮度值存在较大的差异。就目前而言,红外截止滤波片可分为干涉型、吸收型和混合型三种,其三者的截取范围如图红外截止滤波片截取区域如图4-(a)所示。其中普通的IR-cut filter为干涉型红外截止滤波片,在可见光区域有较高的透过率,存在较低反射率,而在红外区域正好相反,反射率较高,透过率很低。但成角度拍摄照片时,红外光在IR膜上会有较大反射,经过多次反射后,被Sensor接收从而改变图像R通道的值,引起图像偏色问题。蓝玻璃则是吸收型红外截止滤波片,对红外光有很强的吸收作用,不存在很大的反射,能在一定程度上减轻渐晕和色差问题。此外,便是使用前两者混合的方式对想要的光谱区域进行截取,虽然能够缓解入射光角度问题,但使得抵达传感器的光量减少了,从而引入了更多的噪声。如图4-(b)所示。其次,在红外截止滤波片之后便是图像传感器,主要由相间的RGB像素感光块构成。为了使感光面积不受感光片的开口面积影响,一般会在其上方增加一层微透镜(Micro Lens),用于收集光线,提高感光度。但微透镜的主光线角CRA(Chief ray angle)值与镜头的CRA值不匹配便会导致严重的shading问题。 1. 由于镜头对不同光谱光线的折射程度不同,导致入射光线中不同波长的光线落在Sensor的不同位置,从而引起Color Shading。我们都知道光的色散现象,即白光通过三棱镜后会被分解为七色光。而产生这种现象的原因就是三棱镜对不同波长光线的折射不同,从而导致不同波长光线走过的光程不同。 2. 由IR-Cut filter引入。具体描述详见上文。 3.由Sensor上微透镜的CRA与镜头的CRA不匹配导致。镜头的主光线角与传感器不匹配,会使传感器的像素出现在光检测区域周围,致使像素曝光不足,亮度不够。 4.在校正Lens Shading时,由于校正参数计算不准确导致。通常而言,摄像头在拍摄原始图像(raw)之后,会经过图像信号处理器(ISP)处理之后再呈现在用户面前。在整个ISP的pipeline中,会含有一个LSC(Lens Shading Correction)模块,用于校正镜头暗影。 3.
矫正方法1,双线性插值; 2,多项式拟合; 下以双线性插值算法为例: Step 1 :选择一个光照均匀的图像,然后将图像分为9x7块,统计每块RGB三个通道的像素的平均值, Step 2:分别计算出每块的图像的RGB平均值与中心块的RGB各个通道的比值Y,得出各个块的gain = 1/Y; Step 3:将各个块的gain存入的LUT中,根据像素的点位置,选取该像素所在块的四个顶点的gain,利用双线性插值算法可以得倒该像素点的gain; 程序如下: BLOCK_X = 9 BLOCK_Y = 7 img_test = imread('test_rggb.bmp'); img_flat = imread('flat_rggb.bmp'); %原图像 [rown,coln] =size(img_flat); %分通道 r = img_flat(1:2:end,1:2:end); b = img_flat(2:2:end,2:2:end); g = zeros(rown,coln/2); g(1:2:end, = img_flat(1:2:end,2:2:end); g(2:2:end, = img_flat(2:2:end,1:2:end); %中值滤波,可以抑制噪声的干扰 %根据具体情况而定,一般会使用,分别对各个通道RGB做中值滤波 img_filt= img_flat;
%各块的RGB平均值 subSampleRGB=ones(BLOCK_Y+1,BLOCK_X+1,3); strideX=floor(coln/BLOCK_X-1); strideY=floor(rown/BLOCK_Y-1); for i=1:BLOCK_X+1 for j=1:BLOCK_Y+1 rows = floor((j-1-0.5)*strideY); rowe = floor((j-1+0.5)*strideY); cols = floor((i-1-0.5)*strideX); cole = floor((i-1+0.5)*strideX); if rows <= 0 rows=0; end if rowe >= rown; rowe = rown; end if cols <= 0 cols=0; end if cole >= coln; cole = coln; end subimg = zeros(rowe-rows,cole-cols); subimg = img_filt(rows+1:rowe,cols+1:cole); subSampleRGB(j,i,1)=mean2( subimg(1:2:end,1:2:end)); gr=mean2( subimg(1:2:end,2:2:end)); gb=mean2( subimg(2:2:end,1:2:end)); subSampleRGB(j,i,2) = mean2([gr,gb]); subSampleRGB(j,i,3)=mean2( subimg(2:2:end,2:2:end)); end end %(Y-shading gain) gainlut=zeros(BLOCK_Y+1,BLOCK_X+1,3);% gainlut centerX = coln/2; centerY = rown/2; centerXs = centerX - strideX/2 + 1; centerXe = centerXs + strideX - 1; centerYs = centerY - strideY/2 + 1; centerYe = centerYs + strideY - 1; centerimg =img_filt( centerYs:centerYe,centerXs:centerXe); centerRvg = mean2( centerimg(1:2:end,1:2:end)); centerBvg = mean2( centerimg(2:2:end,2:2:end)); centergr=mean2( centerimg(1:2:end,2:2:end)); centergb=mean2( centerimg(2:2:end,1:2:end)); centerGvg = mean2([centergr,centergb]); centerAVG = [centerRvg,centerGvg,centerBvg]; for i = 1:BLOCK_X+1 for j =1:BLOCK_Y+1 for k = 1:3 gainlut(j,i,k)=centerAVG(k)/ subSampleRGB(j,i,k); end end end %colorshading gain gainlut_c = zeros(BLOCK_Y+1,BLOCK_X+1,2); center_RoverG = mean2( subSampleRGB(floor(BLOCK_Y/2+1) : floor(BLOCK_Y/2+1)+1, floor(BLOCK_X/2+1) : floor(BLOCK_X/2+1)+1,1)) / mean2( subSampleRGB(floor(BLOCK_Y/2+1) : floor(BLOCK_Y/2+1)+1, floor(BLOCK_X/2+1) : floor(BLOCK_X/2+1)+1,2)); center_BoverG = mean2( subSampleRGB(floor(BLOCK_Y/2+1) : floor(BLOCK_Y/2+1)+1, floor(BLOCK_X/2+1) : floor(BLOCK_X/2+1)+1,3)) / mean2( subSampleRGB(floor(BLOCK_Y/2+1) : floor(BLOCK_Y/2+1)+1, floor(BLOCK_X/2+1) : floor(BLOCK_X/2+1)+1,2)); for i = 1:BLOCK_X+1 for j =1:BLOCK_Y+1 RoverG = subSampleRGB(j,i,1)/subSampleRGB(j,i,2); BoverG = subSampleRGB(j,i,3)/subSampleRGB(j,i,2); gainlut_c(j,i,1) = RoverG/center_RoverG; gainlut_c(j,i,2) = BoverG/center_BoverG; end end 双线性插值FullGainLut x = 1:strideX:coln+1; x(end) = coln; y = 1:strideY:rown+1; y(end) = rown;
xitp = 1:2:coln; yitp = 1:2:rown; [Xitp,Yitp]=meshgrid(xitp,yitp); rgain=interp2(x,y,gainlut(:,:,1),Xitp,Yitp); xitp = 2:2:coln; yitp = 1:2:rown; [Xitp,Yitp]=meshgrid(xitp,yitp); grgain=interp2(x,y,gainlut(:,:,2),Xitp,Yitp);
xitp = 1:2:coln; yitp = 2:2:rown; [Xitp,Yitp]=meshgrid(xitp,yitp); gbgain=interp2(x,y,gainlut(:,:,2),Xitp,Yitp);
xitp = 2:2:coln; yitp = 2:2:rown; [Xitp,Yitp]=meshgrid(xitp,yitp); bgain=interp2(x,y,gainlut(:,:,3),Xitp,Yitp); [gn,gm]=size(gbgain); ggain = zeros(gn*2,gm); ggain(1:2:end, = grgain; ggain(2:2:end,:) = gbgain; gain=zeros(rown,coln); gain(1:2:end,1:2:end) = rgain; gain(1:2:end,2:2:end) = grgain; gain(2:2:end,1:2:end) = gbgain; gain(2:2:end,2:2:end) = bgain;
lscgain = gain; imgDoubleType = im2double(img_flat); imgDoubleType = imgDoubleType.*lscgain; imgUint = im2uint8(imgDoubleType); imshow(imgUint) imwrite(imgUint,'flat.bmp','bmp')
参考文档: https://blog.csdn.net/HuddHeaven/article/details/52300262
|