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