Python实战:图像的变换&图像的手绘效果

浏览: 1077

一、图像的数组表示

图像一般是使用RGB色彩模式,即每个像素点的颜色由红、绿、蓝组成。三种颜色叠加可以得到各种颜色,包括了人类视力所能感知的所有颜色。其中:

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

图像是由像素组成的二维矩阵,每个元素是一个RGB值。即图像可以用一个三维数组表示,维度分别是高度、宽度和像素RGB值,数据类型是uint8。

在Python中有一个强大的图像处理的第三方库,即PIL,安装方法:pip install pillow,通过from PIL import Image调用图像的类对图像进行数组表示。

# 库导入
import numpy as np
from PIL import Image
# 图像读取
a=np.array(Image.open("C:/Users/花花/Desktop/image/fj.jpg"))
print(a.shape,a.dtype)

# (483, 752, 3) uint8


二、图像的变换

由于图像可以表示为数组,数组可以进行运算,那么通过运算变换像素的RGB值即可实现图像的变换。例如可以进行取反、区间变换、平方等运算,来实现图像的变换。代码及效果如下:

# 图像的变换1
b=[255,255,255]-a # 像素变换,取反
im=Image.fromarray(b.astype('uint8')) # 重新生成变换像素后的图像类型
im.save("C:/Users/花花/Desktop/image/fj1.jpg") # 保存新的图像文件

fj.jpg

原图

fj1.jpg

效果图-图像变换1

# 图像的变换2
# convert('L')是对彩色图片变成为灰度值图片,这样生成的数组是二维数组,对应灰度值
a1=np.array(Image.open("C:/Users/花花/Desktop/image/fj.jpg").convert('L'))
b1=255-a1 # 取反
im1=Image.fromarray(b1.astype('uint8'))
im1.save("C:/Users/花花/Desktop/image/fj2.jpg")

fj.jpg

原图

fj2.jpg

效果图-图像变换2

# 图像的变换3
a2=np.array(Image.open("C:/Users/花花/Desktop/image/fj.jpg").convert('L'))
c=(100/255)*a2+150 # 区间变换
im2=Image.fromarray(c.astype('uint8'))
im2.save("C:/Users/花花/Desktop/image/fj3.jpg")

fj.jpg

原图

fj3.jpg

效果图-图像变换3

# 图像的变换4
a3=np.array(Image.open("C:/Users/花花/Desktop/image/fj.jpg").convert('L'))
d=255*(a3/255)**2 # 像素平方
im3=Image.fromarray(d.astype('uint8'))
im3.save("C:/Users/花花/Desktop/image/fj4.jpg")

fj.jpg

原图

fj4.jpg

效果图-图像变换4


三、图像的手绘效果

手绘一般是黑白灰色,且线条感较重,有一定的光感。需要利用像素之前的梯度值和虚拟深度值对图像进行重构,利用灰度变化模拟人类视觉的远近程度。首先构建三维坐标中新的梯度值并归一化,然后预设光源构建光源对三维坐标系各个轴的单位影响,最后通过梯度和光源相互作用,实现灰度值的重构,形成新的图像文件,即为手绘效果。完整代码和效果如下:

from PIL import Image
import numpy as np

# 图像识别
a=np.array(Image.open("C:/Users/花花/Desktop/image/fj.jpg").convert('L')).astype('float')

# 梯度重构和归一化
depth=10. # 预设深度值为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) # 避免数据越界,将生成的灰度裁剪成0-255区间

im=Image.fromarray(b.astype('uint8')) #重构为图像类型
im.save("C:/Users/花花/Desktop/image/fjHD.jpg")

fj.jpg

原图

fjHD.jpg

手绘效果图

推荐 0
本文由 花花_Angel 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册