2017-08-25 11:00:07 wukery 阅读数 2022
  • 海思平台ISP与图像的IQ调试-第9季

    本课程讲解sensor直接采集的图像都有各种不理想性,因此在编码前都会经过一个软件方式处理,这个处理就叫ISP,图像的IQ调试就是研究这些处理算法和实现的。常见的IQ调试技术如:线性纠正、噪声去除、黑电平校正、坏点去除、颜色插补、Gamma 校正、RGB2YUV 转换、主动白平衡处理、主动曝光控制、AE评估等。 随着通信行业发展,网速越来越快,网络也从文本时代发展越过语音时代到了现在视频时代,“优酷、爱奇艺”、“微视频”、“直播”等的出现也是视频逐步成为主流媒体的证据和表现。航拍、视频监控、刷脸过关检测、汽车ADAS系统等应用也是视频在主流行业中的应用,因此视频的采集、编解码、传输、识别等技术变得越来越有价值,涌现出了“海康威视”、“大华股份”、“深圳英飞拓”等一批明星企业,名扬海内外,动辄市值几百亿。同时在芯片级,国产华为海思HI35xx系列视频编解码方案也逐步取代进口芯片(如TI、安霸)成为主流方案。 视频行业技术含量高、难度大、学习周期长、发展变化快而资料少,因此行业比较缺人、工资较高。如海康威视,普通高校硕士研究生应届进入年薪普遍高于15-20万,在嵌入式linux领域也算高工资技术方向了。 本项目是朱老师及其团队推出的一个嵌入式linux领域重量级企业级实战项目,选用华为海思HI3518E方案,结合OV9712/AR0130 Sensor实现图像采集和H.264编码压缩,并通过ethernet和WIFI,以socket实时流和RTSP等方式,实现720P/960P高清视频传输。本项目共分11季,从海思SDK开发环境搭建,到sample程序讲解、SDK中API函数解析,到H.264编解码、RTSP流媒体传输、MP4文件打包,到图像IQ调试、图像识别等视频领域高阶内容,可以说从零基础入手,对图像采集、编解码、网络传输、图像存储和识别做了全方位的详细讲解和代码分析,是目前市面上**一套系统讲解图像和视频技术的视频课程。

    81 人正在学习 去看看 朱有鹏

图像处理之gamma校正

1 gamma校正背景

  在电视和图形监视器中,显像管发生的电子束及其生成的图像亮度并不是随显像管的输入电压线性变化,电子流与输入电压相比是按照指数曲线变化的,输入电压的指数要大于电子束的指数。这说明暗区的信号要比实际情况更暗,而亮区要比实际情况更高。所以,要重现摄像机拍摄的画面,电视和监视器必须进行伽玛补偿。这种伽玛校正也可以由摄像机完成。我们对整个电视系统进行伽玛补偿的目的,是使摄像机根据入射光亮度与显像管的亮度对称而产生的输出信号,所以应对图像信号引入一个相反的非线性失真,即与电视系统的伽玛曲线对应的摄像机伽玛曲线,它的值应为1/γ,我们称为摄像机的伽玛值。电视系统的伽玛值约为2.2,所以电视系统的摄像机非线性补偿伽玛值为0.45彩色显像管的伽玛值为2.8,它的图像信号校正指数应为1/2.8=0.35,但由于显像管内外杂散光的影响,重现图像的对比度和饱和度均有所降低,所以彩色摄像机的伽玛值仍多采用0.45。在实际应用中,我们可以根据实际情况在一定范围内调整伽玛值,以获得最佳效果。

2 gamma校正定义

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

以传统CRTCathode Ray Tube)屏幕的特性而言,该曲线通常是一个乘幂函数,Y=(X+e)γ,其中,Y为亮度、X为输出电压、e为补偿系数、乘幂值(γ)为伽玛值,改变乘幂 值(γ)的大小,就能改变CRT的伽玛曲线。典型的Gamma值是0.45,它会使CRT的影像亮度呈现线性。使用CRT的电视机等显示器屏幕,由于对于 输入信号的发光灰度,不是线性函数,而是指数函数,因此必需校正。

3 gamma校正原理

  假设图像中有一个像素,值是 200 ,那么对这个像素进行校正必须执行如下步骤: 

  1. 归一化 :将像素值转换为  0 ~ 1  之间的实数。 算法如下 : ( i + 0. 5)/256  这里包含 个除法和 个加法操作。对于像素  A  而言  , 其对应的归一化值为  0. 783203 。 

  2. 预补偿 :根据公式  , 求出像素归一化后的 数据以  1 /gamma  为指数的对应值。这一步包含一个 求指数运算。若  gamma  值为  2. 2 ,    1 /gamma    0. 454545 , 对归一化后的  A  值进行预补偿的结果就   0. 783203 ^0. 454545 = 0. 894872 。 

  3. 反归一化 :将经过预补偿的实数值反变换为  0    255  之间的整数值。具体算法为 : f*256 - 0. 5  此步骤包含一个乘法和一个减法运算。续前   ,   A  的预补偿结果  0. 894872  代入上式  , 得到  A  预补偿后对应的像素值为  228 , 这个  228  就是最后送 入显示器的数据。  

  如上所述如果直接按公式编程的话,假设图像的分辨率为 800*600 ,对它进行 gamma 校正,需要执行 48 万个浮点数乘法、除法和指数运算。效率太低,根本达不到实时的效果。 

  针对上述情况,提出了一种快速算法,如果能够确知图像的像素取值范围  , 例如  , 0 ~ 255 之间的整数  , 则图像中任何一个像素值只能   0    255    256  个整数中的某一个   gamma  已知的情况下  ,0 ~ 255  之间的任一整数  , 经过“归一 化、预补偿、反归一化”操作后 所对应的结果是唯一的  , 并且也落在  0 ~ 255  这个范围内。

  如前例  , 已知  gamma  值为  2. 2 , 像素  A  的原始值是  200 , 就可求得   gamma  校正后  A  对应的预补偿值为  228 。基于上述原理  , 我们只需为  0 ~ 255  之间的每个整数执行一次预补偿操作  , 将其对应的预补偿值存入一个预先建立的  gamma  校正查找表 (LUT:Look Up Table) , 就可以使用该表对任何像素值在  0 ~ 255   间的图像进行  gamma  校正。 

4 gamma校正实现

 

复制代码
 1 #include <math.h>
 2 
 3 typedef unsigned char UNIT8; //用 8 位无符号数表示 0~255 之间的整数
 4 UNIT8 g_GammaLUT[256];//全局数组:包含256个元素的gamma校正查找表
 5 //Buildtable()函数对0-255执行如下操作:
 6 //①归一化、预补偿、反归一化;
 7 //②将结果存入 gamma 查找表。
 8 //从公式得fPrecompensation=1/gamma
 9 void BuildTable(float fPrecompensation )
10 {
11   int i;
12   float f;
13   for( i=0;i<256;i++)
14   {
15     f=(i+0.5F)/256;//归一化
16     f=(float)pow(f,fPrecompensation);
17     g_GammaLUT[i]=(UNIT8)(f*256-0.5F);//反归一化
18   }
19 }
20 
21 void GammaCorrectiom(UNIT8 src[],int iWidth,int iHeight,float fGamma,UNIT8 Dst[])
22 {
23   int iCols,iRows;
24   BuildTable(1/fGamma);//gamma校正查找表初始化
25   //对图像的每个像素进行查找表矫正
26   for(iRows=0;iRows<iHeight;iRows++)
27   {
28     for(iCols=0;iCols<iWidth;iCols++)
29     {
30       Dst[iRows*iWidth+iCols]=g_GammaLUT[src[iRows*iWidth+iCols]];
31     }
32   }
33 }
2016-10-31 23:47:57 u013347241 阅读数 4540
  • 海思平台ISP与图像的IQ调试-第9季

    本课程讲解sensor直接采集的图像都有各种不理想性,因此在编码前都会经过一个软件方式处理,这个处理就叫ISP,图像的IQ调试就是研究这些处理算法和实现的。常见的IQ调试技术如:线性纠正、噪声去除、黑电平校正、坏点去除、颜色插补、Gamma 校正、RGB2YUV 转换、主动白平衡处理、主动曝光控制、AE评估等。 随着通信行业发展,网速越来越快,网络也从文本时代发展越过语音时代到了现在视频时代,“优酷、爱奇艺”、“微视频”、“直播”等的出现也是视频逐步成为主流媒体的证据和表现。航拍、视频监控、刷脸过关检测、汽车ADAS系统等应用也是视频在主流行业中的应用,因此视频的采集、编解码、传输、识别等技术变得越来越有价值,涌现出了“海康威视”、“大华股份”、“深圳英飞拓”等一批明星企业,名扬海内外,动辄市值几百亿。同时在芯片级,国产华为海思HI35xx系列视频编解码方案也逐步取代进口芯片(如TI、安霸)成为主流方案。 视频行业技术含量高、难度大、学习周期长、发展变化快而资料少,因此行业比较缺人、工资较高。如海康威视,普通高校硕士研究生应届进入年薪普遍高于15-20万,在嵌入式linux领域也算高工资技术方向了。 本项目是朱老师及其团队推出的一个嵌入式linux领域重量级企业级实战项目,选用华为海思HI3518E方案,结合OV9712/AR0130 Sensor实现图像采集和H.264编码压缩,并通过ethernet和WIFI,以socket实时流和RTSP等方式,实现720P/960P高清视频传输。本项目共分11季,从海思SDK开发环境搭建,到sample程序讲解、SDK中API函数解析,到H.264编解码、RTSP流媒体传输、MP4文件打包,到图像IQ调试、图像识别等视频领域高阶内容,可以说从零基础入手,对图像采集、编解码、网络传输、图像存储和识别做了全方位的详细讲解和代码分析,是目前市面上**一套系统讲解图像和视频技术的视频课程。

    81 人正在学习 去看看 朱有鹏

今天为大家带来的是一篇关于图像自动Gamma校正的文章,主要是利用了html5的canvas做图像处理。一般处理Gamma校正都是通过用户手动调节Gamma值来完成的,自动Gamma校正则是通过一系列的计算得出理想的Gamma值后再做处理。网上关于JavaScript做Gamma校正的文章很少,而自动Gamma校正的文章可以说是几乎找不到,这篇文章里图像自动Gamma校正的相关内容,是我通过查阅有限的资料实现的,所以还是挺有成就感的。今天分享给大家,如果文中有不正确的地方,欢迎大家指出来;有更好的想法也欢迎大家提出来,我们一起探讨学习。感兴趣的话可到文末的链接下载源码,程序的效果如下:


忽略gif图片画质过差的问题,你会发现自动Gamma校正后,图片的整体亮度提高了,石头的细节部分也能看到了。因为这里选用的图片原本是比较暗的,所以最后图片变亮了,如果选用的图片过亮,经过自动Gamma校正后,图片则会变暗。


1. 关于Gamma(伽马)
1.1 什么是Gamma

Gamma(伽马)是图像处理和视频制作中常用的技术用语。它定义了一个像素的数值和它的实际亮度之间的关系。从数学的角度来说,Gamma是用来改变某些输入值的“幂指数”。可以用如下简短的公式进行说明。


下面分别以2,1和0.5的Gamma值为例来简单说明这个公式


根据函数图,Gamma与输入、输出值间的关系就一目了然了,简单总结如下:
①当Gamma值比1大时,在输入值相同的情况下,输出值减小;
②当Gamma值为1时,输出值不变;
③当Gamma值比1小时,在输入值相同的情况下,输出值增加。

1.2 什么是Gamma校正
我是以前使用Photoshop时,才第一次接触到伽马校正(Gamma Correction),但当时并不知道Gamma校正的含义,现在通过一系列调查,才对它有了一个清晰的认识。简而言之,Gamma校正是对动态范围内亮度的非线性存储/还原算法,即输入值进行的非线性操作,使输出值与输入值呈指数关系;从效果上来说Gamma校正调整图像的整体亮度,没有校正的图像看起来可能会存在过亮或太暗的情况,所以想要图像显示效果更完美,Gamma校正就显得很重要了。

使用Photoshop做Gamma校正时,如果设置的Gamma比1大,输出值会增加,即图片会变亮;而如果设置的Gamma值比1小时,输出值会减小,即图片会变暗。似乎不符合我们上一节针对公式所做的总结,刚好是相反的,这是因为PhotoShop是以Gamma的倒数作为输入值的幂,来计算输出值,如下所示:


我们后面的实现也是基于这个公式。

1.3 为什么需要Gamma校正
主要的原因有两个方面:

① 人类对于外界刺激变化程度的感受,不是线性的,是指数形式的,如下图所示:


也就是亮度相同的几盏灯,人类对于1盏灯→2盏灯产生的亮度变化感受,与2盏灯→4盏灯的变化感受是相同的。

而且人类对于较暗的细节更加敏感,光越亮我们对于亮度的变化就不是那么敏感了。所以通过Gamma校正,可以尽可能的保留暗的部分的细节,以满足人眼对暗部敏感的需求。

② 图片文件的色阶很有限,24位色图片每个通道只有2^8个色阶,总共只能显示2^24种颜色;而且亮度级别过于庞大,如果按照线性方案进行存储,那么存储/传输的代价就会变得很昂贵。


2. 基本运用

调整亮度,以及灰度图像中的Gamma校正,使用上一节介绍的指数函数把每个像素的RGB值进行变换。具体执行下列转换公式(假定像素值的取值范围为0到255):


使用之前提到的输入值的倒数幂,来完成Gamma校正。


3. 如何实现Gamma校正
利用 canvas = document.createElement('canvas'); 创建出canvas 元素;
再通过 canvas.getContext('2d')方法得到CanvasRenderingContext2D 对象,这个对象实现了画布绘制所使用的大多数方法;
然后调用 CanvasRenderingContext2D 对象的drawImage() 方法将图片绘制到canvas 上;
之后使用 CanvasRenderingContext2D 对象的getImageData() 方法得到ImageData 对象,该对象拷贝了画布指定矩形的像素数据,即该对象中的每个像素,都保存着 RGBA 值,也就是红、绿、蓝以及 alpha 通道,这些数据(color/alpha信息)以数组形式存在,并存储于 ImageData对象的data 属性中;
对每个像素的RGB值进行Gamma校正,调用的是我们自己实现的resetPixelColor() 方法;
最后,调用 CanvasRenderingContext2D 对象的putImageData()方法将图像数据拷贝回画布上,这时 canvas 上的数据就是经过Gamma校正后的了,如果要得到图片数据,再通过调用canvas.toDataURL('image/png') 方法就可以得到Base64的图片数据。

下面把Gamma校正的代码贴出来:

function adjustImageGamma(img) {
	image = img;
	canvas = document.createElement('canvas');
	canvas.id = img.id;
	canvas.className = img.className;
	//canvas.width = img.naturalWidth;
	canvas.width = img.width;
	//canvas.height = img.naturalHeight;
	canvas.height = img.height;
	
	ctx = canvas.getContext('2d');
	//ctx.drawImage(img, 0, 0);
	ctx.drawImage(img, 0, 0, img.width, img.height);
	
	var image_parentNode = img.parentNode;
	image_parentNode.replaceChild(canvas, img);
		
	//imageData = ctx.getImageData(0, 0, img.naturalWidth, img.naturalHeight);
	imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
	
	var gammaVal = getGammaVal();
	gammaCorrection = 1 / gammaVal;
	
	setTimeout(function() {
		//for ( y = 0; y < image.naturalHeight; y++) {
		for ( y = 0; y < canvas.height; y++) {
			//for ( x = 0; x < image.naturalWidth; x++) {
			for ( x = 0; x < canvas.width; x++) {
				var index = parseInt(x + canvas.width * y) * 4;
				resetPixelColor(index);
			}
		}
		ctx.putImageData(imageData, 0, 0);
		//var dataURL = canvas.toDataURL('image/png');
	}, 0);
}

function resetPixelColor(index) {
	imageData.data[index + 0] = Math.pow(
		(imageData.data[index + 0] / 255), gammaCorrection) * 255;
	imageData.data[index + 1] = Math.pow(
		(imageData.data[index + 1] / 255), gammaCorrection) * 255;
	imageData.data[index + 2] = Math.pow(
		(imageData.data[index + 2] / 255), gammaCorrection) * 255;
}

4. 如何实现自动Gamma校正

上一节的方法中调用过 getGammaVal() 方法来计算出gamma值,这节就具体介绍下这个值的计算过程:
将图片的像素数据转变为非RGB的数据来计算均值,我们这里是将其转变为灰度数据。之所以要转变成非RGB的的色彩模式,是因为如果使用RGB的数据来计算均值,可能会造成色彩平衡偏移。
将计算出来的均值带入 gammaVal = log(mean/255)/log(midrange) 这个公式中,就可以得到Gamma值了。
总的来说,计算Gamma值的过程并不复杂,但之前在调查这部分内容花费了我挺多时间的,因为网上的资料实在是太少了。好了,接下来就把代码贴出来:

function getGammaVal() {
	var pixData = imageData.data;
	var grayNum = pixData.length / 4;
	var totalGrayVal = 0;
	for (var i = 0; i < pixData.length; i += 4) {
		/* RGB to Luma: 
		 * http://stackoverflow.com/questions/37159358/save-canvas-in-grayscale */
		//var grayscale = pix[i] * 0.2126 + pix[i+1] * 0.7152 + pix[i+2] * 0.0722;
		var grayscale = (pixData[i] + pixData[i+1] + pixData[i+2]) / 3;
		totalGrayVal = totalGrayVal + grayscale;
	}
	var mean = totalGrayVal / grayNum;
	var gammaVal = Math.log10(mean/255) / Math.log10(0.5);
	return gammaVal;
}

需要注意的问题:

之前用火狐浏览器运行程序没报错,但是在谷歌的Chrome浏览器运行程序的时候,报了一个错 auto_gamma.js:31 Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.这是为了阻止欺骗,浏览器会追踪 imageData。当你把一个跟canvas的域不同的图片放到canvas上,这个canvas就成为 “tainted”(被污染的,脏的),浏览器就不让你操作该canvas 的任何像素。这对于阻止多种类型的XSS/CSRF攻击(两种典型的跨站攻击)是非常有用的。

解决方案:

https://github.com/mrdoob/three.js/wiki/How-to-run-things-locally我参考的这个链接里的内容,将程序运行于Server上,使图片和canvas处于同一个域,因为刚好安装了node.js的环境,所以我就直接 npm install http-server,然后再启动 http-server 加载html就可以了。


程序源代码:

基于H5/JS实现图像自动Gamma校正

2014-06-06 20:14:47 riskychengallesgut 阅读数 1046
  • 海思平台ISP与图像的IQ调试-第9季

    本课程讲解sensor直接采集的图像都有各种不理想性,因此在编码前都会经过一个软件方式处理,这个处理就叫ISP,图像的IQ调试就是研究这些处理算法和实现的。常见的IQ调试技术如:线性纠正、噪声去除、黑电平校正、坏点去除、颜色插补、Gamma 校正、RGB2YUV 转换、主动白平衡处理、主动曝光控制、AE评估等。 随着通信行业发展,网速越来越快,网络也从文本时代发展越过语音时代到了现在视频时代,“优酷、爱奇艺”、“微视频”、“直播”等的出现也是视频逐步成为主流媒体的证据和表现。航拍、视频监控、刷脸过关检测、汽车ADAS系统等应用也是视频在主流行业中的应用,因此视频的采集、编解码、传输、识别等技术变得越来越有价值,涌现出了“海康威视”、“大华股份”、“深圳英飞拓”等一批明星企业,名扬海内外,动辄市值几百亿。同时在芯片级,国产华为海思HI35xx系列视频编解码方案也逐步取代进口芯片(如TI、安霸)成为主流方案。 视频行业技术含量高、难度大、学习周期长、发展变化快而资料少,因此行业比较缺人、工资较高。如海康威视,普通高校硕士研究生应届进入年薪普遍高于15-20万,在嵌入式linux领域也算高工资技术方向了。 本项目是朱老师及其团队推出的一个嵌入式linux领域重量级企业级实战项目,选用华为海思HI3518E方案,结合OV9712/AR0130 Sensor实现图像采集和H.264编码压缩,并通过ethernet和WIFI,以socket实时流和RTSP等方式,实现720P/960P高清视频传输。本项目共分11季,从海思SDK开发环境搭建,到sample程序讲解、SDK中API函数解析,到H.264编解码、RTSP流媒体传输、MP4文件打包,到图像IQ调试、图像识别等视频领域高阶内容,可以说从零基础入手,对图像采集、编解码、网络传输、图像存储和识别做了全方位的详细讲解和代码分析,是目前市面上**一套系统讲解图像和视频技术的视频课程。

    81 人正在学习 去看看 朱有鹏

总是会遇到Gamma校正的字眼,但是真的要说明究竟什么是Gamma校正,却很难说清楚,这便是这篇博客的由来。

为了说清楚,从解决疑问的方式入手:

1.什么是Gamma校正?(what)

2.为什么要进行Gamma校正?(why)

3.怎样进行Gamma校正?(how)


1.什么是Gamma校正?


Gamma源于早期的CRT显示器的响应曲线,也就是输出亮度和输入电压的非线性关系,如图所示: 



图1 亮度和输入电压的非线性关系图


由图可以看出,亮度和输入电压的关系更加近似于指数函数 (output = input ^ gamma )的关系。事实确实如此,CRT显示器厂商都默认将gamma值设为2.5,也就是如上的曲线。这里的指数,也就是我们所讨论的gamma。


2.为什么要进行Gamma校正?


我们已经知道输出和输入的非线性关系为指数函数 output = input ^ gamma,考虑指数函数的性质:


图2 指数函数性质

由图2可以看出,蓝色曲线对应指数gamma <  1,红色曲线对应指数gamma > 1,考虑一副图像,纵轴代表图像的亮度值,横轴代表自变量区间,当gamma > 1 时,随着gamma的变大,高光区对应的自变量区间逐渐变小,而低光区对应的自变量区间逐渐变大;相反,当gamma < 1 时,随着gamma的变小,高光区对应的自变量区间逐渐变大,而低光区对应的自变量区间逐渐变小。概括起来就是:gamma矫正的值大于1时,图像的高光部分被压缩而暗调部分被扩展,当gamma矫正的值小于1时,图像的高光部分被扩展而暗调部分被压缩。

至此,我们知道,通过调节gamma值,我们可以针对性地控制高光区或者低光区的显示细节(表现为:gamma > 1时,低光区被扩展高光区被压缩。表现为“越来越灰暗”,gamma < 1 是,低光区压缩而高光区扩展,表现为“越来越明亮”)。所以,我们可以根据图像的具体情况,选择合适的gamma值对图像进行校正,提升图像的显示细节。


3.怎么样进行Gamma校正?

根据Gamma校正公式 output = input ^ gamma,用MatLab做三组实验,分别对应着

(1)gamma = 0.4;    (2)gamma = 1.0 ;    (3) gamma = 1.8;


代码:

%Gamma校正
clear all;
img = imread('lena.jpg');%读入图像
img = rgb2gray(img);%转成灰度图,即将[0,255]转成[0,1]
imgGamma_0_4 = imadjust(img,[],[],0.4);%此处gamma = 0.4
figure,imshow(imgGamma_0_4),title('gamma = 0.4');
imgGamma_1_0 = imadjust(img,[],[],1.0);%此处gamma = 1.0
figure,imshow(imgGamma_1_0),title('gamma = 1.0');
imgGamma_1_8 = imadjust(img,[],[],1.8);%此处gamma = 1.8
figure,imshow(imgGamma_1_8),title('gamma = 1.8');


实验结果:

 


                 gamma = 0.4                                     gamma = 1.0                                     gamma = 1.8                                  


这里引用一下http://www.cnblogs.com/zhz3996/archive/2010/01/26/1657090.html的例子:

当遇到如下所示的图例:


图3  原始图像


对于这种图像,衣服的颜色属于高光区,难以看清纹理,就是因为高光区被压缩,如果想要看清衣服的纹理(不要邪恶。。。),那么自然想到扩展高光区,根据前面所讲的,那就是将gamma值调小,从而将高光区进行扩展,可以得到如下结果: 


图4 Gamma校正后的结果

总结:

通过这样的处理,明显看到衣服的纹理更加清晰。所以Gamma校正就是这样操作的,根据具体情况选择合适的gamma值。

参考:

1.http://www.cnblogs.com/zhz3996/archive/2010/01/26/1657090.html(写得很好很详细)

2.http://blog.csdn.net/love_xunmeng/article/details/8274400

3.http://www2.xitek.com/info/showarticle.php?id=2521



2017-09-13 22:28:06 sinat_28296297 阅读数 5653
  • 海思平台ISP与图像的IQ调试-第9季

    本课程讲解sensor直接采集的图像都有各种不理想性,因此在编码前都会经过一个软件方式处理,这个处理就叫ISP,图像的IQ调试就是研究这些处理算法和实现的。常见的IQ调试技术如:线性纠正、噪声去除、黑电平校正、坏点去除、颜色插补、Gamma 校正、RGB2YUV 转换、主动白平衡处理、主动曝光控制、AE评估等。 随着通信行业发展,网速越来越快,网络也从文本时代发展越过语音时代到了现在视频时代,“优酷、爱奇艺”、“微视频”、“直播”等的出现也是视频逐步成为主流媒体的证据和表现。航拍、视频监控、刷脸过关检测、汽车ADAS系统等应用也是视频在主流行业中的应用,因此视频的采集、编解码、传输、识别等技术变得越来越有价值,涌现出了“海康威视”、“大华股份”、“深圳英飞拓”等一批明星企业,名扬海内外,动辄市值几百亿。同时在芯片级,国产华为海思HI35xx系列视频编解码方案也逐步取代进口芯片(如TI、安霸)成为主流方案。 视频行业技术含量高、难度大、学习周期长、发展变化快而资料少,因此行业比较缺人、工资较高。如海康威视,普通高校硕士研究生应届进入年薪普遍高于15-20万,在嵌入式linux领域也算高工资技术方向了。 本项目是朱老师及其团队推出的一个嵌入式linux领域重量级企业级实战项目,选用华为海思HI3518E方案,结合OV9712/AR0130 Sensor实现图像采集和H.264编码压缩,并通过ethernet和WIFI,以socket实时流和RTSP等方式,实现720P/960P高清视频传输。本项目共分11季,从海思SDK开发环境搭建,到sample程序讲解、SDK中API函数解析,到H.264编解码、RTSP流媒体传输、MP4文件打包,到图像IQ调试、图像识别等视频领域高阶内容,可以说从零基础入手,对图像采集、编解码、网络传输、图像存储和识别做了全方位的详细讲解和代码分析,是目前市面上**一套系统讲解图像和视频技术的视频课程。

    81 人正在学习 去看看 朱有鹏
本文主要通过OpenCV实现一些基础的图像处理过程,包括直方图均衡化、拉普拉斯算子图像增强、Gamma校正过程。
图像的对比度:灰度的动态范围来衡量。
一、直方图均衡化
直方图均衡化是通过调整图像的灰阶分布,使得在0~255灰阶上的分布更加均衡,提高了图像的对比度,达到改善图像主观视觉效果的目的。对比度较低的图像适合使用直方图均衡化方法来增强图像细节。

实质上是对图像进行非线性拉伸,重新分配图像象元值,使一定灰度范围内象元值的数量大致相等。这样,原来直方图中间的峰顶部分对比度得到增强,而两侧的谷底部分对比度降低,输出图像的直方图是一个较平的分段直方图:如果输出数据分段值较小的话,会产生粗略分类的视觉效果。

直方图是表示数字图像中每一灰度出现频率的统计关系。

直方图能给出图像灰度范围、每个灰度的频度和灰度的分布、整幅图像的平均明暗和对比度等概貌性描述。

灰度直方图是灰度级的函数, 反映的是图像中具有该灰度级像素的个数,其横坐标是灰度级r, 纵坐标是该灰度级出现的频率( 即像素的个数) pr( r) , 

整个坐标系描述的是图像灰度级的分布情况,由此可以看出图像的灰度分布特性, 

即若大部分像素集中在低灰度区域, 图像呈现暗的特性; 若像素集中在高灰度区域, 图像呈现亮的特性。

图1所示就是直方图均衡化, 即将随机分布的图像直方图修改成均匀分布的直方图。

基本思想是对原始图像的像素灰度做某种映射变换, 使变换后图像灰度的概率密度呈均匀分布。

这就意味着图像灰度的动态范围得到了增加, 提高了图像的对比度。

clip_image001

图1 直方图均衡化

彩色lena图像的直方图均衡化实现:

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace cv;

int main(int argc, const char * argv[])
{
    Mat image = imread("/Users/shandiangou/Downloads/lena.png");
    Mat gray;
    if(image.empty())
    {
        std::cout <<"图片打开失败"<<std::endl;
        return -1;
    }
    imshow("lena原图",image);
    waitKey();
    
    cvtColor(image, gray, CV_RGB2GRAY);
    int bins = 256;
    int hist_size[] = {bins};
    float range[] = {0,256};
    const float * ranges[] ={range};
    MatND hist;
    int channels[] = {0};
    
    calcHist(&gray, 1, channels, Mat(), hist, 1, hist_size, ranges, true, false);
    double max_val;
    minMaxLoc(hist, 0,&max_val, 0,0);
    int scale = 2;
    int hist_height =256;
    Mat hist_img = Mat::zeros(hist_height, bins*scale, CV_8UC3);
    for(int i=1;i<bins;i++)
    {
        float bin_val = hist.at<float>(i);
        int intensity = cvRound(bin_val*hist_height/max_val);
        rectangle(hist_img, Point(i*scale, hist_height-1), Point((i+1)*scale-1, hist_height-intensity), CV_RGB(255,255,255));
    }
    imshow("原图灰度直方图",hist_img);
    waitKey();
        
    Mat gray1, imageRGB[3];
    split(image, imageRGB);
    for (int i =0;i<3;i++)
    {equalizeHist(imageRGB[i],imageRGB[i]);
    }
    merge(imageRGB, 3, image);
    imshow("直方图均衡化后lena",image);
    waitKey();
    
    cvtColor(image, gray1, CV_RGB2GRAY);
    calcHist(&gray1, 1, channels, Mat(), hist, 1, hist_size, ranges, true, false);
    minMaxLoc(hist, 0,&max_val, 0,0);
    for(int i=1;i<bins;i++)
    {
        float bin_val = hist.at<float>(i);
        int intensity = cvRound(bin_val*hist_height/max_val);
        rectangle(hist_img, Point(i*scale, hist_height-1), Point((i+1)*scale-1, hist_height-intensity), CV_RGB(255,255,255));
    }
    imshow("均衡后灰度直方图",hist_img);
    waitKey();
    
    return 0;
}

结果图分别是原图、原图的灰度直方图、直方图均衡化后图、直方图均衡化后图的灰度直方图;可以清楚的看到直方图均衡的效果。



二、基于拉普拉斯算子的图像增强;

使用中心为5的8邻域拉普拉斯算子与图像卷积可以达到锐化增强图像的目的,拉普拉斯算子如下图所示:
      
  

拉普拉斯算子可以增强局部的图像对比度:
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace cv;

int main(int argc, char *argv[])
{
    Mat image = imread("/Users/shandiangou/Downloads/lena.png");
    if (image.empty())
    {
        std::cout << "打开图片失败,请检查" << std::endl;
        return -1;
    }
    imshow("原图像", image);
    waitKey();
    Mat imageEnhance;
    Mat kernel = (Mat_<float>(3, 3) << 0, -1, 0, 0, 5, 0, 0, -1, 0);
    filter2D(image, imageEnhance, CV_8UC3, kernel);
    imshow("拉普拉斯算子图像增强效果", imageEnhance);
    waitKey();
    return 0;
}




三、Gamma校正

伽马变换主要用于图像的校正,将灰度过高或者灰度过低的图片进行修正,增强对比度。变换公式就是对原图像上每一个像素值做乘积运算:



伽马变换对图像的修正作用其实就是通过增强低灰度或高灰度的细节实现的,从伽马曲线可以直观理解:



γ值以1为分界,值越小,对图像低灰度部分的扩展作用就越强,值越大,对图像高灰度部分的扩展作用就越强,通过不同的γ值,就可以达到增强低灰度或高灰度部分细节的作用。

伽马变换对于图像对比度偏低,并且整体亮度值偏高(对于于相机过曝)情况下的图像增强效果明显,此时gamma值>1。

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>

using namespace cv;
using namespace std;

// Normalizes a given image into a value range between 0 and 255.
Mat norm_0_255(const Mat& src) {
    // Create and return normalized image:
    Mat dst;
    switch(src.channels()) {
        case 1:
            cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
            break;
        case 3:
            cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
            break;
        default:
            src.copyTo(dst);
            break;
    }
    return dst;
}

int main(int argc, const char *argv[]) {
    // Get filename to the source image:
    // Load image & get skin proportions:
    Mat image = imread("/Users/shandiangou/Downloads/guobao.jpeg");
    // Convert to floating point:
    Mat X;
    image.convertTo(X, CV_32FC1);
    //image.convertTo(X, CV_32F);
    // Start preprocessing:
    Mat I;
    float gamma = 3;
    pow(X, gamma, I);
    
    
    // Draw it on screen:
    imshow("Original Image", image);
    waitKey();
    imshow("Gamma correction image", norm_0_255(I));
    // Show the images:
    waitKey();
    // Success!
    return 0;  
}

特地找了张过曝图片 进行处理,增强该图的对比度。


2018-11-15 15:50:35 a8039974 阅读数 1838
  • 海思平台ISP与图像的IQ调试-第9季

    本课程讲解sensor直接采集的图像都有各种不理想性,因此在编码前都会经过一个软件方式处理,这个处理就叫ISP,图像的IQ调试就是研究这些处理算法和实现的。常见的IQ调试技术如:线性纠正、噪声去除、黑电平校正、坏点去除、颜色插补、Gamma 校正、RGB2YUV 转换、主动白平衡处理、主动曝光控制、AE评估等。 随着通信行业发展,网速越来越快,网络也从文本时代发展越过语音时代到了现在视频时代,“优酷、爱奇艺”、“微视频”、“直播”等的出现也是视频逐步成为主流媒体的证据和表现。航拍、视频监控、刷脸过关检测、汽车ADAS系统等应用也是视频在主流行业中的应用,因此视频的采集、编解码、传输、识别等技术变得越来越有价值,涌现出了“海康威视”、“大华股份”、“深圳英飞拓”等一批明星企业,名扬海内外,动辄市值几百亿。同时在芯片级,国产华为海思HI35xx系列视频编解码方案也逐步取代进口芯片(如TI、安霸)成为主流方案。 视频行业技术含量高、难度大、学习周期长、发展变化快而资料少,因此行业比较缺人、工资较高。如海康威视,普通高校硕士研究生应届进入年薪普遍高于15-20万,在嵌入式linux领域也算高工资技术方向了。 本项目是朱老师及其团队推出的一个嵌入式linux领域重量级企业级实战项目,选用华为海思HI3518E方案,结合OV9712/AR0130 Sensor实现图像采集和H.264编码压缩,并通过ethernet和WIFI,以socket实时流和RTSP等方式,实现720P/960P高清视频传输。本项目共分11季,从海思SDK开发环境搭建,到sample程序讲解、SDK中API函数解析,到H.264编解码、RTSP流媒体传输、MP4文件打包,到图像IQ调试、图像识别等视频领域高阶内容,可以说从零基础入手,对图像采集、编解码、网络传输、图像存储和识别做了全方位的详细讲解和代码分析,是目前市面上**一套系统讲解图像和视频技术的视频课程。

    81 人正在学习 去看看 朱有鹏

什么是Gamma校正?
Gamma校正是对输入图像灰度值进行的非线性操作,使输出图像灰度值与输入图像灰度值呈指数关系。

上面中的指数γ即为Gamma.
经过Gamma校正后的输入和输出图像灰度值关系如下图所示:横坐标是输入灰度值,纵坐标是输出灰度值,蓝色曲线是gamma值小于1时的输入输出关系,红色曲线是gamma值大于1时的输入输出关系。可以观察到,当gamma值小于1时(蓝色曲线),图像的整体亮度值得到提升,同时低灰度处的对比度增加,高灰度处的对比度降低,更利于分辩低灰度值时的图像细节;当gamma值大于1时(红色曲线),图像的整体亮度值得到减小,同时低灰度处的对比度降低,高灰度处的对比度增加,更利于分辩高灰度值时的图像细节。

​​
为什么要进行Gamma校正?
人眼对外界光源的感光值与输入光强不是呈线性关系的,而是呈指数型关系的。在低照度下,人眼更容易分辨出亮度的变化,随着照度的增加,人眼不易分辨出亮度的变化。而摄像机感光与输入光强呈线性关系。OpenCV环境下对图像进行Gamma校正的源代码如下:

图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",并关注!
源码中用到的图像下载链接:http://pan.baidu.com/s/1miIGyqW 密码:bz9r

//opencv版本:OpenCV3.0
//VS版本:VS2013
//Author:qxsf321.net
 
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>    
#include <opencv2/imgproc/types_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>
 
#include <iostream>
 
using namespace cv;
using namespace std;
 
void MyGammaCorrection(Mat& src, Mat& dst, float fGamma)  
{  
 
    // build look up table  
    unsigned char lut[256];  
    for( int i = 0; i < 256; i++ )  
    {  
        lut[i] = saturate_cast<uchar>(pow((float)(i/255.0), fGamma) * 255.0f);  
    }  
 
    dst = src.clone();  
    const int channels = dst.channels();  
    switch(channels)  
    {  
        case 1:   //灰度图的情况
            {  
 
                MatIterator_<uchar> it, end;  
                for( it = dst.begin<uchar>(), end = dst.end<uchar>(); it != end; it++ )  
                    //*it = pow((float)(((*it))/255.0), fGamma) * 255.0;  
                    *it = lut[(*it)];  
 
                break;  
            }  
        case 3:  //彩色图的情况
            {  
 
                MatIterator_<Vec3b> it, end;  
                for( it = dst.begin<Vec3b>(), end = dst.end<Vec3b>(); it != end; it++ )  
                {  
                    //(*it)[0] = pow((float)(((*it)[0])/255.0), fGamma) * 255.0;  
                    //(*it)[1] = pow((float)(((*it)[1])/255.0), fGamma) * 255.0;  
                    //(*it)[2] = pow((float)(((*it)[2])/255.0), fGamma) * 255.0;  
                    (*it)[0] = lut[((*it)[0])];  
                    (*it)[1] = lut[((*it)[1])];  
                    (*it)[2] = lut[((*it)[2])];  
                }  
 
                break;  
 
            }  
    }  
}  
 
int main()
{
        Mat image = imread("gamma_pending.jpg");
        if (image.empty())
        {
                cout << "Error: Could not load image" << endl;
                return 0;
        }
 
        Mat dst;
        float fGamma=1/2.2;
        MyGammaCorrection(image, dst, fGamma);
 
        imshow("Source Image", image);
        imshow("Dst", dst);
 
        waitKey();
 
        return 0;
}
--------------------- 
作者:清溪算法 
来源:CSDN 
原文:https://blog.csdn.net/lehuoziyuan/article/details/84067207 
版权声明:本文为博主原创文章,转载请附上博文链接!

运行结果截图如下:


从运行结果中我们可以看出:
最左边的图为原图,中图为gamma = 1/2.2时的校正结果,原图中左半侧的灰度值较高,右半侧的灰度值较低,经过gamma=1/2.2校正后(中图),左侧的对比度降低(见胡须),右侧在对比度提高(明显可以看清面容),同时图像在的整体灰度值提高。
最右边的图为gamma = 2.2在校正结果,校正后,左侧的对比度提高(见胡须),右侧在对比度降低(面容更不清楚了),同时图像在的整体灰度值降低。

值得一提的是:人眼是按照gamma<1的曲线对自己看到的图像进行校正的。
--------------------- 
作者:清溪算法 
来源:CSDN 
原文:https://blog.csdn.net/lehuoziyuan/article/details/84067207 
版权声明:本文为博主原创文章,转载请附上博文链接!

没有更多推荐了,返回首页