news 2026/7/7 12:26:18

这是魔法吗?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/7/7 8:29:44

开源绘图新选择:Excalidraw结合AI实现自然语言转流程图

开源绘图新选择:Excalidraw结合AI实现自然语言转流程图 在远程协作成为常态的今天,团队沟通中最常见的场景之一,可能就是“我有个想法,但说不清楚”——尤其是面对复杂系统架构或业务流程时。传统的绘图工具虽然功能齐全&#xff…

作者头像 李华
网站建设 2026/7/7 7:56:16

MBZUAI科学家发明AI版“火眼金睛“:告别“真假孙悟空“的时代困扰

这项由阿联酋人工智能大学(MBZUAI)的萨里姆哈希米、阿卜杜勒拉赫曼埃尔萨耶德、穆罕默德塔尔哈阿拉姆、萨穆埃莱波比和尼尔斯卢卡斯团队完成的研究发表于2024年12月,论文编号为arXiv:2512.15182v1。这项研究解决了一个困扰现代社会的核心问题…

作者头像 李华
网站建设 2026/7/7 14:15:50

Excalidraw入门到精通:AI驱动下的可视化设计革命

Excalidraw:当手绘白板遇上AI,可视化协作的智能跃迁 在一次跨时区的远程架构评审会上,团队正为如何清晰表达新系统的数据流向而发愁。有人提议用Visio画图,但格式复杂、协作不便;也有人想手绘拍照上传,又怕…

作者头像 李华
网站建设 2026/7/7 12:58:18

AdamW weight_decay设高,后来才知道对bias/BN层设0权重衰减

💓 博客主页:借口的CSDN主页 ⏩ 文章专栏:《热点资讯》 目录人类与AI的相爱相杀日常 自动驾驶:人类司机的终极噩梦 医疗AI:能看X光片的"医生" 艺术创作:AI画的蒙娜丽莎会打游戏 智能客服&#xf…

作者头像 李华
网站建设 2026/7/7 15:30:41

20、互联网实用操作指南

互联网实用操作指南 一、Cortana搜索与信息获取 Cortana不仅可以展示来自维基百科的信息,还能呈现微软搜索引擎Bing的信息和图片。若Cortana未能提供足够详细的信息,可滚动至其信息面板底部,那里有一个在Bing上搜索该术语的链接,能让你更自主地进行搜索。 二、从互联网保…

作者头像 李华
网站建设 2026/7/7 17:34:17

26、Windows 10 系统优化与用户账户管理全攻略

Windows 10 系统优化与用户账户管理全攻略 在使用 Windows 10 系统的过程中,我们常常会遇到各种问题,比如磁盘空间不足、设备驱动不兼容、多用户共享电脑等。本文将为你详细介绍如何解决这些问题,让你的 Windows 10 系统更加稳定、高效。 一、释放磁盘空间 当你的电脑磁盘…

作者头像 李华