前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python实现彩照转黑白以及图片转素描画

python实现彩照转黑白以及图片转素描画

作者头像
用户1359560
发布2019-03-22 16:02:58
1.8K0
发布2019-03-22 16:02:58
举报
文章被收录于专栏:生信小驿站生信小驿站

(1)彩照转黑白

代码语言:javascript
复制
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 21 03:45:16 2019

@author: czh
"""
%clear
%reset -f
# In[*]
from PIL import Image
import numpy as np
import os
os.chdir('D:\\train\\cv')
# In[*]

from PIL import Image
import numpy as np
a = np.asarray(Image.open("AWM.jpg").convert('L'))#.convert是变成黑白的
grad = np.gradient(a)
grad
grad_x, grad_y = grad

# In[*]
b=255-a#在对应的颜色通道减去他自己变成黑白底片的效果
im=Image.fromarray(b.astype('uint8'))
im
# In[*]

c=(100/255)*a+150#区间变换,颜色比较淡的灰度的图片
im=Image.fromarray(c.astype('uint8'))

im
# In[*]
d=255*(a/255)**2#像素平方,颜色比较深的图
im=Image.fromarray(d.astype('uint8'))
im

image.png

image.png

image.png

(2)图片转素描画

通过Numpy中的asarray函数将图片的灰度值以浮点型矩阵的形式存储起来,再用gradient函数得出图片灰度值的梯度

代码语言:javascript
复制
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 21 03:45:16 2019

@author: czh
"""
%clear
%reset -f
# In[*]
from PIL import Image
import numpy as np
import os
os.chdir('D:\\train\\cv')
# In[*]

from PIL import Image
import numpy as np
a = np.asarray(Image.open("StarryNight.jpg").convert('L'))#.convert是变成黑白的
grad = np.gradient(a)
grad
Out[37]: 
[array([[225. , 233. , 252. , ...,  18. ,  19. ,   2. ],
        [  0.5, 127. ,   3.5, ...,   5. ,  18. ,  17. ],
        [ 19.5,  10. , 126.5, ..., 103.5,   5.5,  29. ],
        ...,
        [  0. ,   0.5,   1. , ..., 126.5, 126.5, 126.5],
        [  4. ,   4.5,   5. , ...,   7. ,   7. ,   7. ],
        [  9. ,  10. ,   9. , ...,  13. ,  13. ,  13. ]]),
 array([[239. ,   0. ,  21. , ..., 113.5, 115.5, 243. ],
        [247. ,  13.5,  29. , ...,  25.5, 107.5, 226. ],
        [236. ,   3. ,  17. , ...,  62.5, 127.5, 241. ],
        ...,
        [242. , 116.5, 126. , ...,   4. ,   5. ,   5. ],
        [242. , 117.5, 127. , ...,   3. ,   5. ,   5. ],
        [243. , 117.5, 127. , ...,   5. ,   5. ,   5. ]])]

我们来观察一下L矩阵,可以看出a是一个二维浮点型矩阵,因此它的梯度grad里应该有两个数组矩阵,分别对应两层维度的梯度。现取最外层维度梯度为x方向的梯度值grad_x,取第二层维度梯度值为y方向梯度值grad_y

代码语言:javascript
复制
grad_x, grad_y = grad

这时我们已经取得了图像的梯度值,就可以通过改变像素的梯度值来改变图像的灰度变化,对图像进行重构了。我们先设一个深度值depth,取值范围为(0,100),然后利用深度调整x和y方向的梯度值。 我们使

代码语言:javascript
复制
grad_x = grad_x*depth/100.
grad_y = grad_y*depth/100.

深度值越小,重构后的图像梯度值越小,即图像灰度值变化越小,画面线条越少,整体更显洁净。

比如当depth=1时:

反之,深度值越大,重构后的图像梯度值越大,即图像灰度值变化越大,画面线条越多,整体更显肮脏。比如当depth=100时

image.png

因此我们需要通过改变depth,找到最符合人类视觉远近程度的深度值。经过多次测试发现,当深度值为10左右时,即图像灰度梯度变为原来的10%左右时,画面最接近手绘化效果。(当然,对于不同的图片,这个最佳深度值不一定相同)。在本文中我们取depth=10

制造光源效果

类似版画的效果,这是因为此时的图像还没有光源效果,跟我们实际观察事物的感觉不一样,因此我们还需要为图像制造光源效果。如图,我们先假设一个光源位于图像斜上方,设俯视角为el,方位角为az,则单位光线在x,y,z方向上的投影长度分别为:通过多次调整发现,当俯视角el=π/2.2, 方位角az=π/4时光照效果最好。(当然对于不同图像两个角度的选取不一定相同)

实现代码为:

代码语言:javascript
复制
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)     #光源归一化

我们将这个过程叫做光源的归一化

重构图像

由于灰度值的选取范围为(0,255),为了避免数据越界,需要将生成的灰度值裁剪至0-255之间

代码语言:javascript
复制
b = b.clip(0,255)

由新的灰度值重构图像

代码语言:javascript
复制
im = Image.fromarray(gd.astype('uint8'))

其中uint8是一种数据类型。这时图像的手绘化效果已经完成了

代码语言:javascript
复制
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 21 03:45:16 2019

@author: czh
"""
%clear
%reset -f
# In[*]
from PIL import Image
import numpy as np
import os
os.chdir('D:\\train\\cv')
# In[*]

from PIL import Image
import numpy as np
a = np.asarray(Image.open("AWM.jpg").convert('L'))#.convert是变成黑白的
grad = np.gradient(a)
grad
grad_x, grad_y = grad

# In[*]
b=255-a#在对应的颜色通道减去他自己变成黑白底片的效果
im=Image.fromarray(b.astype('uint8'))
im
# In[*]

c=(100/255)*a+150#区间变换,颜色比较淡的灰度的图片
im=Image.fromarray(c.astype('uint8'))

im
# In[*]
d=255*(a/255)**2#像素平方,颜色比较深的图
im=Image.fromarray(d.astype('uint8'))
im


# In[*]
a = np.asarray(Image.open("AWM.jpg").convert('L')).astype('float')
# In[*]
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
# In[*]
im.save("手绘.jpg")
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.03.22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • (1)彩照转黑白
  • (2)图片转素描画
    • 制造光源效果
      • 重构图像
      相关产品与服务
      图像处理
      图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档