图像处理中lsc代表什么

2020-04-18 15:10:01 weixin_40787463 阅读数 732
  • 噪声与去噪

    通过本课程的学习,可以对数字成像系统知识整体上得到理解,在相机等成像产品的开发,获得理论与实际的帮助。

    1160人学习 姜卓
    免费试看
   这段时间由于需要,查阅理解了AP端ISP图像的优化处理,以下的总结都非常的全面,通过整理,希望对大家有所帮助。
  **ISP(Image Signal Processor)**,即**图像信号处理器**,用于处理图像信号传感器输出的图像信号。它在相机系统中占有核心主导的地位,是构成相机的重要设备。ISP 通过一系列数字图像处理算法完成对数字图像的效果处理。主要包括3A、坏点校正、去噪、强光抑制、背光补偿、色彩增强、镜头阴影校正等处理。ISP 包括逻辑部分以及运行在其上的firmware。

1. ISP基础概念
ISP在相机数据流中的位置
ISP是什么?它的目的就是对光学传感器输出的Raw图数据进行信号处理,使之成为符合人眼真实生理感受的信号,并加以输出。
**为什么需要ISP呢?**这是个复杂的问题,其根源就是Raw图数据排布的形式。以下给出jpg和Raw的对比效果,这能非常直观地告诉你,Raw图为什么叫做Raw图(未经处理的图)。
jpg和RAW对比,左JPG右RAW

我们知道所有的光都被能分解为几种基础色光。反之,用一定比例的各种饱和度、色调的基础色光就可以合成几乎所有的光。光学Seneor正是利用了这一原理,设置了红绿蓝pixel(像素单元)来接收光信号。而目前,红绿蓝pixel的排布采用了Bayer(贝尔)排布。这种排布造就了上图显示的传感器Raw图数据直接显示的效果。问题所在:1.图上全是绿色,2有网格现象(我们称之为棋盘格现象).
**怎么样实现ISP?**那么如何处理Raw图的数据,使之能够显示符合人眼真实感受的图片,这就成为了ISP的重要使命。为实现这一使命,ISP分为三个重要的部分,Bayer域信号处理,RGB域信号处理,YUV域信号处理。
isp三个域处理流程

2. ISP主要内部构成及控制

如下图所示,ISP 内部包含 CPU、SUP IP、IF 等设备,事实上,可以认为ISP 是一个 SOC,可以运行各种算法程序,实时处理图像信号。在这里插入图片描述
①CPU
CPU 即中央处理器,可以运行 AF(自动对焦)、LSC 等各种图像处理算法,控制外围设备。现代的 ISP 内部的 CPU 一般都是 ARM Cortex-A 系列的,例如 Cortex-A5、Cortex-A7。

②SUB IP
SUB IP 是各种功能模块的通称,对图像进行各自专业的处理。常见的 SUB IP 如 DIS、CSC、VRA 等。

③图像传输接口
图像传输接口主要分两种,并口 ITU 和串口 CSI。CSI 是 MIPI CSI 的简称,鉴于 MIPI CSI 的诸多优点,在手机相机领域,已经广泛使用 MIPI-CSI 接口传输图像数据和各种自定义数据。外置 ISP 一般包含 MIPI-CSIS 和 MIPI-CSIM 两个接口。内置 ISP 一般只需要 MIPI-CSIS 接口。

④ 通用外围设备
通用外围设备指 I2C、SPI、PWM、UART、WATCHDOG 等。ISP 中包含 I2C 控制器,用于读取 OTP 信息,控制 VCM 等。对于外置 ISP,ISP 本身还是 I2C 从设备。AP 可以通过 I2C 控制 ISP 的工作模式,获取其工作状态等。

ISP 的Firmware 包含三部分,一部分是ISP 控制单元和基础算法库,一部分是AE/AWB/AF 算法库,一部分是sensor 库。Firmware 设计的基本思想是单独提供3A 算法库,由ISP 控制单元调度基础算法库和3A 算法库,同时sensor 库分别向ISP 基础算法库和3A 算法库注册函数回调,以实现差异化的sensor 适配。ISP firmware 架构如下图所示。
在这里插入图片描述
控制结构:
在这里插入图片描述
ISP包括: 1、ISP逻辑 2、运行在其上的firmware
如图所示,lens 将光信号投射到sensor的感光区域后,sensor 经过光电转换,将Bayer 格式的原始图像送给ISP,ISP 经过算法处理,输出RGB空间域的图像给后端的视频采集单元。在这个过程中,ISP通过运行在其上的firmware(固件)对ISP逻辑,从而对lens 和sensor 进行相应控制,进而完成自动光圈、自动曝光、自动白平衡等功能。其中,firmware的运转靠视频采集单元的中断驱动。PQ Tools 工具通过网口或者串口完成对ISP 的在线图像质量调节。
ISP 由ISP逻辑及运行在其上的Firmware组成,逻辑单元除了完成一部分算法处理外,还可以统计出当前图像的实时信息。Firmware 通过获取ISP 逻辑的图像统计信息,重新计算,反馈控制lens、sensor 和ISP 逻辑,以达到自动调节图像质量的目的。
3. 主要及常见功能特性
ISP作为图像处理的核心器件,拥有十分重要的功能,下图展示了 ISP 处理图像数据的基本流程。
在这里插入图片描述
下面针对 ISP 的主要功能特性进行下介绍:
① DEMOSAIC
DEMOSAIC 是 ISP 的主要功能之一。SENSOR 的像素点上覆盖着 CFA,光线通过 CFA 后照射到像素上。CFA 由 R、G、B 三种颜色的遮光罩组成,每种遮光罩只允许一种颜色通过,因此每个像素输出的信号只包含 R、G、B 三者中的一种颜色信息。SENSOR 输出的这种数据就是 BAYER 数据,即通常所说的 RAW 数据。显而易见,RAW 数据所反映的颜色信息不是真实的颜色信息。DEMOSAIC 就是通过插值算法将将每个像素所代表的真实颜色计算出来。
②FOCUS
根据光学知识,景物在传感器上成像最清晰时处于合焦平面上。通过更改 LENS 的位置,使得景物在传感器上清晰的成像,是 ISP FOCUS 功能所需要完成的任务。FOCUS 分为手动和自动两种模式。ISP 可以运行 CONTRAST AF、PDAF、LASER AF 等算法实现自动对焦。
③EXPOSURE
曝光。EXPOSURE 主要影响图像的明暗程度。ISP需要实现 AE 功能,通过控制曝光程度,使得图像亮度适宜。
④ WB
白平衡。白平衡与色温相关,用于衡量图像的色彩真实性和准确性。ISP需要实现 AWB 功能,力求在各种复杂场景下都能精确的还原物体本来的颜色。
⑤ LSC
用于消除图像周边和图片中心的不一致性,包含亮度和色度两方面。ISP 需要借助 OTP 中的校准数据完成 LSC 功能。
⑥ GAMMA CORRECTION
伽玛校正。传感器对光线的响应和人眼对光线的响应是不同的。伽玛校正就是使得图像看起来符合人眼的特性。

⑦ CROP/RESIZE

图像剪裁,即改变图像的尺寸。可用于输出不同分辨率的图像。

⑧ VRA

视觉识别。用于识别特定的景物,例如人脸识别,车牌识别。ISP 通过各种 VRA 算法,准确的识别特定的景物。
⑨ DRC
动态范围校正。动态范围即图像的明暗区间。DRC 可以使得暗处的景物不至于欠曝,而亮处的景物不至于过曝。ISP 需要支持 DRC 功能。
⑩ CSC
颜色空间转换。例如,ISP会将 RGB 信号转化为 YUV 信号输出。
图像稳定。
11. IS
IS 的主要作用是使得图像不要因为手持时轻微的抖动而模糊不清。IS 有很多种,例如 OIS、DIS、EIS。ISP 可以实现 DIS 和 EIS。
事实上,ISP 除了上面提到的主要功能外,还需要支持 DENOISE CONTRAST、SATURATION、SHARPNESS 等调整功能。
4.ISP主要支持的图像处理功能如下:
在这里插入图片描述
4. AP 对 ISP 的操控方式

CPU处理器包括:AP、BP、CP。 BP:基带处理器、AP:应用处理器、 CP:多媒体加速器。
① I2C/SPI
这一般是外置 ISP 的做法。SPI 一般用于下载固件、I2C 一般用于寄存器控制。在内核的 ISP 驱动中,外置 ISP 一般是实现为 I2C 设备,然后封装成 V4L2-SUBDEV。
② MEM MAP
这一般是内置 ISP 的做法。将 ISP 内部的寄存器地址空间映射到内核地址空间,
③ MEM SHARE
这也是内置 ISP 的做法。AP 这边分配内存,然后将内存地址传给 ISP,二者实际上共享同一块内存。因此 AP 对这段共享内存的操作会实时反馈到 ISP 端。
5.ISP处理流程在这里插入图片描述
在这里插入图片描述在这里插入图片描述
图像产生过程:景物通过Lens 生成的光学图像投射到 sensor 表面上,经过光电转换为模拟电信号,消噪声后经过 A/D 转换后变为数字图像信号,再送到数字信号处理芯片( DSP)中加工处理。
所以,从 sensor 端过来的图像是 Bayer图像,经过黑电平补偿
(black level compensation)、镜头矫正(lens shading correction)、坏像素矫正(bad pixel correction)、颜色插值(demosaic)、Bayer 噪声去除、白平衡(awb)矫正、 色彩矫正(colorcorrection)、gamma 矫正、色彩空间转换(RGB 转换为 YUV)、在YUV 色彩空间上彩噪去除与边缘加强、色彩与对比度加强,中间还要进行自动曝光控制等,然后输出 YUV(或者RGB)格式的数据, 再通过 I/O 接口传输到 CPU 中处理。
在这里插入图片描述在这里插入图片描述

2020-01-09 21:25:56 qq_40268412 阅读数 1871
  • 噪声与去噪

    通过本课程的学习,可以对数字成像系统知识整体上得到理解,在相机等成像产品的开发,获得理论与实际的帮助。

    1160人学习 姜卓
    免费试看

超像素

  超像素是把一张图片中具有相似特征的像素进行聚类,形成一个更具有代表性的大“像素”。这个新的像素可以作为其他图像处理算法的基本单位,可以减低图像的维度和异常像素点。目前常用的超像素分割算法有SLIC、SEEDS和LSC。下面来说说这些算法基于Opencv的Python实现。

SLIC算法

  算法具体原理可参考博客:SLIC超像素算法原理
  那么我来讲讲如何在opencv去实现该算法。利用opencv中ximgproc类下的子类SuperpixelSLIC实现。
  python调用方法:

retval	=	cv.ximgproc.createSuperpixelSLIC(	image[, algorithm[, region_size[, ruler]]]	)

  其中各个参数意义如下:
    image :输入图像
    algorithm:选择要使用的算法变体:SLIC、SLICO(默认)和MSLIC三种可选
    region_size:平均超像素大小,默认10
    ruler:超像素平滑度,默认10

  python具体实现如下:

import cv2
import numpy as np

img = cv2.imread("mao.jpg")
#初始化slic项,超像素平均尺寸20(默认为10),平滑因子20
slic = cv2.ximgproc.createSuperpixelSLIC(img,region_size=20,ruler = 20.0) 
slic.iterate(10)     #迭代次数,越大效果越好
mask_slic = slic.getLabelContourMask() #获取Mask,超像素边缘Mask==1
label_slic = slic.getLabels()        #获取超像素标签
number_slic = slic.getNumberOfSuperpixels()  #获取超像素数目
mask_inv_slic = cv2.bitwise_not(mask_slic)  
img_slic = cv2.bitwise_and(img,img,mask =  mask_inv_slic) #在原图上绘制超像素边界
cv2.imshow("img_slic",img_slic)
cv2.waitKey(0)
cv2.destroyAllWindows()

  运行效果如下图所示:
在这里插入图片描述

SEEDS算法

  利用opencv中ximgproc类下的子类 createSuperpixelSEEDS()实现。python调用方法:

retval	=	cv.ximgproc.createSuperpixelSEEDS(	image_width, image_height, image_channels, num_superpixels, num_levels[, prior[, histogram_bins[, double_step]]]	)

  其中各个参数意义如下:
    image_width :输入图像宽度
    image_height: 输入图像高度
    image_channels :输入图像通道数
    num_superpixels :期望超像素数目
    num_levels :块级别数,值越高,分段越准确,形状越平滑,但需要更多的内存和CPU时间。
    histogram_bins: 直方图bins数,默认5
    double_step: 如果为true,则每个块级别重复两次以提高准确性默认false。

  python具体实现如下:

import cv2
import numpy as np

img = cv2.imread("mao.jpg")
#初始化seeds项,注意图片长宽的顺序
seeds = cv2.ximgproc.createSuperpixelSEEDS(img.shape[1],img.shape[0],img.shape[2],2000,15,3,5,True)
seeds.iterate(img,10)  #输入图像大小必须与初始化形状相同,迭代次数为10
mask_seeds = seeds.getLabelContourMask()
label_seeds = seeds.getLabels()
number_seeds = seeds.getNumberOfSuperpixels()
mask_inv_seeds = cv2.bitwise_not(mask_seeds)
img_seeds = cv2.bitwise_and(img,img,mask =  mask_inv_seeds)
cv2.imshow("img_seeds",img_seeds)
cv2.waitKey(0)
cv2.destroyAllWindows()

  运行效果如下图所示:
在这里插入图片描述

LSC算法

  利用opencv中ximgproc类下的子类**createSuperpixelLSC()**实现。python调用方法:

retval	=	cv.ximgproc.createSuperpixelLSC(	image[, region_size[, ratio]]	)

  其中各个参数意义如下:
    image:输入图像
    region_size :平均超像素大小,默认10
    ratio:超像素紧凑度因子,默认0.075

  python具体实现相似,如下所示:

import cv2
import numpy as np

img = cv2.imread("mao.jpg")
lsc = cv2.ximgproc.createSuperpixelLSC(img)
lsc.iterate(10)
mask_lsc = lsc.getLabelContourMask()
label_lsc = lsc.getLabels()
number_lsc = lsc.getNumberOfSuperpixels()
mask_inv_lsc = cv2.bitwise_not(mask_lsc)
img_lsc = cv2.bitwise_and(img,img,mask = mask_inv_lsc)
cv2.imshow("img_lsc",img_lsc)
cv2.waitKey(0)
cv2.destroyAllWindows()

  代码运行效果如下所示:
在这里插入图片描述
以上

2020-01-31 10:53:42 m0_37631324 阅读数 357
  • 噪声与去噪

    通过本课程的学习,可以对数字成像系统知识整体上得到理解,在相机等成像产品的开发,获得理论与实际的帮助。

    1160人学习 姜卓
    免费试看
参考链接:
1.凹凸思 https://www.zhihu.com/people/jiao-tao-52
2.纸上浅谈 https://glumes.com/post/ffmpeg/understand-yuv-format/

1.名词解释

  • 光通量(Φ):指人眼所能感觉到的辐射功率,它等于单位时间内某一波段辐射能量和该波段相对视见率的乘积。单位:流明。
  • 发光强度(光强):在给定方向上(该方向上的辐射强度为(1/683)瓦特/球面度))的单位立体角发出的光通量.单位:坎德拉.
  • 亮度(辉度Lv):指发光体光强与人眼所“见到”的光源面积之比,定义为该光源单位的亮度,即单位投影面积上的发光强度.单位:坎德拉/平方米(cd/m2)
  • 感光度(ISO):是衡量底片对于光的灵敏程度的量.
a. 胶片相机的感光度:是胶片对光线的化学反应速度,也是制造胶片行业中感光速度的标准。

b. 数码相机的感光度:是一种类似于胶卷感光度的一种指标,实际上,数码相机的ISO是通过调整感光元件的灵敏度或者合并感光点来实现的,也就是说是通过提升感光器件的光线敏感度或者合并几个相邻的感光点来达到提升ISO的目的。(简单的说:感光度就是传感器的对光的敏感程度。)感光度越高,对光的敏感度越高,曝光值也会越高。

c. 感光度的参数和表述:感光度一般使用前缀ISO+参数的方式来表述感光度的数值如:感光度 100可以写成ISO100

d. 感光度常用的数值:ISO50、 ISO100 、ISO 200、ISO400、ISO800、ISO1600、ISO3200、ISO6400 (在光圈快门相同的情况下,感光度每增加一倍,曝光量便会增加一倍。)
  • 曝光量

在这里插入图片描述

①AV是孔径值:

AV = 2 * log2 (F number) ,F number是镜头的光圈F值,如F5.6,F值就是5.6。

②TV是时间值:

TV = - log2 (exposure time) ,exposure time是曝光时间单位是秒sec。

③BV是被摄景物的亮度:

BV =log2(B/0.3K) , B是景物亮度单位是Cd/cm2。

LV=BV+5。

④SV是感光材料的感光度值:

SV = log2(0.3S), ISO100的S值就是100.

⑤EV是曝光量:

则曝光公式为:

在这里插入图片描述

2. 3A(AWB,AE,AF)

2.1 AE(Auto Exposure)自动曝光

2.1.1 AE算法思想和曝光量公式

(1)AE的基本概念:Auto Exposure即自动曝光,是相机根据外界光线的强弱自动调整曝光量和增益,防止曝光过度或者不足的一种机制。

在这里插入图片描述

可见,AE的输入为当前影像的亮度值Y,输出为sensor的曝光时间和增益,isp增益和镜头光圈(如果镜头光圈可调)。当AE algorithm得到当前帧的亮度后,便会与target Y做比较,然后计算出下一次需要调整的参数,以便让影像的亮度越来越接近target Y,如下所示(target并非一个固定值,而是一个range)。

在这里插入图片描述

(2)影响曝光的因素:

	AE算法的要求是“快,准,稳”。即要很快的能收敛到target附近,而且亮度要准确,收敛过程要平滑,收敛完成后要稳定。

影响AE算法的因素:图片亮度的统计,AE target,AE table,收敛速度控制。

实际操作中调节的因素有:

  1. 调节曝光时间;
  2. 调节光圈大小;
  3. 调节Sensor的ISO感光度

(3)AE控制模块:

在这里插入图片描述

(4)调节曝光的方法步骤和算法:

A.读入现在设定值所得到的亮度值;

B.经过AE weight table后得到我们想要计算的亮度;

C.将得到的计算值,趋近我们的期望值(如:135);

D.计算出一组新的设定值;

E.重复以上动作,直到亮度值在我们的期望值收敛范围内(Example : 131~139)。

在这里插入图片描述

(5)曝光时间的控制:

因为Sensor本身并没有时间的概念,它是通过pixel clock数和pixel clock的频率来表示sensor曝光时间的。为了得到简便的表达方式,就用曝光行数表示曝光时间了。曝光行数=pixel clock数/每条line的pixel数。 只需要知道sensor的pixel clock频率和每行的pixel数(有效pixel+dummy pixel),便可以计算出任何曝光时间,sensor需要曝光多少行。

(6)sensor曝光过程:

​ 如下图过程可见,曝光是逐个像素从上往下进行的,当读到图中红色块时就说上面的五行已经曝光完成了,也说明sensor的曝光时间是5条lines。

在这里插入图片描述

(7) AE table:

不同的曝光时间和ISO组合方式,表和图示如下:

在这里插入图片描述

(8)AE 收敛

在这里插入图片描述

et是曝光时间;agc指sensor的感光度sensorgain即sensor的ISO值;iris是光圈值的大小。

收敛的概念就是无限趋近。

(9)AE中的问题:flicker,过曝、曝光不足、AE peak、AE震荡等。

Flicker:

现象:图像因为sensor曝光时间不是光源频率的整数倍导致图像上出现Banding即明暗相间的条纹。

产生原因:

  • 曝光时间小于1/100秒,且曝光时间处于波峰时,图片亮度比较亮

  • 曝光时间小于1/100秒,且曝光时间处于波谷时,图片亮度比较暗

从能量的角度看,就是当sensor逐像素吸收外界能量成像时,外界能量有时大有时小,像素就有的亮有的暗。因此产生flicker现象。

解决办法:

  • 所以只有曝光时间=光源周期的整数倍的时候,保证每个像素吸收的光能是稳定的。

才可以避免flicker。国内市电,50HZ.

在这里插入图片描述

AE Peaking:AE的峰值,图像亮度平稳时,突然出现亮度高的画面。

AE震荡:图像亮度忽明忽暗。

2.1.2 测光模式

①平均测光,取画面亮度均值作为曝光依据,画面主体、背景亮度差异大时,容易造成曝光过度或者曝光不足的现象。

在这里插入图片描述

②中央点测光(Spot Metering),仅测量中央很小范围内景物的亮度作为自动曝光依据,
在这里插入图片描述

③多点测光(Multi-Spot Metering):简单理解为点测光+记忆装置,拍摄时使被摄体中不同的部位,先后位于取景视场中心进行点测光,照相机内的电子线路将每次的结果记忆下来,并按各点的平均值进行曝光。可兼顾画面不同部分的亮度,精度高,操作麻烦。多点测光适合于拍摄风景、人像等静止不动的物体,不适合拍摄动体

④中央重点测光,是平均测光与点测光方式的折衷形式,中央部分亮度权重较高,边缘权重较低 能同时兼顾被摄主体和四周景物的亮度,因此对被摄主体的测光精度较高,尤其适合于拍摄带风景的人物照片。但对于亮度不均匀或反差太大的场合,容易造成曝光过度或者曝光不足的现象。

⑤局部测光:佳能首创,中央重点加权平均测光和点测光方式的折中,测光区域较点测光大。

在这里插入图片描述

⑥分区式测光(Multi-Pattern Metering),又称多幅面测光、多模式测光或区域分割式测光,主要原理是将画面分成几个区,先测取每个区的亮度,然后经过综合计算,从而决定每个区域的测光加权比重,给出一个能兼顾各区的曝光值。从理论上讲,分区式测光方式都具有自动逆光补偿能力。
在这里插入图片描述

2.2 AF(Auto Focus) 自动对焦

2.2.1 光学原理

​ 透镜成像:成像点不一定落在焦平面上面,需要通过调整镜头,使成像点落在焦平面上面,使sensor清晰成像,这个过程就是聚焦过程。
在这里插入图片描述

2.2.2 AF 基本方法

在这里插入图片描述

(1)Lens-motion-type AF移动镜头:根据图像的清晰度(一般为边缘信息)或者物距信息,通过AF算法判断对焦情况,从而计算镜头的移动方向和大小,然后驱动电路使镜头移动来改变聚焦位置。

(2)Lens-modification-type AF改变焦距:通过liquid lens或者solid-state electro-optical devices这些可变焦的器件来改变镜头的焦长。

(3)Extended depth of field AF (EDOF)全焦技术:通过光学和数字信号处理技术集合,对光学信息编码,再用计算机信息处理技术解码,使得景深得到扩展,从而实现无运动部件的AF功能。

(4)手机摄像头多使用AF是VCM驱动镜头前后移动的方案。通过给线圈通电流,在永磁体的作用下,使镜头前后移动,同时前后两个弹簧片控制移动位置。

在这里插入图片描述

2.2.3 摄像头中AF系统示意图

在这里插入图片描述

这里的AF算法的信息基础有被动式和主动式两类。

采用对比度法,手机摄像头的AF系统架构图如下:

在这里插入图片描述

2.2.4 AF 算法流程

在这里插入图片描述
在这里插入图片描述

2.2.5 AF算法中信息收集方法

  1. 基于镜头与被摄目标之间距离测量的测距方法。

A、三角测量法:由电路控制可动反光镜的转动,当透射光影和反射光影的重合时可以计算距离。

B、红外线测距法:由照相机主动发射红外线作为测距光源,并用红外发光二极管的转动代替可动反光镜的转动。需要一个获得当前照片对比度的设备来量测

  1. 超声波测距法:该方法是根据超声波在摄像机和被摄物之间传播的时间进行测距的
  2. 激光测距法:
  3. 基于调焦屏上成像清晰的聚焦检测方法。

A、对比度法 :手机上通过获得照片的Focus Value (Edge)来判断当前位置的清晰度,通过检测影像的轮廓边缘实现自动调焦的。

B、相位法PDAF。该方法是通过检测像的偏移量实现自动调焦的。

2.2.6 AF算法中图像清晰度评价方法

(1)常用的图像清晰度评价方法:

A、图像统计:

  • 灰度熵法(灵敏度不高) ;

在这里插入图片描述

pi是图像中灰度值为i的像素出现的概率,L为灰度级总数

  • 灰度方差法 – SMD filter ;
  • 直方图法。

B、图像边缘检测:

  • Laplacian算子(中心算子);
  • Sobel算子(highpass filter) (有一个水平方向算子,一个垂直方向算子,取最大值);
  • Robert算子(一个左上右下对角线算子,一个右上左下对角线算子) ;
  • Prewitt算子(有一个水平方向算子,一个垂直方向算子,取最大值)

C、空间域特征 :tenengrad filter(能量梯度函数)。

(2)函数举例

能量梯度函数:

在这里插入图片描述

Laplace算子:

在这里插入图片描述

模数偏差总和SMD(sum-modulus-difference)算 子:

在这里插入图片描述

2.2.7 AF算法中找最佳对焦点的方法

  1. 曲线拟合

在这里插入图片描述

(1)测得局部最大值peak点(FV):计算当前Step对应的FV值,判断当前FV值是不是在此前连续记录的四个step点FV值中的最大值,是最大值的话,就再判断它是否大于next Step点的FV值。用此方法判断极大值点,若有噪声造成step-FV曲线的微小波动,则通过各波动区域的极大值点对比,以最大值作为局部的MAX点。

(2)拟合曲线获取最佳对焦位置:因为step并不连续,测得Peak点的可能并不是真正最佳的对焦点,此时可通过poly fit曲线拟合的方法来找peak点。对于step-FV曲线采用

y=a*x^2+b*x+c

​ 就可以近似拟合,采用max point点和前、后相邻两个点,共三个点采用最小二乘法拟合抛物线。将抛物线的顶点最为最佳对焦点,反馈给VCM控制电路来驱动Lens移动到最佳对焦位置。

  1. AF Table

    根据不同距离处物体在sensor上成像的边缘信息即FV(Focus Value)值,绘制多条step-FV曲线。图中虚线表示每个物距处,图像认为清晰时可接受的最小FV值,虚线以上FV对应景深范围内物体成像信息。

在这里插入图片描述

根据上图绘制对应的step-DOF(Depth Of Field)曲线

在这里插入图片描述

  1. 连续对焦

    连续对焦:连续对焦中并不是找到焦点就停止,而是根据场景的变化不停的找最佳对焦位置,这样就需要判断镜头移动方向,这里也是主要使用爬山算法。

  2. 不同颜色格式对焦

在这里插入图片描述
在这里插入图片描述

2.3 AWB(Auto White Balance) 自动白平衡

2.3.1 什么是AWB

不同色温环境下,通过ISP的算法调整,抵消色温引起的偏色,使得拍出来的成像效果接近人眼视觉习惯.

2.3.2 为什么要做AWB

因为camera和人眼存在差异.

  • 对人眼,是主观的,本质上白色的物体,不同色温,反射光线颜色是不一样的,但是经过我们的视觉系统的校正后还是白色的.
  • 对于camera,是客观的,不同色温,反射光线颜色不一致,直接成像就会出现和人眼不一样的效果,也就是色偏.所以需要AWB,这个AWB就是类似于经过我们的视觉系统校正.

2.3.3 AWB算法有那些

1.最大亮度法

2.灰度世界法

3.色域界限法

4.图框区域分割法

5.光源预测法

6.完美反射法

7.动态阈值法

8.模糊逻辑法

2.4 ISP(Image Signal Process)

通常的ISP data patch:
在这里插入图片描述

(1)BLC(Black Level Correction)/ Black Level Compensate (OBC) :黑电平校正。所谓黑电平就是在DNP下,将曝光时间和增益都调到最小时拍摄图片的亮度值,理想情况下应该是0,但是实际中因为sensor暗电流作用,全黑像素值大于0。(这一个值,在后面可能会受到AWBGain,CCM,Gamma的影响)。

(2)DPC/BPD(Defect Pixel Correction/Bad Pixel Detect):坏点校正/坏点检测。相机中成像坏点一般是白色或者黑色的点,和周围像素点的差异明显。

(3)FPN(Fix Pattern Noise):固定模式噪声。由于CMOS每个感光二极体旁都搭配一个ADC 放大器,如果以百万像素计,那么就需要百万个以上的 ADC 放大器,但是每个像素结构中的光电二极管的尺寸、掺杂浓度、生产过程中的沾污以及MOS场效应管的参数的偏差等都会造成像素输出信号的变化。对于给定的单个像素它是固定的。通常消除固定模式噪声采用“双采样降噪”方法,这是CMOS 感光器件特有的一种降噪方式。在光线较暗的环境下使用时,画面会有明显的噪声,这时通过对景物进行两次不同曝光率和敏感度的采样,然后将两次采样的结果进行综合处理,就可以有效解决低照度下的图像噪声问题。

在这里插入图片描述

(4)LSC(Lens Shading Correction)/Color Shading :阴影校正。Lens Shading是由于镜片从边缘到中心对入射光线的反射程度不同,造成拍摄均匀亮度的画面,图像从中心到边缘亮度不均匀逐渐变暗。Color Shading是由于Lens从中心到边缘,其R、G、B变暗的速率不一样,总体表现就是Gb/Gr像素值差异较大,两个像素之间有细微纹理。找出shading的distribution,然后用最小的模型来建模将其导入
在这里插入图片描述

Correction原理:

在这里插入图片描述

找到中心点后,以中心点为原心,向周围以圆为单位补Gain,离中心点越远,补的越大

(5)Flare offset:光学上称Flare也叫stray light,耀斑补偿。镜片的表面反射或镜筒、反光镜组的内面所引起的反射光,到达底面后造成画面整体或一部份产生了雾蒙,降低了图像的鲜锐度。镜片的镀膜及内面防反射处理的加强,固然可以大幅度地减少光斑,但被摄体的状况并不相同,不可能完全消除。

在这里插入图片描述

(6)AE(Auto Exposure):自动曝光。

(7)AF(Auto Focus):自动对焦。

(8)AWB(Auto White Balance ):自动白平衡。解决环境光不同色温导致整幅图片偏色的情况。

(9)DM(Demosaicing/Color Filter Array Interpolation/CFA插值):CMOS Sensor出来的RawData是Bayer格式的图像,每个像素只有一个通道的信息。DM是将Bayer格式的图像恢复成每个像素用RGB三通道表示的方式。DM的主要依据是图像在平滑的局部区域,各分量的ratio是相等的。插值算法的好坏会影响图片的细节,如摩尔纹。

在这里插入图片描述

(10)CCM(Color Correction Matrix/ DSC color calibration):颜色校正矩阵。拍摄color checker24色板,将相机拍摄图片值与色板标准值之间进行对比(RGB颜色空间),得出一组能将拍摄值校正到最接近标准值的3x3矩阵。通过这个矩阵对所有相机拍摄的图片进行颜色校正。

(11)NR(Noise Reduction/Denoise):去噪。采用特定的LPF(Low Pass Filter)对图片进行滤波,滤除图像的噪声成分,而Bilateral filtering即双边滤波器,它是一种保护边缘的平滑滤波器,这样既可以滤除噪声,edge又可以保留下来。

在这里插入图片描述

(12)EE(Edge Enhancement/Edge Sharpening):锐化,边缘增强。通过滤波器获取图像的高频分量,按照一定的比例将高频部分和原图进行加权求和获取锐化后的图像。

在这里插入图片描述

(13)DRC/HDR(Dynamic Range Compression/ High-Dynamic Range):宽动态。高动态图像的拍摄出来的结果通常会有,亮部太亮,暗部太暗的问题。DRC是调整图像暗部亮度使之变亮,调整亮部亮度使之变暗,而且保持图像的对比度。

(14)PCA/VDE:Hue,Saturation,Contrast,Brightness调试。单独针对Hue,Saturation,Contrast,Brightness各图像分量进行调节。

(15)Histogram:直方图均衡化。重新分布图片的亮度。使图片的亮度分布更加均匀。

(16)FlashLight Control:闪光灯控制

(17)Cross talk:Optical cross-talk是当主光线进光角度过大,导致光线不能有效地进入本像素的Microlens内,而是进入相邻像素单元或其他无效区域内的现象。
在这里插入图片描述

Electric cross-talk:相邻单元之间的光生少数载流子通过衬底扩散和漏电相互影响造成相邻单元的现象。
在这里插入图片描述

上述原因导致结果都是图像在对角线上相邻两个像素的Gr和Gb value差异较大而产生不平滑的纹理状。

(18)Gradation Control(GDC):可能是对图像数据精度进行的操作

(19)Scaler:对图像进行缩放,缩放的过程中采样和插值直接影响图像的细节质量。

(20)Adaptive tone scale:(这个没有办法处理多种场景)进来的影像,根据histogram,可以调节,让其明暗亮度的曲线比较好看。因此,它最重要的就是histogram equalization,其关键是在哪个domain去做。目前我们的做法应该是在L*做histogram,但只做edge的histogram,这样就ok了。

(21)Dynamic Range Compression:就是把暗的地方变亮一些,亮的地方变暗一些。AE的主要目的是避免亮度饱和的pixels,其余exposure的pixel可以通过DRC校准回来。

(22)gamma:所谓伽玛校正就是对图像的伽玛曲线进行编辑,以对图像进行非线性色调编辑的方法,检出图像信号中的深色部分和浅色部分,并使两者比例增大,从而提高图像对比度效果。计算机绘图领域惯以此屏幕输出电压与对应亮度的转换关系曲线,称为伽玛曲线(Gamma Curve)。
在这里插入图片描述

3. 色彩模型

3.1 色彩模型,色彩空间,色域

色彩模型就是用一定规则来描述(排列)颜色的方法

在一个色彩模型下可以有不同的色彩空间,它们根据排列的条件的不同会有不同的色域(所能表示色彩的范围)和含义,色彩模型只有具体到一种色彩空间上才有实用性。

色域只是指某个对象能表示色彩范围,而不同色彩空间的色域大多是根据色彩空间设计者的具体需求和应用场景,人为决定的。
比如某显示器能显示的色彩范围是 xxx ,就可以设计一个刚好包含包含这个范围的色彩空间。比如用于数字电影的 ACES 系统的色域完全包括并超出了人类可见色域:
在这里插入图片描述

​ 色彩空间和色彩模型是容易混淆的概念,色彩模型是把色彩按规则排列的模型,而色彩空间是其在一定条件下排列的结果,在一个色彩模型下可以有不同的色彩空间,它们根据排列的条件的不同会有不同的色域(所能表示色彩的范围)和含义,色彩模型只有具体到一种色彩空间上才有实用性。Adobe RGB、sRGB、Apple RGB 就是同在 RGB 色彩模型下的不同色彩空间。

3.2 常见色彩模型

1.RGB

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2.YUV,YCbCr,YIQ

YUV 是一种目的为把颜色的视觉亮度分离来建立的色彩空间,Y (Luminance) 代表颜色的视觉亮度,U、V 则是剩余的色彩分量。
​ 与 HSB、HSL 的亮度或明度不同,视觉亮度代表的是颜色在人实际感受的亮度,之所以不同是因为不同色相的颜色的视觉亮度是不同的,比如纯绿色和纯蓝色,HSB 和 HSL 的模型里他们的亮度是一致的,但是在人眼中纯绿色明显要亮很多。

​ 一般的 YUV 模型中红绿蓝的视觉亮度比是:0.299:0.587:0.114

​ YUV 模型是在 1938 年法国工程师 Georges Valensi 为彩色电视制定的模型,为的是在彩色电视信号传输中用 Y 视觉亮度通道能与黑白电视共用一个信号通道,达到既向下兼容黑白电视信号,又节约信号带宽的目的。

	**YCbCr** 通常被当做 YUV 的另一种形式,相比 YUV, Cb 和 Cr 通道分别更向红、蓝偏移,而且通常进行压缩。YCbCr 常用在图像压缩领域,JPEG 图片内部的色彩空间就使用 YCbCr 模型。

​ YIQ 是另一种视觉亮度拆分模型,与 YUV 很相似,是 NTSC 彩色电视的标准,国内不太常见,因为国内用的是 PAL 标准,PAL 标准使用的是 YUV。

在这里插入图片描述

3.CMY,CMYK

​ 印刷色彩模式。C是青色Cyan、M是品红色Magenta、Y是黄色 Yellow,而K是Black最后一个字母。印刷色大多是根据这CMY三种颜色的油墨按照不同比例调出的。

​ CMY 是与 RGB 相对应的颜色,青、洋红、黄分别是红、绿、蓝的补色,也就是说颜色中青色成分越多代表红色成分越少,洋红、黄与蓝、绿也是这个关系,CMY 实际上相相当于在 RGB 都为 100% 的基础上减少颜色,比如 20%的 C 相当于 100% – 20% 的蓝。这就是根据反射光的减色原理制度的模型,用于颜料。

​ 在现实中由于颜料的纯度达不到理想的纯度,所以用 CMY 混合无色彩的灰、黑是很困难的,所以就增加了一个专门的黑色通道:K,(之所以不用 B (Black)来表示黑是为了不与蓝色(Bule)混淆),印刷界使用的色彩模型就 CMYK,所以它又被称为 印刷四分色模型。

在这里插入图片描述

4.HSB/HSV,HSL

在这里插入图片描述

HSB 与 HSL 是很相似的 2 个色彩空间,都是把色相与饱和度、亮度分离,不同的是 HSB 和 HSL 对亮度、饱和度拆分不同, HSB 的 B 明度(Brightness)是从黑色到色相颜色,而 HSL 的 L 亮度(Lightness)是从最暗到色相颜色再到白色,这意味着 HSL 取最大亮度时不管饱和度和色相如何都是白色,而 HSB 最大明度时是色相颜色,要达到白色还需要饱和度最小。

也就是说 HSB 的饱和度代表颜色远离白的程度,明度代表颜色远离黑的程度。而 HSL 的饱和度是颜色远离灰色的程度,亮度则代表了颜色在最暗到最亮之间的位置。
HSB 和 HSL 那种更方便一直是一场争论,PhotoShop 中拾色器使用的是 HSL 模型,而“色相\饱和度”命令用的是 HSB 模型,在 W3C 制定的网页标准中支持了 HSL 。

另外,HSL 实际上视觉亮度分布也很不均匀(同亮度值的颜色看起来实际亮度可能相差很大),所以有 HUSL 等对 HSL 改进的模型,它们视觉亮度分布更加均衡,对人类选择色彩更加直观(同亮度值颜色看起来亮度更加相等),不过由于计算更加复杂,并没有被广泛使用。

  1. HWB
  2. photaYCC
  3. Lab

3.3 色彩空间

RGB模型色彩空间:

sRGB

Adobe RGB

Apple RGB

Prophoto RGB

ScRGB

CMYK模型色彩空间

Japan color 2001coated

US web coated(SWOP)

4. 图像格式及转换

4.1 常见图像格式

在这里插入图片描述

详情参考

4.2 RGB,YUV颜色编码

4.2.1 RGB颜色编码

​ RGB 三个字母分别代表了 红(Red)、绿(Green)、蓝(Blue),这三种颜色称为 三原色,将它们以不同的比例相加,可以产生多种多样的颜色。

​ 在图像显示中,一张 1280 * 720 大小的图片,就代表着它有 1280 * 720 个像素点。其中每一个像素点的颜色显示都采用 RGB 编码方法,将 RGB 分别取不同的值,就会展示不同的颜色。

在这里插入图片描述

​ RGB 图像中,每个像素点都有红、绿、蓝三个原色,其中每种原色都占用 8 bit,也就是一个字节,那么一个像素点也就占用 24 bit,也就是三个字节。一张 1280 * 720 大小的图片,就占用 1280 * 720 * 3 / 1024 / 1024 = 2.63 MB 存储空间。

4.2.2 YUV 颜色编码

​ YUV 颜色编码采用的是 明亮度色度 来指定像素的颜色。其中,Y 表示明亮度(Luminance、Luma),而 U 和 V 表示色度(Chrominance、Chroma)。而色度又定义了颜色的两个方面:色调和饱和度。使用 YUV 颜色编码表示一幅图像,它应该下面这样的:

在这里插入图片描述

​ 和 RGB 表示图像类似,每个像素点都包含 Y、U、V 分量。但是它的 Y 和 UV 分量是可以分离的,如果没有 UV 分量一样可以显示完整的图像,只不过是黑白的。

​ 对于 YUV 图像来说,并不是每个像素点都需要包含了 Y、U、V 三个分量,根据不同的采样格式,可以每个 Y 分量都对应自己的 UV 分量,也可以几个 Y 分量共用 UV 分量。

4.3 RGB 到YUV转换

​ 对于图像显示器来说,它是通过 RGB 模型来显示图像的,而在传输图像数据时又是使用 YUV 模型,这是因为 YUV 模型可以节省带宽。因此就需要采集图像时将 RGB 模型转换到 YUV 模型,显示时再将 YUV 模型转换为 RGB 模型。

​ RGB 到 YUV 的转换,就是将图像所有像素点的 R、G、B 分量转换到 Y、U、V 分量。

有如下公式进行转换:
在这里插入图片描述

​ 此时的转换结束后,每个像素点都有完整的 Y、U、V 分量。而之前提到 Y 和 UV 分量是可以分离的,接下来通过不同的采样方式,可以将图像的 Y、U、V 分量重新组合。

4.4 YUV采样格式

YUV 图像的主流采样方式有如下三种:

  • YUV 4:4:4 采样
  • YUV 4:2:2 采样
  • YUV 4:2:0 采样

4.4.1 YUV 4:4:4采样

​ YUV 4:4:4 采样,意味着 Y、U、V 三个分量的采样比例相同,因此在生成的图像里,每个像素的三个分量信息完整,都是 8 bit,也就是一个字节。

如下图所示:

在这里插入图片描述

其中,Y 分量用叉表示,UV 分量用圆圈表示。

举个例子 :

假如图像像素为:[Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3]

那么采样的码流为:Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3 

最后映射出的像素点依旧为 [Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3] 
	可以看到这种采样方式的图像和 RGB 颜色模型的图像大小是一样,并没有达到节省带宽的目的,当将 RGB 图像转换为 YUV 图像时,也是先转换为 YUV 4:4:4 采样的图像。

4.4.2 YUV 4:2:2采样

	YUV 4:2:2 采样,意味着 UV 分量是 Y 分量采样的一半,Y 分量和 UV 分量按照 2 : 1 的比例采样。如果水平方向有 10 个像素点,那么采样了 10 个 Y 分量,而只采样了 5 个 UV 分量。

如下图所示:

在这里插入图片描述

其中,Y 分量用叉表示,UV 分量用圆圈表示。

 举个例子 :
  
 假如图像像素为:[Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3]

 那么采样的码流为:Y0 U0 Y1 V1 Y2 U2 Y3 V3 

 其中,每采样过一个像素点,都会采样其 Y 分量,而 U、V 分量就会间隔一个采集一个。

 最后映射出的像素点为 [Y0 U0 V1]、[Y1 U0 V1]、[Y2 U2 V3]、[Y3 U2 V3]

采样的码流映射为像素点,还是要满足每个像素点有 Y、U、V 三个分量。但是可以看到,第一和第二像素点公用了 U0、V1 分量,第三和第四个像素点公用了 U2、V3 分量,这样就节省了图像空间。

一张 1280 * 720 大小的图片,在 YUV 4:2:2 采样时的大小为:

(1280 * 720 * 8 + 1280 * 720 * 0.5 * 8 * 2)/ 8 / 1024 / 1024 = 1.76 MB 。

可以看到 YUV 4:2:2 采样的图像比 RGB 模型图像节省了三分之一的存储空间,在传输时占用的带宽也会随之减少。

4.4.3 YUV 4:2:0采样

​ YUV 4:2:0 采样,并不是指只采样 U 分量而不采样 V 分量。而是指,在每一行扫描时,只扫描一种色度分量(U 或者 V),和 Y 分量按照 2 : 1 的方式采样。比如,第一行扫描时,YU 按照 2 : 1 的方式采样,那么第二行扫描时,YV 分量按照 2:1 的方式采样。对于每个色度分量来说,它的水平方向和竖直方向的采样和 Y 分量相比都是 2:1 。

如下图所示:

在这里插入图片描述

其中,Y 分量用叉表示,UV 分量用圆圈表示。

假设第一行扫描了 U 分量,第二行扫描了 V 分量,那么需要扫描两行才能够组成完整的 UV 分量

举个例子 :
 
假设图像像素为:
 
[Y0 U0 V0]、[Y1 U1 V1]、 [Y2 U2 V2]、 [Y3 U3 V3]
[Y5 U5 V5]、[Y6 U6 V6]、 [Y7 U7 V7] 、[Y8 U8 V8]
 
那么采样的码流为:Y0 U0 Y1 Y2 U2 Y3 Y5 V5 Y6 Y7 V7 Y8
 
其中,每采样过一个像素点,都会采样其 Y 分量,而 U、V 分量就会间隔一行按照 2 : 1 进行采样。
 
最后映射出的像素点为:

[Y0 U0 V5]、[Y1 U0 V5]、[Y2 U2 V7]、[Y3 U2 V7]
[Y5 U0 V5]、[Y6 U0 V5]、[Y7 U2 V7]、[Y8 U2 V7]

从映射出的像素点中可以看到,四个 Y 分量是共用了一套 UV 分量,而且是按照 2*2 的小方格的形式分布的,相比 YUV 4:2:2 采样中两个 Y 分量共用一套 UV 分量,这样更能够节省空间。

一张 1280 * 720 大小的图片,在 YUV 4:2:0 采样时的大小为:

(1280 * 720 * 8 + 1280 * 720 * 0.25 * 8 * 2)/ 8 / 1024 / 1024 = 1.32 MB 。

可以看到 YUV 4:2:0 采样的图像比 RGB 模型图像节省了一半的存储空间,因此它也是比较主流的采样方式。

4.5 YUV存储格式

YUV 的存储格式,有两种:

  • planar 平面格式
    • 指先连续存储所有像素点的 Y 分量,然后存储 U 分量,最后是 V 分量。
  • packed 打包模式
    • 指每个像素点的 Y、U、V 分量是连续交替存储的。

根据采样方式和存储格式的不同,就有了多种 YUV 格式。这些格式主要是基于 YUV 4:2:2 和 YUV 4:2:0 采样。

常见的基于 YUV 4:2:2 采样的格式如下表:

YUV 4:2:2 采样
YUYV 格式
UYVY 格式
YUV 422P 格式

常见的基于 YUV 4:2:0 采样的格式如下表:

YUV 4:2:0 采样 YUV 4:2:0 采样
YUV 420P 类型 YV12 格式 YU12 格式
YUV 420SP 类型 NV12 格式 NV21 格式

更多的 YUV 格式信息参考这里:YUV pixel formats

4.5.1 基于YUV 4:2:2采样的格式

YUV 4:2:2 采样规定了 Y 和 UV 分量按照 2: 1 的比例采样,两个 Y 分量公用一组 UV 分量。

1.YUYV格式

YUYV 格式是采用打包格式进行存储的,指每个像素点都采用 Y 分量,但是每隔一个像素采样它的 UV 分量,排列顺序如下:

Y0 UO Y1 V0 Y2 U2 Y3 V2

Y0 和 Y1 公用 U0 V0 分量,Y2 和 Y3 公用 U2 V2 分量….

在这里插入图片描述

2.UYVY格式

UYVY 格式也是采用打包格式进行存储,它的顺序和 YUYV 相反,先采用 U 分量再采样 Y 分量,排列顺序如下:

U0 Y0 V0 Y1 U2 Y2 V2 Y3

Y0 和 Y1 公用 U0 V0 分量,Y2 和 Y3 公用 U2 V2 分量….

根据 UV 和 Y 的顺序还有其他格式,比如,YVYU 格式,VYUY 格式等等,原理大致一样了。

在这里插入图片描述

3.YUV 422P格式

​ YUV 422P 格式,又叫做 I422,采用的是平面格式进行存储,先存储所有的 Y 分量,再存储所有的 U 分量,再存储所有的 V 分量。

4.5.2 基于YUV 4:2:0 采样的格式

1.分类

基于 YUV 4:2:0 采样的格式主要有 YUV 420P 和 YUV 420SP 两种类型,每个类型又对应其他具体格式。

  • YUV 420P 类型
    • YU12 格式
    • YV12 格式
  • YUV 420SP 类型
    • NV12 格式
    • NV21 格式

YUV 420P 和 YUV 420SP 都是基于 Planar 平面模式 进行存储的,先存储所有的 Y 分量后, YUV420P 类型就会先存储所有的 U 分量或者 V 分量,而 YUV420SP 则是按照 UV 或者 VU 的交替顺序进行存储了,具体查看看下图:

YUV420SP 的格式:

在这里插入图片描述

YUV420P 的格式:

在这里插入图片描述

2.YU12 和 YV12 格式

YU12 和 YV12 格式都属于 YUV 420P 类型,即先存储 Y 分量,再存储 U、V 分量,区别在于:YU12 是先 Y 再 U 后 V,而 YV12 是先 Y 再 V 后 U 。

YV 12 的存储格式如下图所示:
在这里插入图片描述

YU 12 又称作 I420 格式,它的存储格式就是把 V 和 U 反过来了。

3.NV12 和 NV21 格式

NV12 和 NV21 格式都属于 YUV420SP 类型。它也是先存储了 Y 分量,但接下来并不是再存储所有的 U 或者 V 分量,而是把 UV 分量交替连续存储。

NV12 是 IOS 中有的模式,它的存储顺序是先存 Y 分量,再 UV 进行交替存储。

在这里插入图片描述

NV21 是 安卓 中有的模式,它的存储顺序是先存 Y 分量,在 VU 交替存储。


个人博客:https://www.letcos.top/

LSC

2017-12-01 18:11:21 u010830004 阅读数 3061
  • 噪声与去噪

    通过本课程的学习,可以对数字成像系统知识整体上得到理解,在相机等成像产品的开发,获得理论与实际的帮助。

    1160人学习 姜卓
    免费试看

概述

介绍

镜头阴影校正(Lens Shading Correction)是为了解决由于lens的光学特性,由于镜头对于光学折射不均匀导致的镜头周围出现阴影的情况。

shading可以细分为luma shading和color shading:

  • luma shading: 
    由于Lens的光学特性,Sensor影像区的边缘区域接收的光强比中心小,所造成的中心和四角亮度不一致的现象。镜头本身就是一个凸透镜,由于凸透镜原理,中心的感光必然比周边多。如图所示: 
    这里写图片描述

  • chrom/color shading: 
    由于各种颜色的波长不同,经过了透镜的折射,折射的角度也不一样,因此会造成color shading的现象,这也是为什么太阳光经过三棱镜可以呈现彩虹的效果。如图所示: 
    这里写图片描述

此外,还有CRA的原因会导致shading现象的出现,这里不再赘述,这里推荐《What’s CRA》这篇文章,详细讲述了由于镜头的CRA带来的shading。

影响

luma shading:会造成图像边角偏暗,就是所谓的暗角。 
这里写图片描述

color shading:中心和四周颜色不一致,体现出来一般为中心或者四周偏色。如图所示: 
这里写图片描述

校正

lens shading的校正是分别对于bayer的四个通道进行校正,每个通道的校正过程是相对独立的过程。

考虑到芯片设计的成本,因此一般情况下不会存储整幅图像的lut,目前主流的都是存储128*128个点的增益,利用双线性插值的方法计算每个pixel的增益。

算法

由于条件限制,图像仅用于算法验证,不做图像质量评判标准 
这里写了一个shading的算法,将图像分为16x16的方块,求取每个交点的增益值,对平面进行四次方拟合,分别计算了luma shading 和 chrom shading,先计算出来一个lut用于存储,校正的世行通过对这个lut进行双线性插值得到每个pixel的值乘以原本像素点。

16x16的分块并非固定,可以对块的大小进行调整,比如中心块偏大,靠近边缘的方块变小,这些都是可以自定义的,本算法由于做演示使用,故不做其他功能。如图所示: 
这里写图片描述

code

由于代码量较大,这里分别附上一部分算法

shading lut caculate:

function [image_r_gain, image_gr_gain, image_gb_gain, image_b_gain] = ...
isp_lsc_lut(image_r, image_gr, image_gb, image_b, side_num)
[height, width] = size(image_r);
side_y = floor(height/side_num);
side_x = floor(width/side_num);

% figure,imshow(image_r);
% hold on;
% for k=0:side_num
%     line_x = side_x * k;
%     line_y = side_y * k;
%     if(k==side_num && line_y ~= width) line_y = height;end
%     if(k==side_num && line_x ~= width) line_x = width;end
%     line([line_x,line_x],[0,height],'Color','red');
%     line([0,width], [line_y, line_y],'Color','red');
% %     line(Xd,Yd,'Color','red');
% end
% hold off

%% compress resolution
image_point = zeros(side_num,side_num);
for i = 0:side_num
    for j = 0:side_num
        x_clip = floor([j*side_x - side_x/2, j*side_x + side_x/2]);
        y_clip = floor([i*side_y - side_y/2, i*side_y + side_y/2]);
        if(i==side_num && y_clip(2) ~= height) y_clip(2) = height;end
        if(j==side_num && x_clip(2) ~= width) x_clip(2) = width;end
        x_clip(x_clip<1) = 1;x_clip(x_clip>width) = width;
        y_clip(y_clip<1) = 1;y_clip(y_clip>height) = height;
        data_r_in = image_r(y_clip(1):y_clip(2), x_clip(1):x_clip(2));
        image_r_point(i+1,j+1) = mean(mean(data_r_in));
        data_gr_in = image_gr(y_clip(1):y_clip(2), x_clip(1):x_clip(2));
        image_gr_point(i+1,j+1) = mean(mean(data_gr_in));
        data_gb_in = image_gb(y_clip(1):y_clip(2), x_clip(1):x_clip(2));
        image_gb_point(i+1,j+1) = mean(mean(data_gb_in));
        data_b_in = image_b(y_clip(1):y_clip(2), x_clip(1):x_clip(2));
        image_b_point(i+1,j+1) = mean(mean(data_b_in));
    end
end

% figure,imshow(uint8(image_r_point));
%% caculate lsc luma gain
for i = 1:side_num+1
    for j = 1:side_num+1
        image_r_luma_gain_point(i,j) = mean2(image_r_point(uint8(side_num/2)-1:uint8(side_num/2)+1, uint8(side_num/2)-1:uint8(side_num/2)+1)) / image_r_point(i,j);
        image_gr_luma_gain_point(i,j) = mean2(image_gr_point(uint8(side_num/2)-1:uint8(side_num/2)+1, uint8(side_num/2)-1:uint8(side_num/2)+1)) / image_gr_point(i,j);
        image_gb_luma_gain_point(i,j) = mean2(image_gb_point(uint8(side_num/2)-1:uint8(side_num/2)+1, uint8(side_num/2)-1:uint8(side_num/2)+1)) / image_gb_point(i,j);
        image_b_luma_gain_point(i,j) = mean2(image_b_point(uint8(side_num/2)-1:uint8(side_num/2)+1, uint8(side_num/2)-1:uint8(side_num/2)+1)) / image_b_point(i,j);
    end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

bilinear interpolation:

image_r_luma_gain_reshape = reshape(image_r_luma_gain_point, [], 1);
image_gr_luma_gain_reshape = reshape(image_gr_luma_gain_point, [], 1);
image_gb_luma_gain_reshape = reshape(image_gb_luma_gain_point, [], 1);
image_b_luma_gain_reshape = reshape(image_b_luma_gain_point, [], 1);
for i = 1:17
    for j = 1:17
        x((i-1)*17+j) = i;
        y((i-1)*17+j) = j;
    end
end
x=x';
y=y';
% scatter3(x,y,image_r_luma_gain_reshape)
% hold on
Z=[ones(length(x),1),x,y,x.^2,x.*y,y.^2,x.^3,x.^2.*y,x.*y.^2,y.^3];
[x y]=meshgrid(1:17,1:17);
A=Z\image_r_luma_gain_reshape;
image_r_luma_gain=A(1)+A(2)*x+A(3)*y+A(4)*x.^2+A(5)*x.*y+A(6)*y.^2+A(7)*x.^3+A(8)*x.^2.*y+A(9)*x.*y.^2+A(10)*y.^3;
A=Z\image_gr_luma_gain_reshape;
image_gr_luma_gain=A(1)+A(2)*x+A(3)*y+A(4)*x.^2+A(5)*x.*y+A(6)*y.^2+A(7)*x.^3+A(8)*x.^2.*y+A(9)*x.*y.^2+A(10)*y.^3;
A=Z\image_gb_luma_gain_reshape;
image_gb_luma_gain=A(1)+A(2)*x+A(3)*y+A(4)*x.^2+A(5)*x.*y+A(6)*y.^2+A(7)*x.^3+A(8)*x.^2.*y+A(9)*x.*y.^2+A(10)*y.^3;
A=Z\image_b_luma_gain_reshape;
image_b_luma_gain=A(1)+A(2)*x+A(3)*y+A(4)*x.^2+A(5)*x.*y+A(6)*y.^2+A(7)*x.^3+A(8)*x.^2.*y+A(9)*x.*y.^2+A(10)*y.^3;
% surf(x,y,image_r_luma_gain)
% hold on 
% surf(x,y,image_r_luma_gain_point)


%% calulate lsc chroma gain
for i = 1:side_num+1
    for j = 1:side_num+1
        image_r_chroma_gain(i,j) = image_r_luma_gain(i,j) - image_r_luma_gain_point(i,j);
        image_gr_chroma_gain(i,j) = image_gr_luma_gain(i,j) - image_gr_luma_gain_point(i,j);
        image_gb_chroma_gain(i,j) = image_gb_luma_gain(i,j) - image_gb_luma_gain_point(i,j);
        image_b_chroma_gain(i,j) = image_b_luma_gain(i,j) - image_b_luma_gain_point(i,j);
    end
end
%% caculate lsc result gain
image_r_gain = image_r_luma_gain - image_r_chroma_gain;
image_gr_gain = image_gr_luma_gain - image_gr_chroma_gain;
image_gb_gain = image_gb_luma_gain - image_gb_chroma_gain;
image_b_gain = image_b_luma_gain - image_b_chroma_gain;



function image_gain_lut = lsc_data_gain_interpolation(image_gain, height, width, side_num)
side_y_ori = floor(height/side_num);
side_x_ori = floor(width/side_num);
k = 0;
l = 0;
[gain_height, gain_width] = size(image_gain);
for i = 1:gain_height-1
    for j = 1:gain_width-1
        data_gain_11 = image_gain(i, j);
        data_gain_12 = image_gain(i, j+1);
        data_gain_21 = image_gain(i+1, j);
        data_gain_22 = image_gain(i+1, j+1);
        if(j == gain_width-1 && ((j-1)*side_x + l) ~= width) 
            side_x = width - (j-1)*side_x_ori;
        else
            side_x = side_x_ori;
        end

        if(i == gain_width-1 && ((i-1)*side_y + k) ~= width)
            side_y = height - (i-1)*side_y_ori;
        else
            side_y = side_y_ori;
        end

        for k = 1:side_y
            for l = 1:side_x
                label_y1 = 1;
                label_x1 = 1;
                label_y2 = side_y;
                label_x2 = side_x;
                image_gain_lut((i-1)*side_y_ori + k, (j-1)*side_x_ori + l) = ...
                    data_gain_22/(label_x2-label_x1)/(label_y2-label_y1)* ...
                    (l - label_x1) * (k - label_y1) + ...
                    data_gain_21/(label_x2-label_x1)/(label_y2-label_y1)* ...
                    (label_x2 - l) * (k - label_y1) + ...
                    data_gain_12/(label_x2-label_x1)/(label_y2-label_y1)* ...
                    (l - label_x1) * (label_y2 - k) + ...
                    data_gain_11/(label_x2-label_x1)/(label_y2-label_y1)* ...
                    (label_x2 - l) * (label_y2 - k);
            end
        end

    end
end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92

效果展示:

实验条件有限,图片有水波纹,仅用于理解算法

original image: 
这里写图片描述

luma shading

这里写图片描述
这里写图片描述
这里写图片描述

chroma shading 
这里写图片描述
这里写图片描述
这里写图片描述

luma shading + chroma shading: 
这里写图片描述
这里写图片描述
这里写图片描述

tuning

LSC的tuning一定要把校正图采集好,一般情况下raw图的G通道中心亮度在8bit的70%~80%之间,由于在不同色温情况下是经过插值的,因此需要校正多个光源,一般情况下TL84、D65、A光源下进行校正。将得到的LUT写入RAM中即可 
注意:采集的raw图不要有filcker。

LSC强度一般是可调的,由于图像边角的增益会很大,因此在高倍gain下,可以把强度给降低,防止图像边角噪声压不住的情况。

由于各个平台不同,这里不做详细介绍,想到再补充。

2015-01-16 09:50:51 Dorkdomain 阅读数 2329
  • 噪声与去噪

    通过本课程的学习,可以对数字成像系统知识整体上得到理解,在相机等成像产品的开发,获得理论与实际的帮助。

    1160人学习 姜卓
    免费试看

一个序列有N个数:A[1],A[2],…,A[N],求出最长非降子序列的长度。 (讲DP基本都会讲到的一个问题LIS:longest increasing subsequence)

正如上面我们讲的,面对这样一个问题,我们首先要定义一个“状态”来代表它的子问题, 并且找到它的解。注意,大部分情况下,某个状态只与它前面出现的状态有关, 而独立于后面的状态。

让我们沿用“入门”一节里那道简单题的思路来一步步找到“状态”和“状态转移方程”。 假如我们考虑求A[1],A[2],…,A[i]的最长非降子序列的长度,其中i<N, 那么上面的问题变成了原问题的一个子问题(问题规模变小了,你可以让i=1,2,3等来分析) 然后我们定义d(i),表示前i个数中以A[i]结尾的最长非降子序列的长度。OK, 对照“入门”中的简单题,你应该可以估计到这个d(i)就是我们要找的状态。 如果我们把d(1)到d(N)都计算出来,那么最终我们要找的答案就是这里面最大的那个。 状态找到了,下一步找出状态转移方程。

为了方便理解我们是如何找到状态转移方程的,我先把下面的例子提到前面来讲。 如果我们要求的这N个数的序列是:

5,3,4,8,6,7

根据上面找到的状态,我们可以得到:(下文的最长非降子序列都用LIS表示)

  • 前1个数的LIS长度d(1)=1(序列:5)
  • 前2个数的LIS长度d(2)=1(序列:3;3前面没有比3小的)
  • 前3个数的LIS长度d(3)=2(序列:3,4;4前面有个比它小的3,所以d(3)=d(2)+1)
  • 前4个数的LIS长度d(4)=3(序列:3,4,8;8前面比它小的有3个数,所以 d(4)=max{d(1),d(2),d(3)}+1=3)

OK,分析到这,我觉得状态转移方程已经很明显了,如果我们已经求出了d(1)到d(i-1), 那么d(i)可以用下面的状态转移方程得到:

d(i) = max{1, d(j)+1},其中j<i,A[j]<=A[i]

用大白话解释就是,想要求d(i),就把i前面的各个子序列中, 最后一个数不大于A[i]的序列长度加1,然后取出最大的长度即为d(i)。 当然了,有可能i前面的各个子序列中最后一个数都大于A[i],那么d(i)=1, 即它自身成为一个长度为1的子序列。




最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS。

排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了。

假设存在一个序列d[1..9] = 2 1 5 3 6 4 8 9 7,可以看出来它的LIS长度为5。
下面一步一步试着找出它。
我们定义一个序列B,然后令 i = 1 to 9 逐个考察这个序列。
此外,我们用一个变量Len来记录现在最长算到多少了

首先,把d[1]有序地放到B里,令B[1] = 2,就是说当只有1一个数字2的时候,长度为1的LIS的最小末尾是2。这时Len=1

然后,把d[2]有序地放到B里,令B[1] = 1,就是说长度为1的LIS的最小末尾是1,d[1]=2已经没用了,很容易理解吧。这时Len=1

接着,d[3] = 5,d[3]>B[1],所以令B[1+1]=B[2]=d[3]=5,就是说长度为2的LIS的最小末尾是5,很容易理解吧。这时候B[1..2] = 1, 5,Len=2

再来,d[4] = 3,它正好加在1,5之间,放在1的位置显然不合适,因为1小于3,长度为1的LIS最小末尾应该是1,这样很容易推知,长度为2的LIS最小末尾是3,于是可以把5淘汰掉,这时候B[1..2] = 1, 3,Len = 2

继续,d[5] = 6,它在3后面,因为B[2] = 3, 而6在3后面,于是很容易可以推知B[3] = 6, 这时B[1..3] = 1, 3, 6,还是很容易理解吧? Len = 3 了噢。

第6个, d[6] = 4,你看它在3和6之间,于是我们就可以把6替换掉,得到B[3] = 4。B[1..3] = 1, 3, 4, Len继续等于3

第7个, d[7] = 8,它很大,比4大,嗯。于是B[4] = 8。Len变成4了

第8个, d[8] = 9,得到B[5] = 9,嗯。Len继续增大,到5了。

最后一个, d[9] = 7,它在B[3] = 4和B[4] = 8之间,所以我们知道,最新的B[4] =7,B[1..5] = 1, 3, 4, 7, 9,Len = 5。

于是我们知道了LIS的长度为5。

!!!!! 注意。这个1,3,4,7,9不是LIS,它只是存储的对应长度LIS的最小末尾。有了这个末尾,我们就可以一个一个地插入数据。虽然最后一个d[9] = 7更新进去对于这组数据没有什么意义,但是如果后面再出现两个数字 8 和 9,那么就可以把8更新到d[5], 9更新到d[6],得出LIS的长度为6。

然后应该发现一件事情了:在B中插入数据是有序的,而且是进行替换而不需要挪动——也就是说,我们可以使用二分查找,将每一个数字的插入时间优化到O(logN)~~~~~于是算法的时间复杂度就降低到了O(NlogN)~!


转载 出自 http://www.felix021.com/blog/read.php?1587

图像调试基本术语

阅读数 263