Umb
Articles3
Tags4
Categories0
边缘提取---图片转线稿

边缘提取---图片转线稿

一种提取图片边缘的算法

起源

突发奇想利用边缘提取做了一个图片转线稿的小程序

先来看一下效果:

环境

Python 3.8 、PIL、numpy

直接使用pip install 安装即可

pip install pillow
pip install numpy

思路

众所周知,我们所看到的图片是一副二维图片,由一堆RGB色值各不相同的像素点构成。

那么我们可以将各个像素点的RGB色值转变为图片的第三维度,这样图片就由二维平面图变为了三维立体图。

此时我们将这张图片看作一个实实在在的三维物体,三维物体表面某点高度由对应二维平面的像素点的RGB色值决定,RGB色值有大有小,自然三维物体表面就会有高低起伏

在某个高度,某个方向上添加一个点光源照射这个物体,在光的照射下,物体凹凸不平的表面自然而然就会出现阴影(RGB色值变化越大的地方表面越陡,阴影越深),再将这些阴影投影回二维平面,这样就得到了图片的边缘。

实现

  1. 将原图转为灰度图

    为了简化矩阵,提高运算速度,我们对图像进行灰度图转换(反正最后的成品也是黑白两色的线稿)

  2. 使用高斯滤波进行降噪

    这个算法对噪点很敏感(你想想平地上突然隆起一个笔直的擎天柱是不是显得特别扎眼)去除噪点影响

  3. 计算图像梯度

    numpy自带矩阵梯度计算(np.gradient),该梯度用来作为图像升维参考,梯度值越大,说明图像颜色在该点变化率越大,对应的虚拟深度应该也越大。

  4. 赋予图像虚拟深度

    因为图像中的RGB值有大有小,直接作为三维高度并不合适,需要经过一些权衡计算来将其转变为三维高度,我们这里结合图像梯度和颜色向量来计算,并预设一个放大深度值,用来放大深度效果。

  5. 光源设置

    这个需要进行调参了,光源的位置是一个很玄学的问题,位置不同,最后的效果也完全不一样。

    个人觉得光源的最佳位置是与平面俯视角(即z轴与平面的夹角)呈 α =(pi / 2.2 )°,平面方向角(即x与y的夹角呈β =(pi / 4 )°,这个角度下提取到的线稿最为清晰。

  6. 三维梯度转二维灰度

    最后我们需要的是二维矩阵而不是三维矩阵,因此分别求平面各点在xy平面、xz平面、yz平面的投影

    将三个方向的投影的值相加的和与原色相乘,也就是(灰度化)

  7. 极值处理

    将处理后的图像进行极值处理,RGB值靠近黑色(0)的归为黑色,靠近白色(255)的归为白色,突出边缘。

  8. 锐化处理

    为了让我们最后的线稿更加清晰,可以对处理后的图片进行一定程度的锐化操作

    代码

#:param: img PIL.Image对象
def img_ege(img):
     img_np_array = np.asarray(img).astype('float')
     depth = 10.  # 放大深度值
     grad = np.gradient(img_np_array)# 返回二维矩阵的数值梯度
     grad_x, grad_y = grad  # 取x,y方向的梯度值
     grad_x = grad_x * depth / 100.  # 归一化
     grad_y = grad_y * depth / 100.
     # 构造x、y梯度的三维归一化坐标系
     A = np.sqrt(grad_x ** 2 + grad_y ** 2 + 1.)
     uni_x = grad_x / A  # x方向单位法向量
     uni_y = grad_y / A  # y方向单位法向量
     uni_z = 1. / A  # z方向单位法向量
     vec_el = np.pi / 2.2  # 俯视角
     vec_az = np.pi / 4.  # 方向角
     # 投影
     dx = np.cos(vec_el) * np.cos(vec_az)
     dy = np.cos(vec_el) * np.sin(vec_az)
     dz = np.sin(vec_el)

     b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)  # 梯度转灰度,三维投影回二维
     b = b.clip(0, 255)  # 极值处理

源码地址

Author:Umb
Link:https://farewell12345.github.io/2021/04/12/%E8%BE%B9%E7%BC%98%E6%8F%90%E5%8F%96-%E5%9B%BE%E7%89%87%E8%BD%AC%E7%BA%BF%E7%A8%BF/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可