| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 人工智能 -> Gamma变换算法之Matlab&FPGA实现 -> 正文阅读 |
|
[人工智能]Gamma变换算法之Matlab&FPGA实现 |
Gamma映射原理
人眼的感光与光强并不是呈线性关系的,而是呈非线性关系(指数型关系,如下图左-曲线。在低照度下,人眼更容易分辨出亮度的变化,随着照度的增加,人眼不易分辨出亮度的变化。而图像传感器与输入光强呈线性关系(如下图左-直线)。从图中可见,当传感器感光在20%左右时,人眼感光响应达到了50%,人眼对低照度的变化更为敏感。从下图右侧可见,Reference Tone为人眼感光50%的亮度,而传感器在感光50%时则相对暗的多(见Select,近似中性灰)。这种将原始图像通过映射操作来满足人眼亮度响应的曲线,就是Gamma曲线,响应的变换就是Gamma变换。 ? ? 光有曲线的数据,虽已具象化,但没有感性的认识,着实不太好理解。我们举个例子,你在黑暗的夜晚,草丛有一只微弱的萤火虫,你会敏锐的发现,或是远方灯火阑珊,那更是灵光一现;但倘若在大白天,从早上8点到正午12点,虽阳光逐渐变得强烈,你却没有很直观的变化。所以可以理解人眼在低照度时候,对亮度的变化更为敏感,而在高亮时却不是很灵敏。 换个维度,假设在Gamma曲线上(以Gamma=2.2为例),我们计算亮度变化的幅度,即我们8bit图像亮度为0-255灰阶,映射到Gamma曲线后,则从灰阶1到2亮度变化幅度为37.04%,但从灰阶幅度254到255,亮度变化则仅只有0.18%,曲线如下图所示: ? 其中相关代码如下所示:
那么,不管从生活还是数据中分析,在高亮下人眼对光强不敏感,而在低照度下更敏感,因此足以见得Gamma映射的重要性。所以在ISP流程中,Gamma是很重要的一部分,我们为了适合人眼进行辨识,对图像传感器产生的图像进行Gamma变换,来提升图像的辨识度。如下图所示,为原始图像经传感器采集的未经Gamma变化的灰阶图(Linear Encoding),以及经过Gamma变换后的灰阶图(Gamma Encoding)。 ? 从图中可见,在未经过Gamma变换时,低灰度值区域在较大范围内表现为同一个值,造成信息的丢失;同时高灰度值区域又被表现为很多不同的值,造成存储的浪费。但经过Gamma变换后,低灰度值下有了更多的灰阶信息,而高灰度值下进行了一定程度的压缩,节省了图像的存储。
这事我不一定说的准确,仅凭个人卓见,两方面给大家阐述一下。 首先是当年的大脑袋的CRT显示器(00后不知道有没有见过),由于其显像管与电压并不是成线性关系。如下图所示,CRT亮度响应曲线。从曲线可知其暗区被压缩了(斜率小于45°),而亮区则被扩展了(斜率大于45°)。典型的比如输入40%亮度的红色+80%亮度的绿色,实际输出近似10%的红色+60%的绿色,显示严重不及预期。 为了弥补这一亮度响应的缺陷,我们需要一个反转的曲线,如上图中间曲线所示。经过中间反转曲线的抵消,最终达到预期的亮度,将会出现上图右边的曲线:近似45°斜率的直线,即便输入和亮度成正比关系,而这一亮度补偿的映射,就是Gamma,CRT的Gamma值据统计分析就在2.2左右。Gamma值没有标准,也没有对错,比如CRT有些文档说2.5,Windows系统默认Gamma=2.2,而Mac系统的Gamma又是1.8,不同的LCD屏幕响应曲线各有不同,最正确的方法则是通过灰阶自己找到最佳的Gamma值。 目前经典的Gamma值就是2.2,或许这是一种巧合,但这也是一个现实,从大量的人眼视觉特性中统计分析出一个经验值,我们人眼的亮度响应曲线,也刚好是2.2。 综上,CRT的亮度响应是一条Gamma曲线(往下弯),CRT的亮度补偿是一条反Gamma曲线(往上弯),而人眼的亮度响应也是一条反Gamma曲线,因此为了达到更好的亮度与对比度,符合人眼的视觉效果,需要额外的反Gamma曲线去对画面进行细微的明暗层次调整,控制整个画面对比度表现,再现立体美影像。 备注:第一次,我们叫作Gamma矫正,第二次个人认为只能称之为Gamma映射。那么既然是映射,跟对比度增强映射也就是一个道理了。
Gamma来龙去脉很复杂,但实现却很简单,只是简单的Mapping操作,是对输入图像灰度值进行的非线性操作,使输出图像灰度值与输入呈指数关系,公式如下: ?这个指数系数就是Gamma变换的系数。Gamma变换后,提升了暗部细节,压缩了亮部细节(Gamma<1);或者提升了亮部细节,压缩了暗部细节(Gamma>1)。如下图中,下方实曲线为CRT的Gamma曲线,而上方虚曲线则为矫正CRT亮度响应的曲线,校正后使得最终近似斜率为45°的线性响应(Gamma=1)。但事实上显示器已经自带了虚曲线的Gamma矫正曲线,其输入与输出在校正后已近似线性,但为了能够让图像变得更加接近人眼感受的非线性响应,提升图像显示的质量,我们仍然可以进一步Gamma 2.2的映射。 ? 上图为官方的图,其中最下方为CRT Gamma 2.2的曲线,而最上方则为反Gamma曲线。由于我们在PC侧处理的像素都是0-255,那么对公式进一步变型,扩展到0-255,计算如下: ??使用Matlab绘制的如上曲线,如下所示。我们将始终在0-255之间,进行线性响应的非线性拉伸,来符合人眼/设备的响应曲线。 ?
首先申明:这里只是演示Gamma映射的算法,但结果并没有对错,毕竟原图可能已经优化过,同时也可能因人而异。 前面已经用Matlab绘制过Gamma曲线,这里为了观察效果,我们同时绘制Gamma=2.2及Gamma=1/2.2的映射结果,以及前一篇中对比度增强的效果,来提高你对曲线映射图像处理的认知。如下所示为Matlab源代码:
? 从上图可知,仅个人视觉效果评判,图【2】的效果更好,虽整体相对图【1】偏暗,比如松鼠鼻子看不清了,但细节更清晰;图【3】严重过曝,效果不佳;图【4】稍微过曝,明暗对比度提升。 为了更好的对比图像映射的过程,绘制了Gamma=2.2;Gamma=1/2.2,以及指数对比度的曲线。可见对比度曲线结合了Gamma=2.2及1/2.2的曲线,同时拉伸了亮部和暗部;而Gamma=2.2或者1/2.2仅拉伸了暗部或者亮度。 当然这个过程没有对与错。 ? ?
沿用对比度增强Verilog生成的Matlab代码,如下所示:
? 由Matlab生成的Verilog代码,如下所示: ? ?
未完待续,等书出来吧 I am CrazyBingo! 本文为《基于Matlab与FPGA的图像处理教程》中的章节,在正式出版前,我将率先在公众号/博客中给大家分享出来,请大胆指正!!!
? ? |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/27 10:36:46- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |