G-channel

之前研究低光图像增强时,看到一篇博客,里面介绍了一种方法,没有说明出处,也没有说明方法的名字,这里暂时叫做 G-channel 算法。

博客地址:低照度图像增强(附步骤及源码)_低照度图像增强算法_grafx的博客-CSDN博客

算法过程

博客里面简单说明了算法的执行过程,这里重复如下:

  1. 将绿色通道反色后作为系数值,分别与各个通道相乘,得到新图层;
  2. 将新图层与原图做一次滤色混合,f(a,b)=1-(1-a)*(1-b);

为了了解算法原理,经过查找,找到了几篇博客:

从这几篇博客里,可以将算法过程归纳为Photoshop的2个处理步骤:

  1. Multiply正片叠底:C=(A×B)/255,A为基色,B为混合色,会使得图像C整体亮度更暗
  2. 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 实现低光图像增强的更多相关文章

  1. python skimage图像处理(一)

    python skimage图像处理(一) This blog is from: https://www.jianshu.com/p/f2e88197e81d 基于python脚本语言开发的数字图片处 ...

  2. Learning to See in the Dark论文阅读笔记

    这是一篇图像增强的论文,作者创建了一个数据集合,和以往的问题不同,作者的创建的see in the dark(SID)数据集合是在极其暗的光照下拍摄的,这个点可以作为一个很大的contribution ...

  3. matlab进阶:常用功能的实现,常用函数的说明

    常用功能的实现 获取当前脚本所在目录 current_script_dir = fileparts(mfilename('fullpath')); % 结尾不带'/' 常用函数的说明 bsxfun m ...

  4. 【树莓派】【转】将树莓派Raspberry Pi设置为无线路由器(WiFi热点AP,RTL8188CUS芯片)

    下文为转载,文章转自:http://wangye.org/blog/archives/845/,仅供本次学习实践参考. 最近又开始折腾起Raspberry Pi来了,因为某处上网需要锐捷拨号,于是我就 ...

  5. 关于 RTL8723BS 同时开启 STA/AP 模式

    最近接到一个调试 wifi 驱动的任务,使用的是 rtl8723bs 芯片组.要求是让无线设备工作在 station 模式的时候同时开启一个 ap 热点.简单来讲就是连接其他 wifi 的同时发出一个 ...

  6. Ubuntu 配置AP总结

    1.这个是使用别人写的一个GUI来配置,:http://hi.baidu.com/lexiangtaotao/item/5d4e87f22db132c70cd1c86f 2.使用hostapd配置:h ...

  7. Libfilth(一个滤波器C库)使用

    Libfilth使用说明 winshton 2009年2月 (*本文大部分翻译自libfilth,还有一部分是个人使用实践 *时间水平均有限,翻译的不完整,尤其第二章可以忽略) 版本历史修改记录 版本 ...

  8. python数字图像处理(5):图像的绘制

    实际上前面我们就已经用到了图像的绘制,如: io.imshow(img) 这一行代码的实质是利用matplotlib包对图片进行绘制,绘制成功后,返回一个matplotlib类型的数据.因此,我们也可 ...

  9. wpa_supplicant.conf

    转自:http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=blob_plain;f=wpa_supplicant/wpa_supplicant.conf ### ...

  10. Hostapd

    Hostapd 一.基本概念 hostapd is an application used to setup your wireless interface as an access-point (m ...

随机推荐

  1. Prism Sample 21-PassingParameters

    这个例子是说明导航中传递参数,类似Asp.net中实现. 例子的模板,是例16中使用regionContext实现过的.在例16中, <Grid x:Name="LayoutRoot& ...

  2. Vue3 +element-plus+ wangEditor 富文本编辑器+前端七牛云上传

    我用的vue3,element-plus ,没用ts 搭建wangEditor 参考 地址 https://www.cnblogs.com/xbxxf/p/16791084.html 七牛云安装参考地 ...

  3. QUIC在京东直播的应用与实践

    作者:京东零售 周凯 一. 前言与背景 国内的互联网直播技术从2005年前后兴起,彼时最具代表性的直播产品是由PPLive创始人姚欣在华中科技大学就读期间发起的校园直播项目PPLive.当时的直播技术 ...

  4. 2023-04-21:用go语言重写ffmpeg的metadata.c示例。

    2023-04-21:用go语言重写ffmpeg的metadata.c示例. 答案2023-04-21: 这段 Go 代码演示了如何使用 ffmpeg-go 库中的函数来读取多媒体文件元数据,包括视频 ...

  5. 2023-03-02:给定一个数组arr,长度为n, 任意相邻的两个数里面至少要有一个被选出来,组成子序列,才是合法的! 求所有可能的合法子序列中,最大中位数是多少? 中位数的定义为上中位数, [1,

    2023-03-02:给定一个数组arr,长度为n, 任意相邻的两个数里面至少要有一个被选出来,组成子序列,才是合法的! 求所有可能的合法子序列中,最大中位数是多少? 中位数的定义为上中位数, [1, ...

  6. 2021-12-10:64位的浮点数和64位的有符号整数,哪个能表示的数据个数多? A.整型多。 B.浮点型多。 C.与平台有关。 D.一样多。 来自qq群。

    2021-12-10:64位的浮点数和64位的有符号整数,哪个能表示的数据个数多? A.整型多. B.浮点型多. C.与平台有关. D.一样多. 来自qq群. 答案2021-12-10: 答案选A. ...

  7. 园子的商业化努力-AI人才服务:招募AI导师

    各位园子的小伙伴: 感谢大家对园子的支持,园子差不多接近20年的历程,一直是最低配模式生存和发展,感谢大家对于前段时间的困局给予了商业化的各种建议!在大家的鼓励与支持之下,园子的商业化努力正在以更快的 ...

  8. idea 查看scala源代码

    使用idea编写spark程序,想要查看源代码,点进去是compiled code private[sql] def this(sc : org.apache.spark.SparkContext) ...

  9. 2013年蓝桥杯C/C++大学B组省赛真题(翻硬币)

    题目描述: 明正在玩一个"翻硬币"的游戏. 桌上放着排成一排的若干硬币.我们用 * 表示正面,用 o 表示反面(是小写字母,不是零). 比如,可能情形是:**oo***oooo 如 ...

  10. ArcMap手动新建矢量要素的方式

      本文介绍在ArcGIS下属ArcMap软件中,新建点.线.面等矢量要素图层,并对新建图层的空间范围加以划定的方法.   首先,在右侧"Catalog"栏中选择需要存放新建立矢量 ...