news 2026/4/16 19:51:21

这是魔法吗?Python PIL实现二次元手绘效果,29行代码搞定

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
这是魔法吗?Python PIL实现二次元手绘效果,29行代码搞定

Python手绘效果生成器:29行代码实现照片艺术化

摘要:本文介绍如何使用Python的PIL和NumPy库,仅用29行代码实现照片手绘效果。通过图像梯度计算和光照模拟,将普通照片转换为手绘风格的艺术作品。


目录

文章目录

  • Python手绘效果生成器:29行代码实现照片艺术化
    • 目录
    • @[toc]
    • 1. 效果展示
    • 2. 核心原理
    • 3. 完整代码实现
    • 4. 代码详解
      • 4.1 图像预处理
      • 4.2 梯度计算
      • 4.3 深度参数
      • 4.4 法向量计算
      • 4.5 光照设置
      • 4.6 光照计算
    • 5. 参数调优指南
      • 5.1 深度参数(depth)
      • 5.2 光源角度
    • 6. 使用示例
      • 6.1 基础使用
      • 6.2 批量处理扩展
    • 7. 常见问题
      • 7.1 ImportError
      • 7.2 文件路径错误
      • 7.3 内存不足
    • 8. 总结
      • 优势:
      • 局限:
      • 扩展方向:
    • 投票与互动
    • 标签
      • 局限:
      • 扩展方向:
    • 投票与互动
    • 标签

1. 效果展示

先来看看最终效果,上面是原始照片,下面是手绘效果:

|
||

2. 核心原理

手绘效果的核心是通过计算图像梯度来模拟线条,再通过光照模型增强立体感。主要包含以下步骤:

  1. 灰度转换:将彩色图片转换为灰度图
  2. 梯度计算:计算像素点的梯度值
  3. 深度调整:通过depth参数控制立体感强度
  4. 光照模拟:添加光源效果,增强立体感

3. 完整代码实现

fromPILimportImageimportnumpyasnp# 读取图片并转换为灰度图a=np.asarray(Image.open(r".\1.jpg").convert('L')).astype('float')# 深度参数 (0-100),控制立体感强度depth=50.# 计算图像灰度的梯度值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.# 光源的方位角度,弧度值# 计算光源对x、y、z轴的影响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(r".\手绘.jpg")# 保存手绘效果print("保存成功,请查看")

4. 代码详解

4.1 图像预处理

a=np.asarray(Image.open(r".\1.jpg").convert('L')).astype('float')

这行代码做了三件事:

  1. Image.open(r".\1.jpg")- 打开图片文件
  2. .convert('L')- 转换为灰度图(L模式)
  3. np.asarray(...).astype('float')- 转换为NumPy数组,数据类型为float

4.2 梯度计算

grad=np.gradient(a)# 取图像灰度的梯度值grad_x,grad_y=grad# 分别取横纵图像梯度值

np.gradient()函数计算图像的梯度,返回两个数组:

  • grad_x: 水平方向的梯度
  • grad_y: 垂直方向的梯度

梯度反映了图像中像素值的变化程度,边缘位置梯度值较大。

4.3 深度参数

depth=50.# (0-100)grad_x=grad_x*depth/100.grad_y=grad_y*depth/100.

depth参数控制手绘效果的立体感:

  • 值越大,立体感越强,线条越粗
  • 值越小,效果越细腻
  • 范围:0-100

4.4 法向量计算

A=np.sqrt(grad_x**2+grad_y**2+1.)uni_x=grad_x/A uni_y=grad_y/A uni_z=1./A

这部分计算每个像素点的法向量,用于后续的光照计算。

4.5 光照设置

vec_el=np.pi/2.2# 光源的俯视角度,弧度值vec_az=np.pi/4.# 光源的方位角度,弧度值

设置光源位置:

  • vec_el:俯仰角,控制光源从上方照射的角度
  • vec_az:方位角,控制光源从左侧照射的角度

4.6 光照计算

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)

通过点积计算每个像素的光照强度,然后归一化到0-255范围。

5. 参数调优指南

5.1 深度参数(depth)

depth值效果描述适用场景
10-30轻微立体感,线条细腻人像照片
40-60适中立体感风景照片
70-100强烈立体感,线条粗犷建筑照片

5.2 光源角度

# 俯仰角调小(光源更接近水平)vec_el=np.pi/1.8# 方位角调整(从左侧45度改为90度)vec_az=np.pi/2

6. 使用示例

6.1 基础使用

# 准备工作# 1. 准备一张名为"1.jpg"的图片# 2. 安装依赖:pip install pillow numpy# 运行代码python Main.py

6.2 批量处理扩展

虽然原代码只处理单张图片,但可以轻松扩展为批量处理:

fromPILimportImageimportnumpyasnpimportosdefprocess_image(input_path,output_path,depth=50):a=np.asarray(Image.open(input_path).convert('L')).astype('float')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.2vec_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)im=Image.fromarray(b.astype('uint8'))im.save(output_path)# 批量处理input_dir="input_images"output_dir="output_images"os.makedirs(output_dir,exist_ok=True)forfilenameinos.listdir(input_dir):iffilename.endswith(('.jpg','.jpeg','.png')):input_path=os.path.join(input_dir,filename)output_path=os.path.join(output_dir,f"handdraw_{filename}")process_image(input_path,output_path)print(f"处理完成:{filename}")

7. 常见问题

7.1 ImportError

# 安装依赖pip install pillow numpy

7.2 文件路径错误

# 使用绝对路径或相对路径Image.open(r"C:\Users\用户\Desktop\1.jpg")# 绝对路径Image.open(r".\1.jpg")# 相对路径

7.3 内存不足

对于大图片,可以调整图片尺寸:

# 在转换前缩小图片img=Image.open(r".\1.jpg")img=img.resize((img.size[0]//2,img.size[1]//2))# 缩小一半a=np.asarray(img.convert('L')).astype('float')

8. 总结

这个29行的Python手绘效果生成器虽然代码简洁,但包含了图像处理的核心概念:

  1. 图像梯度:用于边缘检测和线条提取
  2. 光照模型:模拟真实世界的光照效果
  3. 数值计算:使用NumPy进行高效的数组运算

优势:

  • 代码简洁易懂
  • 效果直观明显
  • 参数可调节
  • 易于扩展

局限:

  • 只支持单张图片处理
  • 参数需要手动调整
  • 对大图片处理较慢

扩展方向:

  • 添加GUI界面
  • 支持批量处理
  • 参数自动优化
  • 支持更多图片格式

投票与互动

如果这篇文章对你有帮助,请:

  • 点赞支持作者
  • 收藏方便后续查看
  • 评论分享你的想法和建议

标签

#Python#图像处理#PIL#NumPy#手绘效果#29行代码


直观明显

  • 参数可调节
  • 易于扩展

局限:

  • 只支持单张图片处理
  • 参数需要手动调整
  • 对大图片处理较慢

扩展方向:

  • 添加GUI界面
  • 支持批量处理
  • 参数自动优化
  • 支持更多图片格式

投票与互动

如果这篇文章对你有帮助,请:

  • 点赞支持作者
  • 收藏方便后续查看
  • 评论分享你的想法和建议

标签

#Python#图像处理#PIL#NumPy#手绘效果#29行代码

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 16:08:38

3、Windows 10 桌面与开始菜单使用指南

Windows 10 桌面与开始菜单使用指南 1. 绕过安全设置直达桌面 你可以选择完全跳过安全设置,在开机时直接进入桌面。不过,具体的设置方法暂不展开介绍。 2. 认识桌面 当你通过安全屏障后,就会来到 Windows 的主界面——桌面。在 Windows 10 中,桌面再次成为大家登录后的…

作者头像 李华
网站建设 2026/4/16 12:44:24

6、Windows 10文件资源管理器实用技巧与功能全解析

Windows 10文件资源管理器实用技巧与功能全解析 1. 全高窗口技巧 全高窗口技巧虽未获微软营销团队大力推广,却十分实用。它与之前的窗口对齐功能不同,不影响窗口宽度,而是让窗口高度与屏幕一致,类似半最大化。操作方法是抓取窗口底部边缘并向下拖动至屏幕底部,此时窗口会…

作者头像 李华
网站建设 2026/4/16 14:26:08

7、Windows 10文件资源管理器使用指南

Windows 10文件资源管理器使用指南 1. 可选窗口窗格 大多数文件资源管理器窗口顶部都有一些基本信息,至少包括地址栏和功能区。此外,还可以在任何文件资源管理器窗口的右侧添加新面板,有两种形式:预览(所选图标的预览)或详细信息面板。开启这些面板可能会让窗口显得有些…

作者头像 李华
网站建设 2026/4/16 11:04:42

19、微软 Edge 浏览器使用指南

微软 Edge 浏览器使用指南 在当今数字化时代,浏览器是我们访问互联网的重要工具。微软 Edge 浏览器以其快速的浏览速度和简洁的界面设计,成为了许多用户的选择。本文将详细介绍微软 Edge 浏览器的使用方法,帮助你更好地利用它在互联网上畅游。 1. 打开微软 Edge 浏览器 要…

作者头像 李华
网站建设 2026/4/16 9:22:08

24、Windows 10 个性化设置与硬件配置全攻略

Windows 10 个性化设置与硬件配置全攻略 1. 多显示器设置 在使用多显示器时,你可以按照以下步骤进行设置: 1. 拖动屏幕上的显示器图标,使其与实际显示器的摆放位置相匹配。 2. 点击应显示开始按钮的屏幕显示器,然后选中“将此显示器设为主显示器”复选框。 3. 根据需要…

作者头像 李华
网站建设 2026/4/16 14:32:04

25、让Windows远离故障的实用指南

让Windows远离故障的实用指南 1. 创建还原点 虽然Windows正在向更新的刷新系统转变,但老派的系统还原爱好者仍然可以创建和使用可靠的Windows还原点,将电脑恢复到状态良好的时间点。还原点就像一个时间胶囊,能保存电脑在特定时间的设置。如果这些设置后来损坏,恢复到早期的…

作者头像 李华