G-channel 实现低光图像增强
G-channel
之前研究低光图像增强时,看到一篇博客,里面介绍了一种方法,没有说明出处,也没有说明方法的名字,这里暂时叫做 G-channel 算法。
博客地址:低照度图像增强(附步骤及源码)_低照度图像增强算法_grafx的博客-CSDN博客
算法过程
博客里面简单说明了算法的执行过程,这里重复如下:
- 将绿色通道反色后作为系数值,分别与各个通道相乘,得到新图层;
- 将新图层与原图做一次滤色混合,f(a,b)=1-(1-a)*(1-b);
为了了解算法原理,经过查找,找到了几篇博客:
- 基于photoshop滤色混合模式的图片亮度改变_悍然的博客-CSDN博客
- 正片叠底(Multiply)和滤色(Screen)是两种基本的混合模式_滤色和正片叠底_e财富800的博客-CSDN博客
- Photoshop图层混合模式的计算公式_pizi0475的博客-CSDN博客
从这几篇博客里,可以将算法过程归纳为Photoshop的2个处理步骤:
- Multiply正片叠底:C=(A×B)/255,A为基色,B为混合色,会使得图像C整体亮度更暗
- Screen滤色:C=255-(A反相×B反相)/255,与上面相反,会使得图像C整体亮度更亮
算法实现
博客中给出了opencv的实现代码,下面使用matlab进行了仿真,代码如下所示:
close all;clear;clc;
src = imread('8.bmp');
im = double(src);
r = im(:,:,1);
g = im(:,:,2);
b = im(:,:,3);
g_alpha = 255 - g;
r1 = r .* g_alpha / 255;
g1 = g .* g_alpha / 255;
b1 = b .* g_alpha / 255;
r = 255 - (255 - r) .* (255 - r1) / 255;
g = 255 - (255 - g) .* (255 - g1) / 255;
b = 255 - (255 - b) .* (255 - b1) / 255;
dst = cat(3, r, g, b);
dst = uint8(round(dst));
imshow([src, dst])
由于找不到博客里测试图像的原图,这里换了另外一张测试图像,结果如下,这里执行2次算法,可以看到结果与博客里面的结果还是很相似的,说明仿真没有问题。

为了方便分析,这里对代码做了调整(原始代码,数据范围为[0,255],调整后的代码,数据范围归一化到[0,1]),如下所示,与原始结果是一致:
close all;clear;clc;
src = imread('8.bmp');
im = double(src)/255;
r = im(:,:,1);
g = im(:,:,2);
b = im(:,:,3);
g_alpha = 1 - g;
r1 = r .* g_alpha;
g1 = g .* g_alpha;
b1 = b .* g_alpha;
r = 1 - (1 - r) .* (1 - r1);
g = 1 - (1 - g) .* (1 - g1);
b = 1 - (1 - b) .* (1 - b1);
dst = cat(3, r, g, b);
dst = uint8(round(dst*255));
imshow([src, dst])
原理分析
下面就个人理解来对算法原理做个简单的分析。
步骤一:Multiply正片叠底
正片叠底公式为:C=(A×B)/255,数据范围都为[0,255],这里全部都归一化到[0,1],则公式变为:C=A×B。
任何一个数乘以一个小于1的数以后,都会变小,即C<A(C=A×B),因而图像整体会变暗。
这步里面的B为G通道取反,以G通道进行说明,处理后为:g1=g×(1-g)。原始图像中本来很亮的像素值gh,取反之后变为1-gh,变得很小,处理后会乘以一个很小的小数,使得很亮的像素值gh降低的很多;而原本很暗的像素值gl,取反之后1-gl,变得很大,处理后会乘以一个很大的小数,使得很暗的像素值gl降低的很少。最终的处理结果是图像中亮的像素变很暗,而暗的像素稍微变暗,因而图像会整体变暗。
我们换一个方式来看,公式是一个二次函数,开口朝下,对称轴为0.5,超过0.5部分,单调递减,即原始亮度越亮,处理后亮度越暗,如下所示为其函数关系图:

下面是算法实际仿真结果,如下所示:
close all;clear;clc;
src = imread('8.bmp');
im = double(src)/255;
r = im(:,:,1);
g = im(:,:,2);
b = im(:,:,3);
g_alpha = 1 - g;
r1 = r .* g_alpha;
g1 = g .* g_alpha;
b1 = b .* g_alpha;
dst = cat(3, r1, g1, b1);
dst = uint8(round(dst*255));
imshow([src, dst])

可以看到,图像整体亮度变暗,且图中白色的杯盘变得很暗,与上面的分析很吻合。
步骤二:Screen滤色
同样,归一化到[0,1]后,Screen滤色公式为:C=1-(1-A)×(1-B)。如果用来做图像增强,则需要A和B有很强的相关性;如果是为了实现某种效果,则B跟这种效果密切相关(比如让某个区域更亮)。为了简化说明,这里让B=A,同样以G通道进行说明:g2=1-(1-g)×(1-g),这里先单独看Screen滤色。从第一步的分析可知,(1-g)可以使图像中亮的像素值降低的更多,然后取反,这样会使得图像中亮的像素增加的更多,暗的像素值增加的很少,图像整体亮度提升。
我们再来看看g2这个函数,它是一个二次函数,开口朝下,对称轴为1,[0,1]单调递增,如下所示:

close all;clear;clc;
src = imread('8.bmp');
im = double(src)/255;
r = im(:,:,1);
g = im(:,:,2);
b = im(:,:,3);
g_alpha = 1 - g;
r2 = 1 - (1- r) .* g_alpha;
g2 = 1 - (1- g) .* g_alpha;
b2 = 1 - (1- b) .* g_alpha;
dst = cat(3, r2, g2, b2);
dst = uint8(round(dst*255));
figure, imshow([src, dst])

可以看到,图像整体亮度变亮,且图中白色的杯盘变得更亮,与上面的分析很吻合。
这样就会出现一个问题,图像中原本比较亮的像素值处理后会更亮,容易出现饱和,为了避免出现这种问题,就需要结合步骤一里面的Multiply正片叠底,先对亮的像素值进行抑制再来提升亮度,从而可以减小出现饱和的风险。
下面我们结合步骤一Multiply正片叠底一起看,对G通道,g3=1-(1-g)×(1-g1)=1-(1-g)×(1-g×(1-g)),它是一个3次函数,如下所示:

可以看到,最终的曲线g3,相比于Screen滤色g2,在亮的像素增强上进行了抑制。其最终增强效果如文章开头所示。
G-channel 实现低光图像增强的更多相关文章
- python skimage图像处理(一)
python skimage图像处理(一) This blog is from: https://www.jianshu.com/p/f2e88197e81d 基于python脚本语言开发的数字图片处 ...
- Learning to See in the Dark论文阅读笔记
这是一篇图像增强的论文,作者创建了一个数据集合,和以往的问题不同,作者的创建的see in the dark(SID)数据集合是在极其暗的光照下拍摄的,这个点可以作为一个很大的contribution ...
- matlab进阶:常用功能的实现,常用函数的说明
常用功能的实现 获取当前脚本所在目录 current_script_dir = fileparts(mfilename('fullpath')); % 结尾不带'/' 常用函数的说明 bsxfun m ...
- 【树莓派】【转】将树莓派Raspberry Pi设置为无线路由器(WiFi热点AP,RTL8188CUS芯片)
下文为转载,文章转自:http://wangye.org/blog/archives/845/,仅供本次学习实践参考. 最近又开始折腾起Raspberry Pi来了,因为某处上网需要锐捷拨号,于是我就 ...
- 关于 RTL8723BS 同时开启 STA/AP 模式
最近接到一个调试 wifi 驱动的任务,使用的是 rtl8723bs 芯片组.要求是让无线设备工作在 station 模式的时候同时开启一个 ap 热点.简单来讲就是连接其他 wifi 的同时发出一个 ...
- Ubuntu 配置AP总结
1.这个是使用别人写的一个GUI来配置,:http://hi.baidu.com/lexiangtaotao/item/5d4e87f22db132c70cd1c86f 2.使用hostapd配置:h ...
- Libfilth(一个滤波器C库)使用
Libfilth使用说明 winshton 2009年2月 (*本文大部分翻译自libfilth,还有一部分是个人使用实践 *时间水平均有限,翻译的不完整,尤其第二章可以忽略) 版本历史修改记录 版本 ...
- python数字图像处理(5):图像的绘制
实际上前面我们就已经用到了图像的绘制,如: io.imshow(img) 这一行代码的实质是利用matplotlib包对图片进行绘制,绘制成功后,返回一个matplotlib类型的数据.因此,我们也可 ...
- wpa_supplicant.conf
转自:http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=blob_plain;f=wpa_supplicant/wpa_supplicant.conf ### ...
- Hostapd
Hostapd 一.基本概念 hostapd is an application used to setup your wireless interface as an access-point (m ...
随机推荐
- MySQL的varchar存储原理:InnoDB记录存储结构
摘要:varchar(M) 能存多少个字符,为什么提示最大16383?innodb怎么知道varchar真正有多长?记录为NULL,innodb如何处理?某个列数据占用的字节数非常多怎么办?影响每行实 ...
- django4 前后端分离和不分离的优缺点
Django4可以采用前后端分离或者不分离两种方式来开发Web应用,它们各有优缺点. 前后端分离的优点: 前后端职责分离:前端负责视图展示.用户交互,后端负责数据处理.逻辑处理,分工明确,开发效率高. ...
- mysql报错Unknown collation: utf8mb4_0900_ai_ci
mysql报错Unknown collation: utf8mb4_0900_ai_ci 解决方案: 将文件内的所有 utf8mb4_0900_ai_ci 换成 utf8_general_ci utf ...
- 合合信息亮相CCIG2023:多位大咖共话智能文档未来,文档图像内容安全还面临哪些技术难题?
近日,中国图象图形大会(CCIG 2023)(简称"大会")在苏州圆满落幕.本届大会以"图象图形·向未来"为主题,由中国科学技术协会指导,中国图象图形学学会 ...
- springboot~国际化Locale正确的姿势
Java中的Locale.getDefault()获取的是操作系统的默认区域设置,如果需要获取客户端浏览器的区域设置,可以从HTTP头中获取"Accept-Language"的值来 ...
- 手机app抓包个人简述
1.将在网上下载的手机软件放入apps 2.启动 3.查看结果 urls里是网址
- vue项目连接socket.io跨域及400异常处理
最近看人家用socket.io聊天,于是自己也想打个服务试试,不试不知道,一试吓一跳,原来这里吗还有这么多坑,下面就是所遇的坑,记录一哈,但愿可以帮助到遇到同样的坑的小伙伴 文章目录 一.服务端配置 ...
- 代码随想录算法训练营Day30 回溯算法| 332.重新安排行程 51. N皇后 37. 解数独 总结
代码随想录算法训练营 332.重新安排行程 题目链接:332.重新安排行程 给定一个机票的字符串二维数组 [from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划 ...
- 如何同步更新 Github 上 Fork 的项目?
Github Fork 过程概述 在 Github 上有很多优秀的开源项目,相信每一位热衷于技术的朋友都会在 Github 上 Fork 一些感兴趣的项目,然后在本地修改并提交.本文以 Galaxy ...
- bugku_EasyMath
bugku_EasyMath 题目描述 简单的数学题 from Crypto.Util.number import getPrime, bytes_to_long from secret import ...