铅笔画算法

PencilDrawing

论文《Combining Sketch and Tone for Pencil Drawing Production》(Cewu Lu, LiXu, JiayaJia)
算法的实现。

代码说明

oschina: git.oschina.net/corfox/Kikyo
github: github.com/corfox/Kikyo
该算法的实现在项目目录PencilDrawing中。

依赖

OpenCV2.4.10
Eigen3

class PencilDrawing

构造函数

PencilDrawing()

成员函数

void operator()(const Mat& image, const Mat& pencilStyle, OUT_PARA Mat& pencilDrawing)

生成图像image的铅笔画。

image:原始图像,image的类型需为BGR三通道彩色图或Gray单通道灰度图。
pencilStyle:铅笔画的风格模板(线条的粗细或轻重)
pencilDrawing:算法生成的铅笔画

算法步骤

注:此算法步骤摘自《Combining Sketch and Tone for Pencil Drawing Production》

算法的整体框架如下图:
框架图

1.生成梯度图: $$G=\sqrt{(\alpha_x{I})^2 + (\alpha_y{I})^2}$$

2.生成线条形状图: $$G_i=\varphi_i * G, i=1, ..., 8$$
其中$\varphi_i$是线段滤波器,方向为${45}^\circ*i$。
$$C_i(p) = \begin{cases}G(p), & if \space {argmin}_i\{G_i(p)\} = i\\ 0, & otherwise \end{cases}$$
$$S^{'} = \sum_{i=1}^8 (\varphi_i \otimes C_i)$$
再次利用$\varphi_i$对$C_i$进行滤波,并取和。

3.将$S^{'}$映射到区间$[0, 1]$得到$S^{''}$,最终生成的线条图$S=1-S^{''}$

4.生成色调图,将原始图像亮度值划分为三个区域:明亮区,暗区和温和区。每个区域使用一种分布去描述该区域的亮度变化。

明亮区:$$p_1(v)=\begin{cases} \frac{1}{\delta_b} e^{-\frac{1-v}{\delta_b}}, & if \space v \le 1 \\0, & otherwise \end{cases}$$

温和区:$$p_2(v) = \begin{cases} \frac{1}{u_b - u_a}, & if \space u_a \le v \le u_b \\0, & otherwise \end{cases}$$

暗区:$$p_e(v) = \frac{1}{\sqrt{2\pi\delta_d}} e^{-\frac{(v-u_d)^2}{2\delta_d^2}}$$

每个像素值对应的概率值为$p(v) = \frac{1}{Z} \sum_{i=1}^3w_ip_i(v)$,其中$Z$是归一化因子,使得$\int_0^1p(v)dv = 1$。

其中,每种分布的参数值是通过已有的铅笔画训练得到的,计算公式如下:$\delta_b=\frac{1}{N}\sum_{i=1}^{N}|x_i - 1|$, $u_a = m_m - \sqrt3s_m$, $u_b = m_m + \sqrt3s_m$, $u_d=m_d$, $\delta_d = s_d$。$x_i$表示铅笔画明亮区域的像素值,$m$与$s$表示铅笔画相应区域的像素均值与标准差。

最后,使用直方图匹配得到色调图$J$

5.纹理渲染,记$H$为铅笔画风格图,使用$H$拟合$J$:$H(x)^{\beta{(x)}} \approx J(x)$。可以通过共轭梯度法求得$\beta$:$$\beta^{*} = argmin_{\beta}||\beta \ln{H} - \ln{J}||_2^2 + \lambda||\nabla\beta||_2^2$$

最后得到铅笔纹理图: $$T = H^{\beta^{*}}$$

6.最终得到的铅笔画可以表示为:$$R = S \cdot T$$

## 参考资料

1. [《Combining Sketch and Tone for Pencil Drawing Production》(Cewu Lu, LiXu, JiayaJia)](http://www.cse.cuhk.edu.hk/leojia/projects/pencilsketch/pencil_drawing.htm)

2. [MatLab版本实现-github.com/candycat1992/PencilDrawing](https://github.com/candycat1992/PencilDrawing)

3. [Python版实现-github.com/moonfighting/PencilDrawing--python-version](https://github.com/moonfighting/PencilDrawing--python-version)

posted @ 2016-08-28 16:04  corfox  阅读(583)  评论(0编辑  收藏  举报