欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

重印 ISP 算法简介

最编程 2024-04-08 07:20:36
...

come from : https://www.cnblogs.com/whw19818/archive/2016/08.html

ISP(Image Singal Process)算法广泛应用于安防监控,汽车电子等等一系列产品中。

ISP主要算法包括:3A---[AWB(自动白平衡),AE(自动曝光),AF(自动对焦)],CFA插值,暗角补偿,坏点检测,2D/3D去噪,锐化,VDE,Color Matrix,图片缩放,数字宽动态,伽马矫正等等一系列图像处理算法.

       所有这些算法的最终目的都是使图像看上去更清晰,更好,使人们看上去有一个更好的感受。那么学习ISP算法需要哪些知识呢?其实也就是一些最基本的图像处理方面的知识,如:图像色彩空间:RGB,YUV,LAB,XYZ,HSV空间等等。在研究算法的时候,只要多动脑多查资料,相信都会有一个好的收获。

自动白平衡(auto white balance )

自动白平衡:主要解决图像偏色的问题,如果图像偏色,我们就可以用自动白平衡算法给矫正过来。

有以下几个问题要考虑:

1,我们看到的图像是否存在偏色,如果不偏色就不需要矫正,只有偏色的图片才需要矫正。

        注:实际中,图像都存在偏色,只是情况不一样,有的看起来失真严重,有的看起来也还很自然。

2,对于偏色的情况我们采用什么方法来对图片进行矫正。

首先,检测偏色。这一算法,主要用到图像的一些空间变换的知识。RGB—XYZ-—Lab,对图像偏色的检测,主要在Lab空间进行。

其次,矫正。矫正最主要的就是对图像进行找白点,就是白色参考点的确认。这一过程主要用图像YCbCR空间。

如果图片不存在偏色,则对每个像素点必须满足:Cb=0,Cr=0;   但实际情况中,Cb和Cr的值是不可 能全部为零的。我们可以用一下判断条件:

 (1) Y>T1(T1事先预设),|Cb|<X,|Cr|<Y;

 (2)|Y-|cb|-|Cr||>T1

(3) 对图片进行分块,然后利用(1)或者(2)进行判断白点

 具体算法就不一一列出了,呵呵

 

ISP图像处理算法之一黑电平校正

       本文主要介绍ISP pipeline里边算法之一黑电平校正:

        众所周知,CMOS传感器采集的信息经过一系列转换,最后生成原始RAW格式数据,RAW数据每个像素点只有一种颜色信息,只是RGB的一个,但是由于sensor对绿色光的频率基本可以全部通过,故RAW data数据里边,有两个G一个R,一个B。我们要想得到RGB数据就必须利用已有的信息来得到缺失的信息,这个处理后面专门介绍。这里接着黑电平校正说。

        我们知道图像数据一般为0--255,但sensor在出厂的时候,厂家一般会设置图像数据输出范围如5-250等,反正最低电平不为零。因此我们就需要对图像数据范围进行调整,使其最小值为零,这就是黑电平校正。

         黑电平校正有两种方法:一种是直接在RAW data数据上减去一个值,可以RGB减的值一样,也可以不一样,目前大多数厂家如,安霸,海思等基本都是采用这一做法。一种是利用一次函数,这个比较麻烦,就不介绍了。

         PS:这个是ISP里面最简单做法,以后会详细介绍一些其他复杂的算法。

 

ISP图像处理算法之---Demosaic

目前市场上主流传感器为Coms传感器,sensor出来的的数据格式为bayer数据格式,这种格式,每个像素点只有三个颜色通道中的一个,如图1所示 :图1  bayer数据格式

Demosaic的目的就是有bayer数据恢复出完整的RGB数据。

方法:色差和色比,一般用色差的理论

常见算法:双线性,基于梯度,自适应,及其他一些方法,具体原理网上都能查的到,此处不一一介绍,最后贴几张自己做的一个Demosaic和常见算法的一个对比

 

     原图

双线性插值

基于梯度插值

自适应插值

基于差值的插值方法

   自己方法

 

ISP模块之RAW DATA去噪(一)

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

    RAW DATA,可以理解为:RAW图像就是CMOS或者CCD图像感应器将捕捉到的光源信号转化为数字信号的原始数据,是无损的,包含了物体原始的颜色信息等。RAW数据格式一般采用的是Bayer排列方式,通过滤波光片,产生彩色滤波阵列(CFA),鉴于人眼对绿色波段的色彩比较敏感,Bayer数据格式中包含了50%的绿色信息,以及各25%的红色和蓝色信息。

  Bayer排列格式有以下4种:

  1.| R | G |   2.| B | G |    3.| G | R |    4.| G | B |

     | G | B |      | G | R |       | B | G |       | R | G |

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

一、中值滤波CFA(Color Filter Array)Data去噪方法 

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

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

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

    对CFA DATA进行去噪时,需要将不同的颜色通道分开进行处理,这样是为了防止在平滑过程中将有用的颜色信息丢掉,比如说,由绿色信息包围的蓝色像素值与其相差很大时,此时就会被认为是噪声被处理掉,然而真实情况是,该区域的蓝色信息都是很大的。所以各通道单独处理的话是有利于保护颜色信息的。在我的处理过程中,是将原CFA DATA分成4块-R,G1,G2,B,分块去噪完成后再重新恢复到原来的位置,这样整个过程就完成了。

    下面给出参考的中值滤波和主程序的C++(MFC)代码:

主函数:

 

  1. void main()  
  2. {  
  3.   
  4.     /*******开始编写中值滤波去噪模块--2015.07.27***********/  
  5.     //针对R分量块进行去噪  
  6.     pNewDoc->m_RBlock  = new unsigned short [m_Height*m_Width/4];  
  7.     pNewDoc->m_G1Block = new unsigned short [m_Height*m_Width/4];  
  8.     pNewDoc->m_G2Block = new unsigned short [m_Height*m_Width/4];  
  9.     pNewDoc->m_BBlock  = new unsigned short [m_Height*m_Width/4];  
  10.   
  11.     unsigned short* smoothR  = new unsigned short[m_Height*m_Width/4];  
  12.     unsigned short* smoothG1 = new unsigned short[m_Height*m_Width/4];  
  13.     unsigned short* smoothG2 = new unsigned short[m_Height*m_Width/4];  
  14.     unsigned short* smoothB  = new unsigned short[m_Height*m_Width/4];  
  15.     for (int i = 0; i < m_Height/2 ;i ++ )  
  16.     {  
  17.         for(int j = 0; j < m_Width/2 ; j ++ )  
  18.         {  
  19.             pNewDoc->m_RBlock [i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + j*2];  
  20.             pNewDoc->m_G1Block[i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + j*2 + 1];  
  21.             pNewDoc->m_G2Block[i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + m_Width + j*2];  
  22.             pNewDoc->m_BBlock [i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + m_Width + j*2 + 1];  
  23.         }  
  24.     }  
  25.     medianFilter(pNewDoc->m_RBlock,smoothR,m_Width/2,m_Height/2);   //针对R分量块进行去噪  
  26.     medianFilter(pNewDoc->m_G1Block,smoothG1,m_Width/2,m_Height/2); //针对G1分量块进行去噪  
  27.     medianFilter(pNewDoc->m_G2Block,smoothG2,m_Width/2,m_Height/2); //针对G2分量块进行去噪  
  28.     medianFilter(pNewDoc->m_BBlock,smoothB,m_Width/2,m_Height/2);   //针对B分量块进行去噪  
  29.   
  30.     //反过来构造去噪去噪后的raw data  
  31.     for (int i = 0; i < m_Height/2 - 1;i ++ )  
  32.     {  
  33.         for(int j = 0; j < m_Width/2-1; j ++ )  
  34.         {  
  35.             pNewDoc->m_ImageNR[i*m_Width*2 + j*2] = smoothR[i*m_Width/2 + j];  
  36.             pNewDoc->m_ImageNR[i*m_Width*2 + j*2 + 1] = smoothG1[i*m_Width/2 + j];   
  37.             pNewDoc->m_ImageNR[i*m_Width*2 + m_Width + j*2] = smoothG2[i*m_Width/2 + j];  
  38.             pNewDoc->m_ImageNR[i*m_Width*2 + m_Width + j*2 + 1] = smoothB[i*m_Width/2 + j];  
  39.   
  40.         }  
  41.     }  
  42.     /***********中值滤波模块完成--2015.07.27********************/  
  43.     //SaveImageData(pNewDoc->m_ImageNR, m_Height ,m_Width,"E:\\m_ImageNR.bmp");  
  44.     SetDisplayRawImage( pNewDoc->m_ImageNR, m_Height ,m_Width, m_RawBitType,pNewDoc->m_Image);  
  45. }  
void main()
{
/*******开始编写中值滤波去噪模块--2015.07.27***********/
//针对R分量块进行去噪
pNewDoc-&gt;m_RBlock  = new unsigned short [m_Height*m_Width/4];
pNewDoc-&gt;m_G1Block = new unsigned short [m_Height*m_Width/4];
pNewDoc-&gt;m_G2Block = new unsigned short [m_Height*m_Width/4];
pNewDoc-&gt;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 &lt; m_Height/2 ;i ++ )
{
	for(int j = 0; j &lt; m_Width/2 ; j ++ )
	{
		pNewDoc-&gt;m_RBlock [i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + j*2];
		pNewDoc-&gt;m_G1Block[i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + j*2 + 1];
		pNewDoc-&gt;m_G2Block[i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + m_Width + j*2];
		pNewDoc-&gt;m_BBlock [i*m_Width/2 + j] = m_RawImage[i*m_Width*2 + m_Width + j*2 + 1];
	}
}
medianFilter(pNewDoc-&gt;m_RBlock,smoothR,m_Width/2,m_Height/2);   //针对R分量块进行去噪
medianFilter(pNewDoc-&gt;m_G1Block,smoothG1,m_Width/2,m_Height/2); //针对G1分量块进行去噪
medianFilter(pNewDoc-&gt;m_G2Block,smoothG2,m_Width/2,m_Height/2); //针对G2分量块进行去噪
medianFilter(pNewDoc-&gt;m_BBlock,smoothB,m_Width/2,m_Height/2);   //针对B分量块进行去噪

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

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

}

 

  1. void medianFilter (unsigned short* corrupted, unsigned short* smooth, int width, int height)    
  2. {    
  3.         
  4.     memcpy ( smooth, corrupted, width*height*sizeof(unsigned short) );    
  5.     for (int j=1;j<height-1;j++)    
  6.     {    
  7.         for (int i=1;i<width-1;i++)    
  8.         {    
  9.             int k = 0;    
  10.             unsigned short window[9];    
  11.             for (int jj = j - 1; jj < j + 2; ++jj)    
  12.                 for (int ii = i - 1; ii < i + 2; ++ii)    
  13.                     window[k++] = corrupted[jj * width + ii];    
  14.             //   Order elements (only half of them)    
  15.             for (int m = 0; m < 5; ++m)    
  16.             {    
  17.                 int min = m;    
  18.                 for (int n = m + 1; n < 9; ++n)    
  19.                     if (window[n] < window[min])    
  20.                         min = n;    
  21.                 //   Put found minimum element in its place    
  22.                 unsigned short temp = window[m];    
  23.                 window[m] = window[min];    
  24.                 window[min] = temp;    
  25.             }  
  26.             smooth[ j*width+i ] = window[4];    
  27.         }    
  28.     }    
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&lt;height-1;j++)  
{  
    for (int i=1;i&lt;width-1;i++)  
    {  
        int k = 0;  
        unsigned short window[9];  
        for (int jj = j - 1; jj &lt; j + 2; ++jj)  
            for (int ii = i - 1; ii &lt; i + 2; ++ii)  
                window[k++] = corrupted[jj * width + ii];  
        //   Order elements (only half of them)  
        for (int m = 0; m &lt; 5; ++m)  
        {  
            int min = m;  
            for (int n = m + 1; n &lt; 9; ++n)  
                if (window[n] &lt; window[min])  
                    min = n;  
            //   Put found minimum element in its place  
            unsigned short temp = window[m];  
            window[m] = window[min];  
            window[min] = temp;  
        }
		smooth[ j*width+i ] = window[4];  
    }  
}  

} <span style=“font-family: Arial, Helvetica, sans-serif;”> </span>

 

中值滤波函数是在网上找的代码,由于比较基础,就直接拿过来用了,侵删去噪前后效果图:

 

    下一篇文章,我将主要给大家展示一下BM3D算法RAW DATA去噪效果,谢谢。

 

 

ISP模块之RAW DATA去噪(二)--BM3D算法

在正式开始本篇文章之前,让我们一起回顾一下CFA图像去噪的一些基本思路与方法。接着我会详细地和大家分享自己学习理解的BM3D算法,操作过程,它的优缺点,最后会给出算法效果图供参考。

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

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

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

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

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

下面是BM3D算法的详细介绍:

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)明显优于中值滤波,去噪模块就此结束,下一篇开始给大家介绍两种色彩增强的算法。

BM3D网上有现成的Matlab代码,算法链接网址:http://www.cs.tut.fi/~foi/GCF-BM3D/

参考文献:

1).A case for denoising before demosaicking color fiter array data,Sung Hee Park etc.

2).A Framework for wavelet-based analysis and processing of color filter array images with applications to denoising and demosaicing,Hirakawa etc.Havard University.

3).Cross-color BM3D Filtering of Noise Raw Data,Aram Danielyan etc.

 

ISP模块之彩色图像增强--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.****.net/topics/390815673

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

                原图 

                                   

              ACE处理后

                                        原图

                                        ACE处理后

 

ISP模块之色彩增强算法--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进行拟合,得到曲线参数。

  1. % Color Enhancement  
  2. clc,clear,close all  
  3. src1 = imread('src.bmp');  
  4. src2 = imread('src_40.bmp');  
  5.   
  6. src1_hsv = rgb2hsv(src1);  
  7. src2_hsv = rgb2hsv(src2);  
  8.   
  9. h1 = src1_hsv(:,:,1);  
  10. s1 = src1_hsv(:,:,2);  
  11. v1 = src1_hsv(:,:,3);  
  12.   
  13. h2 = src2_hsv(:,:,1);  
  14. s2 = src2_hsv(:,:,2);  
  15. v2 = src2_hsv(:,:,3);  
  16. %   
  17. meanS1 = mean(s1(:));  
  18. varS1  = std2(s1);   
  19. %   
  20. meanS2 = mean(s2(:));  
  21. varS2  = std2(s2);   
  22. %   
  23. deltaS = s2 - s1;  
  24. deltaV = v2 - v1;  
  25.   
  26. %% test1 : 观测“原饱和度-饱和度调整增量”的关系 saturation and delta saturation  
  27. figure;  
  28. oriS = zeros(101,2);  
  29. s3 = s1;  
  30. j = 1;  
  31. for i = 0: 0.01 : 1  
  32.     oriS(j,1) = i + 0.01;  
  33.     oriS(j,2) =  mean(deltaS(find(s1 > i & s1< i + 0.01)));  
  34.     j = j + 1;  
  35. end  
  36. X  = oriS(:,1);  
  37. Y  = oriS(:,2);  
  38. XX = oriS(:,1) * 255;  
  39. YY = oriS(:,2) * 255;  
  40. plot(XX,YY)  
% 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  
%% Color Enhancement Module -- Authored by HuangDao,08/17/2015
% functions: input a image of type BMP or PNG, the program will decide to
% do the Color Enhancement choice for you.There are four types of Enhanced
% intensity - 20,40,60,80.The larger number stands for stronger
% enhancement.
% And we can also choose the simple color channel(eg.R,G,B) to do the
% enhancement.There are also four different types of enhanced intensity.
%
% parameters table
%  ------------------------------------------------------------------------
% | Enhanced  |     MATLAB params             |      OpenCV params         |
% | intensity |p1        p2        p3         | p1        p2        p3     |
% | 20        |-0.1661   0.2639    -0.003626  |-0.0006512 0.2639    -0.9246|
% | 40        |-0.4025   0.6238    -0.0005937 |0.001578   0.6238    -0.1514|
% | 60        |1.332     1.473     -0.01155   |-0.005222  1.473     -2.946 |
% | 80        |-4.813    3.459     -0.004568  |-0.01887   3.459     -1.165 |
%  ------------------------------------------------------------------------

clc; clear ;close all
% 载入文件夹
pathName = ‘.’;
fileType = ‘*.bmp’;
files = dir([pathName fileType]);
len = length(files);

for pic = 5%1:1:len
srcName = files(pic).name;
srcImg = imread(srcName);
srcHSV = rgb2hsv(srcImg);
srcH = srcHSV(:,:,1);
srcS = srcHSV(:,:,2);
srcV = srcHSV(:,:,3);
meanS = mean(srcS(????);
varS = std2(srcS);
%图像整体进行色彩增强处理
if (meanS >= 0.5)
p1 = 0;p2 = 0;p3 = 0;
else if (meanS >= 0.35 && meanS < 0.5)
p1 = -0.1661;p2 = 0.2639;p3 = -0.003626;
else if (meanS >=0.2 && meanS <0.35)
p1 = -0.4025;p2 = 0.6238;p3 = -0.0005937;
else
p1 = 1.332;p2 = 1.473;p3 = -0.01155;
end
end
end
dstS = srcS + p1*srcS.srcS + p2srcS + p3 ;
dstHSV = srcHSV;
dstHSV(:,:,2) = dstS;
dstImg = hsv2rgb(dstHSV);
figure;imshow(srcImg);
figure;imshow(dstImg);
%指定R,G,B通道进行色彩增强处理,红色范围([225-255]),绿色范围(75-[105-135]-165),蓝色范围([-15-15])
p11 = -0.4025;p21 = 0.6238;p31 = -0.0005937;%周边杂色调整系数,40
p12 = 1.332; p22 = 1.473; p32 = -0.01155; %纯色区域调整系数,60
compHue = srcH;
GcompS = dstS;
RcompS = dstS;
BcompS = dstS;
channel = ‘B’;
switch channel
case ‘G’
I1 = find(compHue > 0.2083 & compHue <0.2917);
GcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
I2 = find(compHue >= 0.2917 & compHue <= 0.3750);
GcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
I3 = find(compHue > 0.3750 & compHue <0.4583);
GcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
compHSV = dstHSV;
compHSV(:,:,2) = GcompS;
dstImgG = hsv2rgb(compHSV);
figure;imshow(dstImgG);
case ‘R’
I1 = find(compHue > 0.875 & compHue <0.9583);
RcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
I2 = find(compHue >= 0.9583 | compHue <= 0.0417);
RcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
I3 = find(compHue > 0.0417 & compHue <0.125);
RcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
compHSV = dstHSV;
compHSV(:,:,2) = RcompS;
dstImgR = hsv2rgb(compHSV);
figure;imshow(dstImgR);
case ‘B’
I1 = find(compHue > 0.5417 & compHue <0.625);
BcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
I2 = find(compHue >= 0.625 & compHue <= 0.7083);
BcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
I3 = find(compHue > 0.7083 & compHue <0.7917);
BcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
compHSV = dstHSV;
compHSV(:,:,2) = BcompS;
dstImgB = hsv2rgb(compHSV);
figure;imshow(dstImgB);
end
%进行R,G,B通道之间的互换
convH = zeros(size(srcH,1),size(srcH,2)); %convert
deltaHue = 240;
switch deltaHue
case 120
disp(‘R -> G’)
convH = srcH + 1/3;
convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;
case 240
disp(‘R -> B’)
convH = srcH + 2/3;
convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;
end
convHSV = dstHSV;
convHSV(:,:,1) = convH;
convImg = hsv2rgb(convHSV);
figure;imshow(convImg)
pause();
end

 

   添加OpenCV代码段:

  1. Mat srcHSV,sat,satAdj,dstMerge,dst;     //sat - saturation饱和度分量  
  2. Mat imageAwb = imread("m_ImageAwb.bmp");  
  3. vector<Mat> 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<uchar>(i,j);  
  27.         satAdj.at<uchar>(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);  
	Mat srcHSV,sat,satAdj,dstMerge,dst;     //sat - saturation饱和度分量
	Mat imageAwb = imread("m_ImageAwb.bmp");
	vector<Mat> channels,channels1;
	double p1,p2,p3;
cvtColor(imageAwb,srcHSV,CV_BGR2HSV);
split(srcHSV,channels);
split(srcHSV,channels1);
sat = channels.at(1);
Scalar m = mean(sat);

if (m(0) &lt;= 51.5)	                   
{p1 = -0.002714 , p2 = 0.9498, p3 = -0.5073;  AfxMessageBox("High Color Enhancement!"); }//高
else if (m(0) &gt; 38.5 &amp;&amp; m(0) &lt;= 89.5)  
{p1 = -0.001578  , p2 = 0.6238, p3 = -0.1514;AfxMessageBox("Middle Color Enhancement!"); }//中
else if (m(0) &gt; 89.5 &amp;&amp; m(0) &lt;=127.5)  
{p1 = -0.0006512, p2 = 0.2639, p3 = -0.9246;AfxMessageBox("Low Color Enhancement!");}//低
else                                   
{p1 = 0,p2 = 0,p3 =0;AfxMessageBox("No Color Enhancement!");}

satAdj = sat;
for (int i = 0 ; i &lt; sat.rows;i ++)
{
	for (int j = 0;j &lt; sat.cols;j ++)
	{
		uchar val = sat.at&lt;uchar&gt;(i,j);
		satAdj.at&lt;uchar&gt;(i,j) = (val + p1 * val * val + p2 * val + p3) ;
	}
}

channels1.at(1) = satAdj;
merge(channels1,dstMerge);
cvtColor(dstMerge,dst,CV_HSV2BGR);
imwrite("m_ImageCE.bmp",dst);</pre> 

 

   最后给出算法效果图:

Group1.原图->增强后

 

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

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

完!下篇讲Local Tone Mapping。

 

直方图均衡(HE)与局部色调映射(LTM) .

直方图均衡(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> clahe = createCLAHE();   
  2. clahe ->apply(src,dst);  
Ptr<CLAHE> clahe = createCLAHE(); 
clahe ->apply(src,dst);

   局部色调映射(Local Tone Mapping)

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

   全局映射算子

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

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

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

   1、伽马压缩算法

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

   3、基于Retinex的算法

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

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

   Matlab代码如下:

  1. %% local tone mapping  
  2. clc,clear ,close all  
  3. % src = imread('m_ImageDemosaic.bmp');  
  4. src = imread('C:\Users\Administrator\Desktop\LTP5.png');  
  5. figure;imshow(src);  
  6. srcHDR = double(src) * 256;  
  7. hsv = rgb2hsv(srcHDR);  
  8. figure;imshow(uint16(srcHDR))  
  9. J = adapthisteq(uint16(hsv(:,:,3)));  
  10. hsv(:,:,3) = double(J);  
  11. dstHDR = hsv2rgb(hsv);  
  12. figure;imshow(uint16(dstHDR))  
  13. imwrite(uint16(dstHDR),'C:\Users\Administrator\Desktop\LTP5_1.png')  
%% 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.htmlhttp://www.nipic.com/show/7139458.html

 

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

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

 

9695d0002311a41b6d211c852577848d334.jpg

高通8974 拍照显示流程,可以清晰的看出ISP在整个流程中的位置

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电平的平衡关系)使反射到镜头里的光线都呈现为消色。如果以偏红的色光来调整白平衡,那么该色光的影像就为消色,而其他色彩的景物就会偏蓝(补色关系)。

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

       白平衡是一个很抽象的概念,最通俗的理解就是让白色所成的像依然为白色,如果