IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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映射原理

  1. 什么是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映射函数
x = [0:1:255];
y1 = (255/255.^(1/2.2))*x.^(1/2.2);
y2 = zeros(1,256);
for i = 1:255
    if(x==0)
        y2(1)=0;
    else
        y2(i)=(y1(i+1)-y1(i))/y1(i);
    end
end
subplot(121),plot(x,y1,'Linewidth',2);grid on;  title('Gamma映射曲线');
subplot(122),plot(x,y2,'Linewidth',2);grid on;title('Gamma变化强度');

那么,不管从生活还是数据中分析,在高亮下人眼对光强不敏感,而在低照度下更敏感,因此足以见得Gamma映射的重要性。所以在ISP流程中,Gamma是很重要的一部分,我们为了适合人眼进行辨识,对图像传感器产生的图像进行Gamma变换,来提升图像的辨识度。如下图所示,为原始图像经传感器采集的未经Gamma变化的灰阶图(Linear Encoding),以及经过Gamma变换后的灰阶图(Gamma Encoding)。

?

从图中可见,在未经过Gamma变换时,低灰度值区域在较大范围内表现为同一个值,造成信息的丢失;同时高灰度值区域又被表现为很多不同的值,造成存储的浪费。但经过Gamma变换后,低灰度值下有了更多的灰阶信息,而高灰度值下进行了一定程度的压缩,节省了图像的存储。

  1. Gamma为啥是2.2

这事我不一定说的准确,仅凭个人卓见,两方面给大家阐述一下。

首先是当年的大脑袋的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映射。那么既然是映射,跟对比度增强映射也就是一个道理了。

    1. 如何进行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之间,进行线性响应的非线性拉伸,来符合人眼/设备的响应曲线。

?

  1. Gamma映射Matlab实现

首先申明:这里只是演示Gamma映射的算法,但结果并没有对错,毕竟原图可能已经优化过,同时也可能因人而异。

前面已经用Matlab绘制过Gamma曲线,这里为了观察效果,我们同时绘制Gamma=2.2及Gamma=1/2.2的映射结果,以及前一篇中对比度增强的效果,来提高你对曲线映射图像处理的认知。如下所示为Matlab源代码:

% -----------------------------------------------------------------------
%                                \\\|///
%                              \\  - -  //
%                               (  @ @  )
% +---------------------------oOOo-(_)-oOOo-----------------------------+
% CONFIDENTIAL IN CONFIDENCE
% This confidential and proprietary software may be only used as authorized
% by a licensing agreement from CrazyBingo (Thereturnofbingo).
% In the event of publication, the following notice is applicable:
% Copyright (C) 2013-20xx CrazyBingo Corporation
% The entire notice above must be reproduced on all authorized copies.
% Author                :       CrazyBingo
% Technology blogs      :       www.crazyfpga.com
% Email Address         :       crazyfpga@qq.com
% Filename              :       Image_Constrast.m
% Date                  :       2021-08-25
% Description           :       Image Constrast alg.
% Modification History  :
% Date          By          Version         Change Description
% =========================================================================
% 21/08/25      CrazyBingo  1.0             Original
% -------------------------------------------------------------------------
% |                                    Oooo                           |
% +-----------------------------oooO--(   )-------------------------------+
%                              (   )   ) /
%                               \ (   (_/
%                                \_)
% -----------------------------------------------------------------------
 
 
clear all;  
close all;
clc;
 
% -------------------------------------------------------------------------
% Read PC image to Matlab
IMG1 = imread('../images/scart.jpg');    % 读取jpg图像
IMG1 = rgb2gray(IMG1);
% IMG1 = imread('../images/gsls_test1.tif');    % 读取jpg图像
h = size(IMG1,1);         % 读取图像高度
w = size(IMG1,2);         % 读取图像宽度
subplot(221);imshow(IMG1);title('原图');
 
% -------------------------------------------------------------------------
IMG2 = zeros(h,w);
for i = 1:h
    for j = 1:w
        IMG2(i,j) = (255/255.^2.2)*double(IMG1(i,j)).^2.2;
    end
 
end
IMG2 = uint8(IMG2);
subplot(222);imshow(IMG2);title('Gamma=2.2映射');
 
% -------------------------------------------------------------------------
IMG3 = zeros(h,w);
for i = 1:h
    for j = 1:w
        IMG3(i,j) = (255/255.^(1/2.2))*double(IMG1(i,j)).^(1/2.2);
    end
 
end
IMG3 = uint8(IMG3);
subplot(223);imshow(IMG3);title('Gamma=1/2.2映射效果');
 
% -------------------------------------------------------------------------
THRESHOLD = 127;
E=4;
IMG4 = zeros(h,w);
for i = 1:h
    for j = 1:w
        IMG4(i,j) = (1./(1 + (THRESHOLD./double(IMG1(i,j))).^E)) * 255;
    end
 
end
IMG4 = uint8(IMG4);
subplot(224);imshow(IMG4);title('对比度增强效果');

% ----------------------------------------------
fid = fopen('..\..\SIM\4_Gamma_Mapping_sim\source_files\image_gray.txt','wt');
for row = 1 : h
    for col = 1 : w
        fprintf(fid,'%s ',lower(dec2hex(IMG1(row,col),2)));
    end
    fprintf(fid,'\n');
end
fclose(fid);

fid = fopen('image_gray_gamma.txt','wt');
for row = 1 : h
    for col = 1 : w
        fprintf(fid,'%s ',lower(dec2hex(IMG2(row,col),2)));
    end
    fprintf(fid,'\n');
end
fclose(fid);

?

从上图可知,仅个人视觉效果评判,图【2】的效果更好,虽整体相对图【1】偏暗,比如松鼠鼻子看不清了,但细节更清晰;图【3】严重过曝,效果不佳;图【4】稍微过曝,明暗对比度提升。

为了更好的对比图像映射的过程,绘制了Gamma=2.2;Gamma=1/2.2,以及指数对比度的曲线。可见对比度曲线结合了Gamma=2.2及1/2.2的曲线,同时拉伸了亮部和暗部;而Gamma=2.2或者1/2.2仅拉伸了暗部或者亮度。

当然这个过程没有对与错。

?

?

  1. Gamma映射FPGA实现
    1. Gamma映射LUT的生成

沿用对比度增强Verilog生成的Matlab代码,如下所示:

% -----------------------------------------------------------------------
clear all;  
close all;
clc;

% ----------------------------------------------------------------------
fp_gray = fopen('.\Curve_Gamma_2P2.v','w');
fprintf(fp_gray,'//Curve of Gamma = 2.2\n');
fprintf(fp_gray,'module Curve_Gamma_2P2\n');
fprintf(fp_gray,'(\n');
fprintf(fp_gray,'   input\t\t[7:0]\tPre_Data,\n');
fprintf(fp_gray,'   output\treg\t[7:0]\tPost_Data\n');
fprintf(fp_gray,');\n\n');
fprintf(fp_gray,'always@(*)\n');
fprintf(fp_gray,'begin\n');
fprintf(fp_gray,'\tcase(Pre_Data)\n');
Gray_ARRAY = zeros(1,256);
for i = 1 : 256
    Gray_ARRAY(1,i) = (255/255.^2.2)*(i-1).^2.2;
    Gray_ARRAY(1,i) = uint8(Gray_ARRAY(1,i));
    fprintf(fp_gray,'\t8''h%s : Post_Data = 8''h%s; \n',dec2hex(i-1,2), dec2hex(Gray_ARRAY(1,i),2));
end
fprintf(fp_gray,'\tendcase\n');
fprintf(fp_gray,'end\n');
fprintf(fp_gray,'\nendmodule\n');   
fclose(fp_gray);

% -----------------------------------------------------------------------
% 打印变形后的映射数组Gray_ARRAY
reshape(Gray_ARRAY,16,16)

?

由Matlab生成的Verilog代码,如下所示:

?

?

  1. RTL仿真结果及实测

未完待续,等书出来吧


I am CrazyBingo!

本文为《基于Matlab与FPGA的图像处理教程》中的章节,在正式出版前,我将率先在公众号/博客中给大家分享出来,请大胆指正!!!

?

?

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-10-16 19:38:58  更:2021-10-16 19:40:40 
 
开发: 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-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码