用python代码将原图转化为手绘图

此文参考了两位博主的代码: 个人感觉挺好玩的,但是代码还没能完全看懂。用我捉襟见肘的计算机视觉和更加贫瘠的图像处理的知识,初步觉得这是用的求灰度值梯度的边缘检测原理,每一个手绘痕迹也就是一条灰度变化较大的边缘(我猜的。。) 现记录一下,权当休闲,等以后某一天回过头来看或许能恍然大悟也不错。 现有原图: 下面分别用两种代码处理该图,生成手绘图,可以比较一下两种代码效果的差异。

  1. 第一种代码
from PIL import Image
import numpy as np

a = np.asarray(Image.open("C:/Users/matebook/Desktop/手绘图原图/图1.jpg").convert(L)).astype(float)

depth = 10.  # (0-100)
grad = np.gradient(a)  # 取图像灰度的梯度值
grad_x, grad_y = grad  # 分别取横纵图像梯度值
grad_x = grad_x * depth / 100.
grad_y = grad_y * depth / 100.
A = np.sqrt(grad_x ** 2 + grad_y ** 2 + 1.)
uni_x = grad_x / A
uni_y = grad_y / A
uni_z = 1. / A

vec_el = np.pi / 2.2  # 光源的俯视角度,弧度值
vec_az = np.pi / 4.  # 光源的方位角度,弧度值
dx = np.cos(vec_el) * np.cos(vec_az)  # 光源对x 轴的影响
dy = np.cos(vec_el) * np.sin(vec_az)  # 光源对y 轴的影响
dz = np.sin(vec_el)  # 光源对z 轴的影响

b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)  # 光源归一化
b = b.clip(0, 255)

im = Image.fromarray(b.astype(uint8))  # 重构图像
im.save("C:/Users/matebook/Desktop/手绘图生成图/手绘图.jpg")
print("保存成功,请到D:/Python/目录下查看")

生成的手绘图:

  1. 第二种代码
from PIL import Image
import numpy as np
#为了定义好俯视角el、方位角az与深度,将三个变量定义在前面便于调节
el=np.pi/2.2
az=np.pi/4.
dep=90.
#转化为灰度图
im=Image.open("C:/Users/matebook/Desktop/手绘图原图/图1.jpg")
im=im.convert(L)
im.save(C:/Users/matebook/Desktop/中间生成的灰度图/灰度.jpg)
#取梯度,对图像进行重构
a=np.asarray(im).astype(float)
grd=np.gradient(a)
grd_x,grd_y=grd
grd_x=grd_x*dep/100.
grd_y=grd_y*dep/100.
#制造光源效果
dx=np.cos(el)*np.cos(az)
dy=np.cos(el)*np.sin(az)
dz=np.sin(el)
uni_x=grd_x
uni_y=grd_y
uni_z=1
b=255*(dx*uni_x+dy*uni_y+dz*uni_z)
b=b.clip(0,255)
im0=Image.fromarray(b.astype(uint8))
im0.save(C:/Users/matebook/Desktop/手绘图生成图/手绘图1.jpg)

中间生成的灰度图: 生成的手绘图: 就这张图而言第一个代码跑的效果较好。 手动调一下代码中的参数应能得到不同的效果。

经验分享 程序员 微信小程序 职场和发展