ISP基础与算法

 ISP主要做下面的工作:

AEC(自动曝光控制)、AGC(自动增益控制)、AWB(自动白平衡)、色彩校正、Lens Shading、Gamma 校正、祛除坏点、Auto Black Level、Auto White Level

 

什么是ISP,它的工作原理是怎样的?

ISP是Image Signal Processor的缩写,全称是影像处理器。在相机成像的整个环节中,它负责接收感光元件(Sensor)的原始信号数据,可以理解为整个相机拍照、录像的第一步处理流程,对图像质量起着非常重要的作用。

 

ISP的功能比较杂,基本上跟图像效果有关的它都有份。它内部包含多个图像算法处理模块,其中比较有代表性的是:扣暗电流(去掉底电流噪声),线性化(解决数据非线性问题),shading(解决镜头带来的亮度衰减与颜色变化),去坏点(去掉sensor中坏点数据),去噪(去除噪声),demosaic(raw数据转为RGB数据),3A(自动白平衡,自动对焦,自动曝光),gamma(亮度映射曲线,优化局部与整体对比度),旋转(角度变化),锐化(调整锐度),缩放(放大缩小),色彩空间转换(转换到不同色彩空间进处理),颜色增强(可选,调整颜色),肤色增强(可选,优化肤色表现)等。

 

实际情况下,不同芯片的ISP,其处理流程和模块可能会稍有不同,但是其原理、实现功能都是一样的。

 

ISP基础一:

1、专业术语

【ColorTemp】 色温

        所谓色温,简而言之,就是定量地以开尔文温度(K)来表示色彩。英国著名物理学家开尔文认为,假定某一黑体物质,能够将落在其上的所有热量吸收,而没有损失,同时又能够将热量生成的能量全部以“光”的形式释放出来的话,它便会因受到热力的高低而变成不同的颜色。例如,当黑体受到的热力相当于500—550℃时,就会变成暗红色,达到1050-1150℃时,就变成黄色,温度继续升高会呈现蓝色。光源的颜色成分与该黑体所受的热力温度是相对应的,任何光线的色温是相当于上述黑体散发出同样颜色时所受到的“温度”,这个温度就用来表示某种色光的特性以区别其它,这就是色温。打铁过程中,黑色的铁在炉温中逐渐变成红色,这便是黑体理论的最好例子。色温现象在日常生活中非常普遍,相信人们对它并不陌生。钨丝灯所发出的光由于色温较低表现为黄色调,不同的路灯也会发出不同颜色的光,天然气的火焰是蓝色的,原因是色温较高。正午阳光直射下的色温约为5600 K,阴天更接近室内色温3200K。日出或日落时的色温约为2000K,烛光的色温约为1000K。

【备注】

黑体的定义:

⑴在任何温度下,完全吸收任何波长的外来辐射而无任何反射的物体。

⑵吸收比为1的物体。

⑶在任何温度下,对入射的任何波长的辐射全部吸收的物体。

黑体,是一个理想化了的物体,它能够吸收外来的全部电磁辐射,并且不会有任何的反射与透射。换句话说,黑体对于任何波长的电磁波的吸收系数为1,透射系数为0。但黑体不见得就是黑色的,即使它没办法反射任何的电磁波,它也可以放出电磁波来,而这些电磁波的波长和能量则全取决于黑体的温度,不因其他因素而改变。当然,黑体在700K以下时看起来是黑色的,但那也只是因为在700K之下的黑体所放出来的辐射能量很小且辐射波长在可见光范围之外。若黑体的温度高过上述的温度的话,黑体则不会再是黑色的了,它会开始变成红色,并且随着温度的升高,而分别有橘色、黄色、白色等颜色出现,即黑体吸收和放出电磁波的过程遵循了光谱,其轨迹为普朗克轨迹(或称为黑体轨迹)。黑体辐射实际上是黑体的热辐射。在黑体的光谱中,由于高温引起高频率即短波长,因此较高温度的黑体靠近光谱结尾的蓝色区域而较低温度的黑体靠近红色区域。

在室温下,黑体辐射的能量集中在长波电磁辐射和远红外波段;当黑体温度到几百摄氏度之后,黑体开始发出可见光。以钢材为例根据温度的升高过程,分别变为红色,橙色,黄色,当温度超过1300摄氏度时开始发白色和蓝色。当黑体变为白色的时候,它同时会放出大量的紫外线。

 

        色温规律:

        色温越高,光色越偏蓝;色温越低则偏红。

        某一种色光比其它色光的色温高时,说明该色光比其它色光偏蓝,反之则偏红;

        同样,当一种色光比其它色光偏蓝时说明该色光的色温偏高,反之偏低。

 

   由于人眼具有独特的适应性,使我们有的时候不能发现色温的变化。比如在钨丝灯下呆久了,并不会觉得钨丝灯下的白纸偏红,如果突然把日光灯改为钨丝灯照明,就会觉查到白纸的颜色偏红了,但这种感觉也只能够持续一会儿。

       摄像机的CCD并不能像人眼那样具有适应性,所以如果摄像机的色彩调整同景物照明的色温不一致就会发生偏色。白平衡就是为了避免偏色的出现。从而引出白平衡概念。

 

【AWB】Auto White Balance 

概念

       白平衡就是针对不同色温条件下,通过调整摄像机内部的色彩电路使拍摄出来的影像抵消偏色,更接近人眼的视觉习惯。白平衡可以简单地理解为在任意色温条件下,摄像机镜头所拍摄的标准白色经过电路的调整,使之成像后仍然为白色。这是一种经常出现的情况,但不是全部,白平衡其实是通过摄像机内部的电路调整(改变蓝、绿、红三个CCD电平的平衡关系)使反射到镜头里的光线都呈现为消色。如果以偏红的色光来调整白平衡,那么该色光的影像就为消色,而其他色彩的景物就会偏蓝(补色关系)。

      【备注】消色就是指黑白灰三种颜色。黑白灰的物体对光源的光谱成分不是有选择地吸收和反射而是等量吸收和等量反射各种光谱成分。这时物体看上去没有了色彩。对各种光谱成分全部吸收的表面,看上去是黑色,等量吸收一部分等量反射一部分的表面是灰色,反射绝大部分而吸收极小部分是白色。消色和任何色彩搭配在一起,都显得和谐协调。

       白平衡是一个很抽象的概念,最通俗的理解就是让白色所成的像依然为白色,如果白是白,那其他景物的影像就会接近人眼的色彩视觉习惯。调整白平衡的过程叫做白平衡调整,白平衡调整在前期设备上一般有三种方式:预置白平衡、手动白平衡调整和自动跟踪白平衡调整。通常按照白平衡调整的程序,推动白平衡的调整开关,白平衡调整电路开始工作,自动完成调校工作,并记录调校结果。如果掌握了白平衡的工作原理,那么使用起来会更加有的放矢,得心应手。

工作原理

         摄像机内部有三个CCD电子耦合元件,他们分别感受蓝色、绿色、红色的光线,在预置情况下这三个感光电路电子放大比例是相同的,为1:1:1的关系,白平衡的调整就是根据被调校的景物改变了这种比例关系。比如被调校景物的蓝、绿、红色光的比例关系是2:1:1(蓝光比例多,色温偏高),那么白平衡调整后的比例关系为1:2:2,调整后的电路放大比例中明显蓝的比例减少,增加了绿和红的比例,这样被调校景物通过白平衡调整电路到所拍摄的影像,蓝、绿、红的比例才会相同。也就是说如果被调校的白色偏一点蓝,那么白平衡调整就改变正常的比例关系减弱蓝电路的放大,同时增加绿和红的比例,使所成影像依然为白色

       换一个思路来考虑白平衡调整的问题,摄像机在白平衡调整容度之内不会“拒绝”放在镜头前面的被调校景物,就是说镜头可以对着任何景物来调整白平衡。大多情况下使用白色的调白板(卡)来调整白平衡,是因为白色调白板(卡)可最有效地反映环境的色温,其实很多时候某种环境下白板(卡)并不是白色,多多少少会偏一点蓝或其它的颜色,经验丰富的摄像也会利用蓝天来调白平衡,从而得到偏红黄色调的画面。搞清楚白平衡的工作原理之后,再使用的时候就会大胆地尝试不同的效果,丰富了摄像创作。

       数码相机白平衡的调整通常有三种模式;自动白平衡,分档设定白平衡,精确设定白平衡(手动设定模式)。不同的相机设有不同调节白平衡的方式。一般的普及型的数码相机大都采用自动白平衡。准专业数码相机大都设有分档设定白平衡。专业的数码相机设有精确白平衡(手动设定模式)。专业数码相机这三种模式的白平衡都拥有,准专业数码相机拥有自动和分档设定白平衡。可根据使用者的不同需要而选用。

       自动白平衡,是依赖数码相机里的测色温系统,测出红光和蓝光的相对比例。再依据次数据调整曝光,产生红、绿、蓝电信号的增益。自动白平衡最大的优势是;简单、快洁。但有时按它的调整拍摄离准确的色彩还原还相距甚远。有时它还会帮倒忙。

       分档设定白平衡,是按光源种类分和色温值分两类。大多数数码相机都是按光源种类分的这类。在相机上分别设有日光、阴天、日光灯、白炽灯、闪光灯的图标档位。拍摄时只需将拍摄时的光源种类和相机上的白平衡档位相吻合就可拍出较为准确的色彩。但由于分设档位少,分设档位的精度不高,在一些特殊光照条件下拍摄就不能准确的记录色彩。按色温分类的白平衡,理论上讲其精度要高于按光源种类分档。但它要求使用者要记住各种光源的色温值,这就给使用者带来极大的麻烦。故用此分档白平衡的相机较少。

 

精确白平衡(手动设定模式),是在拍摄现场光的条件下,用白纸或白色物体充满镜头视野进行白平衡调节。经过这样的调试再拍摄,记录的色彩将是非常准确的这是目前最准确的白平衡调节方式。白平衡的功能给我们摄影带来了许多的便利和意想不到的效果。如摄影棚摄影对灯光的色温要求就可不必那么高。白炽灯下依然可拍出准确的色彩。也不必为日光灯给我们带来的青色而烦恼。我们可以在较高色温条件下设定白平衡,在较低色温情况下拍摄,使画面带上暖色调。反之,也可在低色温条件下设定,在高色温下拍摄也可产生特别的效果。在分档设定白平衡里,也可有意的将光源档与现场光设定不一致,亦可同样的产生不同的艺术效果

【AE】Auto Exposure

       自动曝光是相机根据光线的强弱自动调整曝光量,防止曝光过度或者不足,但是,在场景反差很大的时候会出现误差(比如舞台的场景),光圈优先和快门优先都是自动曝光的范畴,除非很高档的相机,这两种功能不会同时出现在一个相机上,在自动曝光的同时也让你有部分选择的权利,当使用光圈优先的功能时,特别是小光圈时,要注意此时的快门速度会相应的调得很低,端稳相机防止图像不清晰

       自动曝光,主要分为三类,全自动程式曝光、光圈先决曝光、快门先决曝光

 

【CCM】Color Correction Matrix

【IMP】?

【AI】Auto Iris 自动光圈

【AntiFlicker 】 抗闪烁

 

【ColorTone】冷暖色调

色彩的冷暖分别。色彩学上根据心理感受,把颜色分为暖色调(红、橙、黄)、冷色调(青、蓝)和中性色调(紫、绿、黑、灰、白)。

 

【RDC】Dynamic Range Compression

  即动态范围压缩,目的是调整图像的动态范围,使得图像显示出更多的信息。 DRC 模块是一个基于人眼视觉系统特性的高级局部色阶映射(多空间动态范围压缩)引擎。

【AntiFalseColor】去假彩

 

    真彩色(True Color):真彩色是指在组成一幅彩色图像的每个像素值中,有R、G、B三个基色分量,每个基色分量直接决定显示设备的基色强度产生彩色。

    伪彩色(Pseudo Color):每个像素的颜色不是由每个基色分量的数值直接决定,而是把像素值当作颜色查找表(color look-up table,CLUT)的表项入口地址,去查找一个显示图像时使用的R,G,B强度值,用查找出的R,G,B强度值合成产生彩色。

 

    假彩色(False Color):将多波段单色影像合成为假彩色影像,如landsat 7/ETM+有八个波段,用其中三个合成就是假彩色

从实现技术上讲,假彩色与真彩色是一致的,都是R、G、B分量组合显示;伪彩色显示调用的是颜色表。

ISP基础与算法_第1张图片

 

【AntiFog】去雾

去雾原理很复杂,可以参考链接:

http://blog.csdn.net/baimafujinji/article/details/27206237

http://blog.csdn.net/occupy8/article/details/40322683

【Defect Pixel】坏点

【ShadingAttr】暗角校正属性

【ShadingTable】暗角补偿查找表

【Denoise】噪点抑制

【SharpenAttr】边缘锐化属性

【DemosaicAttr】去马赛克属性

【NoiseProfile】噪声型式表

【CrosstalkAttr】CrossTalk remove Attr

【DIS】?

【FPN】



算法部分

RAW DATA去噪(1)

ISP(图像信号处理器),主要用来对前端图像传感器输出信号处理的单元,主要用于手机,监控摄像头等设备上。

RAW DATA,可以理解为:RAW图像就是CMOS或者CCD图像感应器将捕捉到的光源信号转化为数字信号的原始数据,是无损的,包含了物体的原始的颜色信息等。

RAW数据格式一般采用的是Bayer排列方式,通过滤波光片,产生彩色滤波矩阵(CFA)

鉴于人眼对绿色波段的色彩比较敏感,Bayer的数据格式中包含了50%的绿色信息,以及各25%的红色和蓝色信息。

Bayer的排列格式有以下4种:

ISP基础与算法_第2张图片

在ISP处理模块的第一部分,就是需要对CFA DATA进行去噪操作。普通的去噪方法针对Bayer数据格式是不合适的,需要进行变换后,才能进行处理。



一、中值滤波CFA Data 去噪方法

首先,让我们一起来回顾一下中值滤波的算法原理和以及优缺点,然后给出示意的算法效果图。

中值滤波顾名思义就是将滤波器里面所有的像素值进行排序,然后用中间值替代当前像素点值

常用的中值滤波器有3*3,5*5等

中值滤波的优点是:实现简单,能够有效地消除“校验”噪声,以及其它脉冲型噪声。缺点,也是所有去噪算法所共有的,就是平滑模糊了图像的内容,有些角点以及边缘的信息损失。

 

对CFA DATA进行去噪时,需要将不同的颜色通道分开进行处理,这样是为了防止在平滑过程中将有用的颜色信息丢掉,比如说,由绿色信息包围的蓝色像素与其相差很大时,此时就会被认为是噪声处理掉,然而真实情况是,该区域的蓝色信息都是很大的。所以各通道独立处理的话,是有利于保护颜色信息的。

 

在下面的这个处理过程中,是将原CFA DATA分成4块-R,G1,G2,B,分块去噪完成后,再重新恢复到原来的位置,这样整个过程就完成了。

 

中值滤波和C++(MFC)代码主程序、主函数:

void main()
{

	/*******开始编写中值滤波去噪模块--2015.07.27***********/
	//针对R分量块进行去噪
	pNewDoc->m_RBlock  = new unsigned short [m_Height*m_Width/4];
	pNewDoc->m_G1Block = new unsigned short [m_Height*m_Width/4];
	pNewDoc->m_G2Block = new unsigned short [m_Height*m_Width/4];
	pNewDoc->m_BBlock  = new unsigned short [m_Height*m_Width/4];

	unsigned short* smoothR  = new unsigned short[m_Height*m_Width/4];
	unsigned short* smoothG1 = new unsigned short[m_Height*m_Width/4];
	unsigned short* smoothG2 = new unsigned short[m_Height*m_Width/4];
	unsigned short* smoothB  = new unsigned short[m_Height*m_Width/4];
	for (int i = 0; i < m_Height/2 ;i ++ )
	{
		for(int j = 0; j < m_Width/2 ; j ++ )
		{
			pNewDoc->m_RBlock [i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + j*2];
			pNewDoc->m_G1Block[i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + j*2 + 1];
			pNewDoc->m_G2Block[i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + m_Width + j*2];
			pNewDoc->m_BBlock [i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + m_Width + j*2 + 1];
		}
	}
	medianFilter(pNewDoc->m_RBlock,smoothR,m_Width/2,m_Height/2);   //针对R分量块进行去噪
	medianFilter(pNewDoc->m_G1Block,smoothG1,m_Width/2,m_Height/2); //针对G1分量块进行去噪
	medianFilter(pNewDoc->m_G2Block,smoothG2,m_Width/2,m_Height/2); //针对G2分量块进行去噪
	medianFilter(pNewDoc->m_BBlock,smoothB,m_Width/2,m_Height/2);   //针对B分量块进行去噪

	//反过来构造去噪去噪后的raw data
	for (int i = 0; i < m_Height/2 - 1;i ++ )
	{
		for(int j = 0; j < m_Width/2-1; j ++ )
		{
			pNewDoc->m_ImageNR[i*m_Width*2 + j*2] = smoothR[i*m_Width/2 + j];
			pNewDoc->m_ImageNR[i*m_Width*2 + j*2 + 1] = smoothG1[i*m_Width/2 + j]; 
			pNewDoc->m_ImageNR[i*m_Width*2 + m_Width + j*2] = smoothG2[i*m_Width/2 + j];
			pNewDoc->m_ImageNR[i*m_Width*2 + m_Width + j*2 + 1] = smoothB[i*m_Width/2 + j];

		}
	}
	/***********中值滤波模块完成--2015.07.27********************/
	//SaveImageData(pNewDoc->m_ImageNR, m_Height ,m_Width,"E:\\m_ImageNR.bmp");
	SetDisplayRawImage( pNewDoc->m_ImageNR, m_Height ,m_Width, m_RawBitType,pNewDoc->m_Image);
}


void medianFilter (unsigned short* corrupted, unsigned short* smooth, int width, int height)  
{  
      
    memcpy ( smooth, corrupted, width*height*sizeof(unsigned short) );  
    for (int j=1;j

RAW DATA 去噪(2)-BM3D算法

在ISP模块里,研究者们会讨论去噪模块(Noise Reduction)到底是在去马赛克模块(Demosaic)之前还是之后进行。如果在之前处理的话,随着去噪过程的进行,噪声点消除的同时,伴随着色彩信息的损失;如果在这之后,复杂的插值过程将会改变噪声的统计模型,使其变得很复杂并且难以计算。所以,更多的情况是选择在Demosaic之前进行去噪操作。

 

CFA Data 不能采用传统的灰度图像去噪算法,因为CFA图像中相邻的像素点具有不同的颜色信息度量,CFA图像的块状结构与没有传统意义上的平滑性以及分段恒常性,以至于一般的去噪算法对CFA图像并不适用。CFA DATA也不能够采用彩色图像去噪算法,因为每个像素点只含有一个颜色通道的信息。

 

①一种方法是,将原来的CFA图像阵列分成四小块(R,G1,G2,B),分别对这四块采用灰度图像去噪的方法。这种方法往往表现差,因为重要的色彩相关性信息被忽视掉了。CFA去噪算法可以通过利用CFA Data的空间以及色彩相关性来改善其效果。

②另外一种方法是利用CFA图像里面各颜色块的信息构造一幅低分辨率的RGB图像,这种方式很好的利用了其颜色相关信息,但是不能够较好的保护空间域上的高频信息。

③BM3D(Block Matching 3-D filtering algorithm)算法的提出,通过限制图像块具有相同的颜色配置结构来达到处理CFA图像的目的。

 

下面的BD3D算法的详细介绍:

1.基础估计

1).逐块估计(Block-wise estimates)

分组(Grouping),找到所有与目前处理图像块相似的块,把它们堆在一起形成一个3维的数组(分组)。

联合硬阈值(Collaborative Hard-Thresholding).对已经组织好的分组进行3D变换,通过硬阈值3D变换系数达到减弱噪声的目的,然后通过3D反变换回去得到分组内图像块的去噪后估计,并返回到它们之前所在的位置。

2).聚集(Aggregation)

对所估计图像块重复遮盖的像素点进行加权平均,得到最终的像素值,也就是最后的基础估计结果。

 

2.最终估计

1).逐块估计(Block-wise estimates)

分组(Grouping),使用图像块匹配的方法,找到原噪声图像以及基础估计图像里面与目前处理图像块相似的所有块,形成两个3维数组(分组)。

联合维纳滤波(Collaborative wiener-filtering).对已经组织好的两个分组进行3D变换,将基础估计图像的能量频谱作为真实的能量频谱对噪声图像分组进行维纳滤波,然后通过3D反变换回去得到所有分组的图像块估计,并返回到它们之前所在的位置。

2).聚集(Aggregation)

对所有得到的估计图像块重复遮盖的像素点进行加权平均,得到最终的像素值,也就是最后的最终估计结果。

BM3D如何找到相似图像块组织3D分组:如下图所示,正方形所示为各个图像块,左上的分组所选取的图像块都具有角点(尖点)特征,其他分组类似。

BM3D如何在CFA中进行处理:如下图所示,左边的分组里面的图像块具有不同的彩色配置,即R,G,B的排列方式不是一致的,而右边具有相同的彩色配置,所以其对于处理CFA图像是非常合理的。

上面将BM3D的算法原理以及细节操作都跟大家介绍清楚了,下面就来看一下BM3D对于CFA图像的算法效果:

原噪声图像

中值滤波图像

BM3D去噪图像

算法效果(PSNR)明显优于中值滤波,去噪模块就此结束,下一篇开始给大家介绍两种色彩增强的算法。

原文1:https://blog.csdn.net/u013626386/article/details/47783677

原文2:https://blog.csdn.net/u013626386/article/details/47805303

 

二、彩色图像增强——ACE算法

 ACE(Automatic Color Enhancement),自动色彩增强算法,是一种对于彩色图像增强十分行之有效的方法。它的改进算法以及快速实现在文章Automatic Color Enhancement (ACE) and its Fast Implementation,2012中提出。

    在NxN的图像上,ACE算法的算法复杂度为O(N^4),文章提出的新的ACE算法采取了两种近似的方法,一是采用多项式函数逼近坡度函数(Slope function)降低卷积计算量,二是采用不同程度的插值来降低卷积的计算量。

    ACE算法具体步骤:

    第一步:分别对彩色图像的R,G,B通道进行单独处理,计算每个像素点的R(x)值,其中Sa(t)为坡度函数,表示如下,第一步适应局部图像对比,Sa(t)能够放大较小的差异,并且丰富大的差异,能够根据局部内容来扩展或者压缩动态范围:

            

          

    第二步:利用下面的公式将R(x)展到[0,1]之间,得到增强后的通道,第二步获得全局白平衡。

    

    第三步:求解最优化问题,ACE算法可以看做是对规范的直方图均衡化方法的一种平滑和局部修正的方法。

    

    改进方法所考虑的一些因素:

    1)其他的坡度函数Sa(t),多项式函数逼近

    

    2)除了1/||x-y||外的权重函数的选择

    3)在求和的过程中,y可以限制在x周围的一个小窗口中

    4)L(x)的一些其他的标准化方法

    实验效果:在官网上下载源代码,安装FFTW3库之后方能正常运行得到结果。该方法对于对比度低,或者有雾的图像处理后效果明显。

源代码链接网址:http://www.ipol.im/pub/art/2012/g-ace/

 FFTW3库下载以及配置链接:http://bbs.csdn.net/topics/390815673

    命令行:AutoColorEnhancement -a 5 -w 1/r -m interp:12 input.bmp output.bmp

                原图 

                                   

              ACE处理后

                                        原图

                                        ACE处理后

 

三、色彩增强算法——HSV空间Saturation通道调整

色彩增强不同于彩色图像增强,图像增强的一般处理方式为直方图均衡化等,目的是为了增强图像局部以及整体对比度。

而色彩增强的目的是为了使原有的不饱和的色彩信息变得饱和、丰富起来。对应于Photoshop里面的“色相/饱和度”选项里的对饱和度的操作。

色彩增强的过程,并不改变原有色彩图像的颜色以及亮度信息

 

在色彩增强算法里面,始终只针对色彩饱和度(Saturation)信息做研究、调整。这样的话,那就不得不介绍HSV颜色空间了,H代表Hue(色彩),S代表Saturation(饱和度),V代表Value,也可以用B表示(Brightness,明度),HSV空间又HSB空间。

 

HSV空间在wikipedia上的介绍,https://en.wikipedia.org/wiki/HSL_and_HSV 

    下面根据自己的理解介绍一下HSV空间,以及其各通道在Matlab和OpenCV中的不同。

    HSV的圆柱模型

    

    HSV的圆锥模型

    

    从上图可以看出,在HSV空间中,Hue通道的取值从0-360°变化时,颜色从红->黄->绿->青->蓝逐步变化。Saturation从0->1变化时,色彩逐渐加深变成纯色(pure)。Value值从0->1变化时,图像整体亮度增加,V值为0时,图像为全黑,V值为1时,图像为全白

    Matlab RGB色彩空间向HSV转换,采用函数rgb2hsv,转换后的hsv各通道的元素取值范围为[0,1];OpenCV中彩色图像向HSV空间中转换,cvtColor(src,srcHsv,CV_BGR2HSV),转换后H的取值范围为[0,180],S,V的取值范围为[0,255].

   下面介绍自己的算法处理思路,后面会给出完整的Matlab代码: 

   步骤一、给出一张原图src,用PS进行饱和度(Saturation)+40处理后另存为src_40;

   步骤二、将以上两张图像分别转换到hsv空间,提取出饱和度信息,分别为S,S_40;

   步骤三、统计饱和度增加40后,原色彩饱和度与饱和度增量之间的对应关系,即S -- (S_40-S);

   步骤四、对关系S -- (S_40-S)进行二次多项式曲线拟合,得到二次曲线f(x) = p1*x^2 + p2*x + p3;

   为什么是二次?1.对应关系呈现出抛物线形状;2.更高次曲线并没有明显改善拟合性能,且计算消耗会变高。

   步骤五、任意给定输出图像input,根据其色彩饱和度信息,即可进行色彩增强40处理,新的饱和度信息可以表示为S'(x) = S(x) + f(x),得到增强后的色彩信息后返回RGB图像输出;

   步骤六、分别对原图+20,+40,+60后进行饱和度信息统计,并得到相应拟合参数,设置为色彩增强的低、中、高三挡,在实际处理过程中,根据输入图像input自身色彩饱和度信息(均值)自适应选取相应参数进行色彩增强;

   步骤七、按需对某一单独颜色通道进行色彩增强处理,例如绿色范围为105°-135°,在对该范围进行增强的同时,还需对75°-105°,135°-165°进行一半强度的增强,这样才会保证色彩的连续性,不会出现色斑;

   步骤八、按需对色彩(Hue)进行转换;

   代码部分:第一部分用作估计拟合参数,在Curve fitting tool里面对X,Y进行拟合,得到曲线参数。

 

% Color Enhancement
clc,clear,close all
src1 = imread('src.bmp');
src2 = imread('src_40.bmp');

src1_hsv = rgb2hsv(src1);
src2_hsv = rgb2hsv(src2);

h1 = src1_hsv(:,:,1);
s1 = src1_hsv(:,:,2);
v1 = src1_hsv(:,:,3);

h2 = src2_hsv(:,:,1);
s2 = src2_hsv(:,:,2);
v2 = src2_hsv(:,:,3);
% 
meanS1 = mean(s1(:));
varS1  = std2(s1); 
% 
meanS2 = mean(s2(:));
varS2  = std2(s2); 
% 
deltaS = s2 - s1;
deltaV = v2 - v1;

%% test1 : 观测“原饱和度-饱和度调整增量”的关系 saturation and delta saturation
figure;
oriS = zeros(101,2);
s3 = s1;
j = 1;
for i = 0: 0.01 : 1
    oriS(j,1) = i + 0.01;
    oriS(j,2) =  mean(deltaS(find(s1 > i & s1< i + 0.01)));
    j = j + 1;
end
X  = oriS(:,1);
Y  = oriS(:,2);
XX = oriS(:,1) * 255;
YY = oriS(:,2) * 255;
plot(XX,YY)

 

 

   第二部分,对输入图像进行高、中、低三级自适应增强处理

 

 
  1. %% Color Enhancement Module -- Authored by HuangDao,08/17/2015

  2. % functions: input a image of type BMP or PNG, the program will decide to

  3. % do the Color Enhancement choice for you.There are four types of Enhanced

  4. % intensity - 20,40,60,80.The larger number stands for stronger

  5. % enhancement.

  6. % And we can also choose the simple color channel(eg.R,G,B) to do the

  7. % enhancement.There are also four different types of enhanced intensity.

  8. %

  9. % parameters table

  10. % ------------------------------------------------------------------------

  11. % | Enhanced | MATLAB params | OpenCV params |

  12. % | intensity |p1 p2 p3 | p1 p2 p3 |

  13. % | 20 |-0.1661 0.2639 -0.003626 |-0.0006512 0.2639 -0.9246|

  14. % | 40 |-0.4025 0.6238 -0.0005937 |0.001578 0.6238 -0.1514|

  15. % | 60 |1.332 1.473 -0.01155 |-0.005222 1.473 -2.946 |

  16. % | 80 |-4.813 3.459 -0.004568 |-0.01887 3.459 -1.165 |

  17. % ------------------------------------------------------------------------

  18.  
  19. clc; clear ;close all

  20. % 载入文件夹

  21. pathName = '.\';

  22. fileType = '*.bmp';

  23. files = dir([pathName fileType]);

  24. len = length(files);

  25.  
  26. for pic = 5%1:1:len

  27. srcName = files(pic).name;

  28. srcImg = imread(srcName);

  29. srcHSV = rgb2hsv(srcImg);

  30. srcH = srcHSV(:,:,1);

  31. srcS = srcHSV(:,:,2);

  32. srcV = srcHSV(:,:,3);

  33. meanS = mean(srcS(:));

  34. varS = std2(srcS);

  35. %图像整体进行色彩增强处理

  36. if (meanS >= 0.5)

  37. p1 = 0;p2 = 0;p3 = 0;

  38. else if (meanS >= 0.35 && meanS < 0.5)

  39. p1 = -0.1661;p2 = 0.2639;p3 = -0.003626;

  40. else if (meanS >=0.2 && meanS <0.35)

  41. p1 = -0.4025;p2 = 0.6238;p3 = -0.0005937;

  42. else

  43. p1 = 1.332;p2 = 1.473;p3 = -0.01155;

  44. end

  45. end

  46. end

  47. dstS = srcS + p1*srcS.*srcS + p2*srcS + p3 ;

  48. dstHSV = srcHSV;

  49. dstHSV(:,:,2) = dstS;

  50. dstImg = hsv2rgb(dstHSV);

  51. figure;imshow(srcImg);

  52. figure;imshow(dstImg);

  53. %指定R,G,B通道进行色彩增强处理,红色范围([225-255]),绿色范围(75-[105-135]-165),蓝色范围([-15-15])

  54. p11 = -0.4025;p21 = 0.6238;p31 = -0.0005937;%周边杂色调整系数,40

  55. p12 = 1.332; p22 = 1.473; p32 = -0.01155; %纯色区域调整系数,60

  56. compHue = srcH;

  57. GcompS = dstS;

  58. RcompS = dstS;

  59. BcompS = dstS;

  60. channel = 'B';

  61. switch channel

  62. case 'G'

  63. I1 = find(compHue > 0.2083 & compHue <0.2917);

  64. GcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;

  65. I2 = find(compHue >= 0.2917 & compHue <= 0.3750);

  66. GcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;

  67. I3 = find(compHue > 0.3750 & compHue <0.4583);

  68. GcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;

  69. compHSV = dstHSV;

  70. compHSV(:,:,2) = GcompS;

  71. dstImgG = hsv2rgb(compHSV);

  72. figure;imshow(dstImgG);

  73. case 'R'

  74. I1 = find(compHue > 0.875 & compHue <0.9583);

  75. RcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;

  76. I2 = find(compHue >= 0.9583 | compHue <= 0.0417);

  77. RcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;

  78. I3 = find(compHue > 0.0417 & compHue <0.125);

  79. RcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;

  80. compHSV = dstHSV;

  81. compHSV(:,:,2) = RcompS;

  82. dstImgR = hsv2rgb(compHSV);

  83. figure;imshow(dstImgR);

  84. case 'B'

  85. I1 = find(compHue > 0.5417 & compHue <0.625);

  86. BcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;

  87. I2 = find(compHue >= 0.625 & compHue <= 0.7083);

  88. BcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;

  89. I3 = find(compHue > 0.7083 & compHue <0.7917);

  90. BcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;

  91. compHSV = dstHSV;

  92. compHSV(:,:,2) = BcompS;

  93. dstImgB = hsv2rgb(compHSV);

  94. figure;imshow(dstImgB);

  95. end

  96. %进行R,G,B通道之间的互换

  97. convH = zeros(size(srcH,1),size(srcH,2)); %convert

  98. deltaHue = 240;

  99. switch deltaHue

  100. case 120

  101. disp('R -> G')

  102. convH = srcH + 1/3;

  103. convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;

  104. case 240

  105. disp('R -> B')

  106. convH = srcH + 2/3;

  107. convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;

  108. end

  109. convHSV = dstHSV;

  110. convHSV(:,:,1) = convH;

  111. convImg = hsv2rgb(convHSV);

  112. figure;imshow(convImg)

  113. pause();

  114. end

 

   添加OpenCV代码段:

 

 
  1. Mat srcHSV,sat,satAdj,dstMerge,dst; //sat - saturation饱和度分量

  2. Mat imageAwb = imread("m_ImageAwb.bmp");

  3. vector channels,channels1;

  4. double p1,p2,p3;

  5.  
  6. cvtColor(imageAwb,srcHSV,CV_BGR2HSV);

  7. split(srcHSV,channels);

  8. split(srcHSV,channels1);

  9. sat = channels.at(1);

  10. Scalar m = mean(sat);

  11.  
  12. if (m(0) <= 51.5)

  13. {p1 = -0.002714 , p2 = 0.9498, p3 = -0.5073; AfxMessageBox("High Color Enhancement!"); }//高

  14. else if (m(0) > 38.5 && m(0) <= 89.5)

  15. {p1 = -0.001578 , p2 = 0.6238, p3 = -0.1514;AfxMessageBox("Middle Color Enhancement!"); }//中

  16. else if (m(0) > 89.5 && m(0) <=127.5)

  17. {p1 = -0.0006512, p2 = 0.2639, p3 = -0.9246;AfxMessageBox("Low Color Enhancement!");}//低

  18. else

  19. {p1 = 0,p2 = 0,p3 =0;AfxMessageBox("No Color Enhancement!");}

  20.  
  21. satAdj = sat;

  22. for (int i = 0 ; i < sat.rows;i ++)

  23. {

  24. for (int j = 0;j < sat.cols;j ++)

  25. {

  26. uchar val = sat.at(i,j);

  27. satAdj.at(i,j) = (val + p1 * val * val + p2 * val + p3) ;

  28. }

  29. }

  30.  
  31. channels1.at(1) = satAdj;

  32. merge(channels1,dstMerge);

  33. cvtColor(dstMerge,dst,CV_HSV2BGR);

  34. imwrite("m_ImageCE.bmp",dst);


 

 

   最后给出算法效果图:

Group1.原图->增强后

 

Group2.原图->R通道增强->颜色通道改变R2B

Group3.原图->增强后->颜色通道改变R2B

 

四、直方图均衡(AHE)算法、局部色调映射(LTM):① 伽马压缩算法、② 基于直方图均衡的压缩算法、③ 基于Retinex的算法 ④ 基于梯度的压缩算法等

 直方图均衡(Histogram Equalization)是图像处理中一个十分基础的概念,具有调整图像灰度,增强对比度的作用。

   限制对比度自适应直方图均衡(Contrast Limited Adaptive Histogram Equalization,CLAHE),关于该算法的中文原理性描述可以参考网址:http://www.cnblogs.com/Imageshop/archive/2013/04/07/3006334.html 

   下面我按照自己的理解来介绍一下CLAHE算法:

   自适应直方图均衡(AHE)算法,对于图像中存在明显比其他区域亮或者暗的地方时,普通的直方图均衡算法就不能将该处的细节信息描述出来。AHE算法通过在当前处理像素周边的一个矩形区域内进行直方图均衡,来达到扩大局部对比度,显示平滑区域细节的作用。

   AHE算法的2个属性:1、AHE算法处理的局部领域,矩形领域小,局部对比度强,矩形领域大,局部对比度弱。2、如果矩形区域内的图像块信息比较平坦,灰度接近,其灰度直方图呈尖状,在直方图均衡的过程中就可能会出现过度放大噪声的情况。

   CLAHE,对比度受限的自适应直方图均衡算法就能够有效的限制噪声放大的情形。下图表示的就是局部矩形领域内的灰度直方图,由于对比度放大的程度与像素点的概率分布直方图的曲线斜度成比例,所以为了限制对比度,将大于一定阈值的部分平均分配到直方图的其他地方,如右图所示,这样的话,通过限制CDF(累积分布函数)的斜率来一定程度限制对比度。

   

   插值过程,得到了CDF函数,也就获得了对应的亮度变换函数,在计算变换函数的时候可以通过插值过程来降低计算量。其中红色块(图像角点处)的变换函数是完全按照定义获得的,绿色块(图像边缘)的变换函数是通过旁边两个图像块的变换函数线性插值得到的,蓝色部分图像块的变换函数则是通过双线性插值得到。

   

   目前,Matlab和OpenCV中都已经集成了CLAHE函数,在Matlab中,就是函数J = adapthisteq(I);

   在OpenCV中,按照如下代码段处理:

 

 
  1. Ptr clahe = createCLAHE();

  2. clahe ->apply(src,dst);

 

 

   局部色调映射(Local Tone Mapping)

   重建视觉外观是色调映射的终极目标。色调映射算法在降低高动态图像(HDR)范围的同时着力保护捕捉到的原始图像的外观。色调映射算子分两种策略,一种是全局的,另一种是局部的。

   全局映射算子

   每一个像素点将会根据它的全图特征和亮度信息进行映射,不管其空间位置几何。全局算子一个比较典型的例子就是色调曲线。全局色调映射在处理12位(12-bit)深度的图像的时候是完全OK的,当图像的动态范围特别高的时候,那就不行了。这是因为所有的像素点都采取同一种方式进行处理,根本就没有管它是在较亮区域还是较暗区域。这样的话,就是导致图像色调映射过后看起来很平坦,失去了其局部的细节信息。

   局部映射算子
   像素点所在的空间位置会被考虑,在进行尺度变换的时候,所以,具有相同亮度值的两个像素点会被映射成不同的值,因为它们的空间位置周边的亮度信息可能不一样。局部色调映射需要考虑到每个像素点周围的亮度信息,这样这会使得计算量和内存的使用会更大,但是会有更好的结果。如果处理得当,局部色调映射会很好的保护高亮和阴影部分的局部对比度和细节信息。

   目前的一些色调映射算法:

   1、伽马压缩算法

   2、基于直方图均衡的压缩算法

   3、基于Retinex的算法

   4、基于梯度的压缩算法,等等

   下面给出2组基于CLAHE的LTP算法效果图:(测试图像在网上找的)

   Matlab代码如下:

 

%% local tone mapping
clc,clear ,close all
% src = imread('m_ImageDemosaic.bmp');
src = imread('C:\Users\Administrator\Desktop\LTP5.png');
figure;imshow(src);
srcHDR = double(src) * 256;
hsv = rgb2hsv(srcHDR);
figure;imshow(uint16(srcHDR))
J = adapthisteq(uint16(hsv(:,:,3)));
hsv(:,:,3) = double(J);
dstHDR = hsv2rgb(hsv);
figure;imshow(uint16(dstHDR))
imwrite(uint16(dstHDR),'C:\Users\Administrator\Desktop\LTP5_1.png')


   由于获取不到源HDR,所以自己先将8-bit图像映射到16-bit之后再进行试验

 

   测试图像来源链接:http://www.vista123.com/vista/9226.html;http://www.nipic.com/show/7139458.html

 

 

 

 

 

 

 

 

你可能感兴趣的:(ISP基础与算法)