前言
之前经常在网上看到用PS实现真实图片到素描图片的转换,但是流程都大同小异,身为一只程序猿,必须来个一键转化额。
国际惯例,参考博客:
Photoshop基础教程:混合模式原理篇
颜色减淡的原理讲解以及应用
ps是如何通过最小值获得描边效果的?
图纸转线稿背后的计算机绘图原理
步骤与实现
网上的流程大都分为四个步骤:
- 去色:直接把彩图转成灰度图或者转成HSV/HSL后将饱和度S的值置零
- 反向:将去色后的图像颜色去反,直接用255减
- 滤镜:高斯模糊或者PS里面的最小值滤镜
- 颜色减淡:PS里面叫
color dodge
那么python实现也很方便:
第一步:读图片,转灰度图
img = cv2.imread('./images/zly1.jpg')
# 去掉饱和度
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
第二步:反向,图像就变成了底片色
# 反相
img_inv = 255.0 - img_gray
第三步:高斯模糊或者最小值滤镜
# 高斯模糊
# img_filt = cv2.GaussianBlur(img_inv, ksize=(3, 3),sigmaX=0, sigmaY=0)
# 最小值滤镜
img_filt = np.zeros_like(img_inv,dtype=np.uint8)
radius = 3;
for i in range(radius,img_inv.shape[0]-radius):for j in range(radius,img_inv.shape[1]-radius):img_filt[i,j] = np.min(img_inv[i-radius:i+radius,j-radius:j+radius])
关于高斯模糊或者最小值滤镜的原理,可以看上面的参考博客,实测发现最小值滤镜效果或更好。
第四步:颜色减淡
# color dodge
A = img_gray.astype('float32')
B = img_filt.astype('float32')
img_dodge = A+(A*B)/(255.0-B)
原理在第一篇参考博客,其实就是一个公式,用于混合两组图像。
可视化
plt.figure(figsize=(8,8))
plt.subplot(121)
plt.imshow(img/255.0)
plt.axis('off')
plt.subplot(122)
plt.imshow(img_dodge/255.0,cmap='gray')
plt.axis('off')
我颖美如画…
有兴趣可以自行去按照流程在PS中操作一遍,可以达到一样的效果。
后记
记录一下这个好玩的流程,代码公布在微信公众号简介的github
中,有兴趣或者疑问欢迎关注公众号,私信讨论问题,持续更新骨骼动画、机器学习、图像相关有趣实用的知识点。