LIC(Line Integral Convolution)

前言

最近在阅读NPR相关论文时需要用到线积分卷积,因此查阅了一下相关论文以及网上已有的实现方法。本文主要讲解线积分卷积的快速实现版本(SIGGRAPH,1995)。为了便于实验和测试,用Python实现并进行了简单的封装。如果本文讲解部分有任何理解错误,希望明确指出。

线积分卷积原理

首先,我们需要获取一张图像的二维矢量场,基于每个像素点上矢量的方向来构造一条流线。构造流线的方式在最早的论文中使用了DDA算法。通过以下的公式来进行迭代:

P 0 = ( x + 0.5 , y + 0.5 ) P_0 = (x+0.5,y+0.5) P0=(x+0.5,y+0.5)

P i = P i − 1 + V ( P i − 1 ) ∣ V ( P i − 1 ) ∣ ∗ △ s i − 1 P_i = P_{i-1} + \frac{V(P_{i-1})}{|V(P_{i-1})|}*\bigtriangleup{s_{i-1}} Pi=Pi1+V(Pi1)V(Pi1)si1

此处 V ( P i − 1 ) V(P_{i-1}) V(Pi1)代表的是矢量场 P i − 1 P_{i-1} Pi1坐标下的数值。

△ s i − 1 \bigtriangleup{s_{i-1}} si1的含义是在 P i − 1 P_{i-1} Pi1点处上下左右四个方向中变化量最小的方向的数值,计算的方式也很简单,请参考论文1

另外需要注意的是此处需要计算出一条流线,但是初始的点只有一个,所以要考虑到向前查找和向后查找,即:

P i = P i − 1 − V ( P i − 1 ) ∣ V ( P i − 1 ) ∣ ∗ △ s i − 1 P_i = P_{i-1} - \frac{V(P_{i-1})}{|V(P_{i-1})|}*\bigtriangleup{s_{i-1}} Pi=Pi1V(Pi1)V(Pi1)si1

这样逐步查找构造一条流线的方式本质上就是递归来寻找下一个点,结束条件依靠 △ s i − 1 \bigtriangleup{s_{i-1}} si1数值设定一个阈值来控制。

最后,通过刚才构筑好的多条流线通过卷积运算的方式就可以计算出每一个像素点的数值。此处计算方式不是很难,参考第一篇论文就可以进行计算。


时间原因,以后再补充关于快速运算的算法。TODO

不足

参考文献1的问题就在于运算速度过慢,因而可以通过第二篇的快速算法来进行一定的加速处理2

当然这两篇的实现都是在CPU上进行的,可以通过并行处理的方式进行一定加速。

后续我会补充GPU上的实现算法。

实验结果

输入图片
在这里插入图片描述

输出图片

在这里插入图片描述

参考资料

---------------------------------------------20181019更新----------------------------------

附上WebGL版的demo


  1. Cabral, Brian, and Leith Casey Leedom. "Imaging vector fields using line integral convolution." Proceedings of the 20th annual conference on Computer graphics and interactive techniques. ACM, 1993. ↩︎

  2. Stalling, Detlev, and Hans-Christian Hege. "Fast and resolution independent line integral convolution." Proceedings of the 22nd annual conference on Computer graphics and interactive techniques. ACM, 1995. ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值