github unity 图片切换效果_[Unity实现]图像去雾

5c57baaa939557c7425f059657468f5b.png

(文章图片均来自网络, 侵删)


大二第二学期的数字图像处理, 我们小组选择了"视频去雾"作为学期末的探究实验, 这个实验基于何凯明博士的论文《Single Image Haze Removal Using Dark Channel Prior》[1] 和 《Guided Image Filtering》[2]
为了方便学习和快速理解, 我参考了多个博客来学习:
《Single Image Haze Removal Using Dark Channel Prior》图像去雾算法的原理、实现、效果[3],
导向滤波(Guided Filter)的解析与实现[4],
双边滤波与引导滤波[5],
在此基础上, 对比原论文进行理解.


1.暗通道先验

f8067bf045415be6f1b6a343bd820e64.png

即:
1. 首先求出每个像素RGB分量中的最小值,存入一副和原始图像大小相同的灰度图中

2. 再对这幅灰度图进行最小值滤波,滤波的半径由窗口Ω(x)大小决定,一般有:WindowSize = 2 * Radius + 1

暗通道先验理论:

where Jc is a color channel of J and Ω(x) is a local patch
centered at x. Our observation says that except for the
sky region, the intensity of Jdark is low and tends to be
zero, if J is a haze-free outdoor image. We call Jdark the
dark channel of J, and we call the above statistical observation
or knowledge the dark channel prior.

简单来讲, 就是无霾非天空区域的暗通道强度接近0.

2. 雾图像形成模型

2.1 雾图像形成模型

7610ae236eb63a76b5c25d8d4058d2ed.png


翻译一下:Haze = Origin*Transmissivity + (1-Transmissivity)*HazeColor
- Haze : 有雾的图像
- 当前已知
- Origin : 原始(没有雾的)图像
- 希望得到的图像
- Transmissivity : 透射率
- 通过暗通道先验理论计算获得
- HazeColor是雾(大气)的颜色
- 给定常量

所以接下来求透射率T.

2.2 求透射率T

由于HazeColor有RGB三个分量, 为了方便求暗通道, 首先将1.2中的雾图像形成模型公式变换一下:

cc1cc9885eb5c1bdcb8235ff8d9f7091.png

然后对两边分别求暗通道:

2bcece2fa663056aea86baee0c0a074b.png

由1.1的暗通道先验理论得:

bc9eb3f0d37961aef0bbd3fe6f7f87ba.png

因此得透射率T

ccd7cde1d7982a99f34b5014814468bb.png

为了保留一定程度的雾(模拟现实情况, 景深效果等), 此处再引入一个因子 ω=0.95

f010fd1016f492469803133c1dfc12e0.png

2.3 估计一下HazeColor

差点忘了, 前面还提到了一个常量, 公式里'A', 也就是大气的颜色. 我们可以借助于暗通道图来从有雾图像中获取该值:
1. 从暗通道图中按照亮度的大小取前0.1%的像素。
2. 在这些位置中,在原始有雾图像I中寻找对应的具有最高亮度的点的值,作为A值。

3. 开始去雾!

3.1 最终去雾公式:

由第二章节得恢复公式:Origin = (Haze - HazeColor)/Transmissivity + HazeColor

由于透射率T偏小时(当此区域雾太重...), Origin值将偏大导致图像过白, 所以设置一个阈值(t0 = 0.1):

9c52079507ec7a4868a95573773032a4.png

## 3.2 目前缺点
由于透射率的计算不够精细(较高的精细度会导致性能问题), 所以可以看到边缘没有去雾以及部分地方去雾有较明显的问题.

3bc5642a7238d7758377156533634a31.png

所以在2011年,何博士又出了一片论文,其中提到了导向滤波的方式来获得较好的去雾效果.

4. 导向滤波

4.1 导向滤波原理

局部线性模型认为,某函数上一点与其邻近部分的点成线性关系,一个复杂的函数就可以用很多局部的线性函数来表示,当需要求该函数上某一点的值时,只需计算所有包含该点的线性函数的值并做平均即可。这种模型,在表示非解析函数上,非常有用。

同理,我们可以认为图像是一个二维函数,而且没法写出解析表达式,因此我们假设该函数的输出与输入在一个二维窗口内满足线性关系,如下

9667a48fb756719fcd179abec459a29a.png


其中I是输入, q是输出.对两边取梯度可得到 ▽q = a▽I, 即输入和输入有类似的梯度, 所以导向滤波能保持边缘特性.
下一步是求出线性函数的系数,也就是线性回归,即希望拟合函数的输出值与真实值p之间的差距最小,也就是让下式最小

01075e411d08bd9c98060ae2a0aaecf2.png


p是待滤波图像, e用于防止a过大, 调节滤波效果, 得到

1a5d1d1c69f09cd80b69a8fb9e3ad8ac.png


其中, u_k是I在窗口w_k中的平均值, σ_k^2是I在窗口w_k这个i不过的方差, |w|是窗口w_k中像素的数量. p_k是滤波图像p在窗口w_k中的均值.
因此, 在求具体某点的输出值时, 只需将所有包含该点的线性函数值平均即可:

96302b0dccc37772f35e95d6843335cd.png


w_k是包含像素i的窗口
当把引导滤波用作边缘保持滤波器时,往往有 I = p (一直在想引导图像要怎么获得, 原来用原图就可以)

4.2 导向滤波实现

176817eea799088c4124073785c3eafb.png


(其中, mean filter可使用box filter实现)

4.3 在原来的去雾方法中使用导向滤波

将原来算出的暗通道作为原图, 将有雾的原始图片作为引导图, 进行导向滤波得到一张更好的暗通道图, 用它替换原来的暗通道图应用到去雾过程中即可.

5. 使用Unity实现

知道了算法, 实现起来没有什么难点, 主要步骤:
- 使用Unity播放视频
- 使用Unity摄像机获取想要处理的原始有雾图像
- 在OnRenderImage方法中对图像进行去雾处理
- 计算大气颜色
- 根据大气颜色获得初始暗通道图
- 将初始暗通道图作为导向滤波的原图, 将原始雾图作为导向滤波引导图, 获得最终暗通道图
- 根据暗通道图获得透射图
- 根据透射图和大气颜色获得去雾图.
- 输出去雾图像

效果展示 :

2e77902200e5a78f66fdc3a02029150c.png


这是Unity工程的地址 :

Github : Haze Removal​github.com

知乎导入markdown文档实在太难过了, 这是我的博客原文.

基于暗通道先验的图像去雾实验​jamesika.github.io

参考文献

  • [1] Kaiming He, Jian Sun, Xiaoou Tang, Single Image Haze Removal Using Dark Channel Prior. IEEE Trans Pattern Anal Mach Intell , 2011 , 33 (12) :2341-2353
  • [2] Kaiming He, Jian Sun, Xiaoou Tang, Guided Image Filtering. IEEE Transactions on Pattern Analysis and Machine Intelligence, Volume 35, Issue 6, pp. 1397-1409, June 2013
  • [3]《Single Image Haze Removal Using Dark Channel Prior》图像去雾算法的原理、实现、效果
  • [4]导向滤波(Guided Filter)的解析与实现
  • [5]双边滤波与引导滤波
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值