Python实现图像手绘效果的方法详解

闻溪
闻溪
发布时间:2026-10-16 | 8人浏览过
原创

本文详解如何利用Python的PIL库与NumPy实现图像手绘效果。内容涵盖RGB色彩模式原理、图像数组结构解析,以及通过梯度重构、虚拟光源模拟和灰度归一化生成素描风格图像的具体代码实现与参数调整方法。

图像的数组表示

图像的RGB色彩模式

在计算机视觉中,图像通常采用RGB色彩模式进行存储与处理,这意味着每个像素点的颜色信息由红色(Red)、绿色(Green)和蓝色(Blue)三个通道共同构成。

通过调整这三个颜色通道的数值及其叠加关系,可以合成出各种各样的颜色。具体而言:

  • R 红色,取值范围,0‐255
  • G 绿色,取值范围,0‐255
  • B 蓝色,取值范围,0‐255

RGB色彩模式所涵盖的颜色范围,基本覆盖了人类视觉系统能够感知的所有颜色。

PIL库

PIL——Python Image Library

PIL是一个功能强大的第三方图像处理库。若需在命令行环境中安装,可执行以下命令:

#安装
pip install pillow
#引入包
from PIL import Image

在PIL库中,Image类用于代表一个图像对象。

图像组成

从数据结构角度看,图像是一个由像素构成的二维矩阵,其中每个元素对应一个RGB值(即R、G、B三元组)。因此,图像在内存中表现为一个三维数组,其维度分别对应图像的高度、宽度以及像素的RGB分量。

from PIL import Image
import numpy as np
 
im=np.array(Image.open("beijing.jpg"))
print(im.shape,im.dtype)

其输出结果是

(669, 1012, 3) uint8

图像的变换

接下来的操作将演示如何读取图像、获取像素RGB值、进行相应修改,并将结果保存为新的图像文件。

首先,我们尝试生成每个像素颜色互补的图像:

from PIL import Image
import numpy as np
 
a=np.array(Image.open("beijing.jpg"))
b=[255,255,255]-a
im=Image.fromarray(b.astype("uint8"))
im.save('./new.jpg')

其次,观察图像经过灰度处理后的效果,此时主要保留亮度信息。

from PIL import Image
import numpy as np
 
a=np.array(Image.open("beijing.jpg").convert("L"))
b=255-a
im=Image.fromarray(b.astype("uint8"))
im.save('./new.jpg')

对灰度图像进行区间变换处理

from PIL import Image
import numpy as np
 
a=np.array(Image.open("beijing.jpg").convert("L"))
b=(100/255)*a+150
im=Image.fromarray(b.astype("uint8"))
im.save('./new.jpg')

对灰度图像像素值进行平方运算处理

from PIL import Image
import numpy as np
 
a=np.array(Image.open("beijing.jpg").convert("L"))
b=255*(a/255)**2
im=Image.fromarray(b.astype("uint8"))
im.save('./new.jpg')

通过上述示例可以看出,我们只需针对特定的通道或数值进行修改即可实现不同的视觉效果。

图像的手绘效果

手绘效果展示

实现手绘风格通常具备以下几个显著特征:

  • 黑白灰色
  • 边界线条较重
  • 相同或相近色彩趋于白色
  • 略有光源效果

代码展示与讲解

from PIL import Image
import numpy as np
 
a = np.asarray(Image.open('./beijing.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('./beijingHD.jpg')
 

梯度的重构

利用像素之间的梯度值和虚拟深度值对图像进行重构,根据灰度变化来模拟人类视觉的远近程度。

depth = 10.					
grad = np.gradient(a)				
grad_x, grad_y = grad 				
grad_x = grad_x*depth/100.
grad_y = grad_y*depth/100.

预设深度值depth为10,其取值范围0‐100,再提取x和y方向的梯度值,根据深度调整x和y方向的梯度值。

光源效果

根据灰度变化来模拟人类视觉的远近程度。

  • 设计一个位于图像斜上方的虚拟光源
  • 光源相对于图像的俯视角为Elevation,方位角为Azimuth
  • 建立光源对个点梯度值的影响函数
  • 运算出各点的新像素值
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) 			

np.cos(vec_el)为单位光线在地平面上的投影长度,dx, dy, dz是光源对x/y/z三方向的影响程度。

梯度归一化

A = np.sqrt(grad_x**2 + grad_y**2 + 1.)
uni_x = grad_x/A
uni_y = grad_y/A
uni_z = 1./A
b = 255*(dx*uni_x + dy*uni_y + dz*uni_z) 

A是构造x和y轴梯度的三维归一化单位坐标系,然后梯度与光源相互作用,将梯度转化为灰度

图像生成

b = b.clip(0,255)
 
im = Image.fromarray(b.astype('uint8')) 	#重构图像
im.save('./beijingHD.jpg')

在这里,为避免数据越界,将生成的灰度值裁剪至0‐255区间

到此这篇关于Python实现图像手绘效果的方法详解的文章就介绍到这了,更多相关Python图像手绘内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表