这是我参与8月更文挑战的第14天
前言
利用Python与一些图像处理技术将照片卡通化,让我们愉快地开始吧~
开发工具
Python版本: 3.6.4
相关模块:
cv2模块;
numpy模块;
以及一些Python自带的模块。
环境搭建
安装Python并添加到环境变量,pip安装需要的相关模块即可。
原理简介
一. 方案一
Step1:
利用双边滤波器对原图像进行保边去噪处理;
代码如下:
'''
Step1: 利用双边滤波器对原图像进行保边去噪处理
'''
img_bilateral = img
# 下采样
for _ in range(2):
img_bilateral = cv2.pyrDown(img_bilateral)
# 进行多次的双边滤波
# 参数含义(依次):原始图像、邻域直径、空间高斯函数标准差,灰度值相似性标准差
for _ in range(7):
img_bilateral = cv2.bilateralFilter(img_bilateral, d=9, sigmaColor=9, sigmaSpace=7)
# 上采样
for _ in range(2):
img_bilateral = cv2.pyrUp(img_bilateral)
复制代码
效果如下:
Step2:
将步骤一中获得的图像灰度化后,使用中值滤波器去噪;
代码如下:
'''
Step2: 将步骤一中获得的图像灰度化后,使用中值滤波器去噪
'''
img_gray = cv2.cvtColor(img_bilateral, cv2.COLOR_RGB2GRAY)
img_median = cv2.medianBlur(img_gray, 7)
复制代码
效果如下:
Step3:
对步骤二中获得的图像使用自适应阈值从而获得原图像的轮廓;
代码如下:
Step3: 对步骤二中获得的图像使用自适应阈值从而获得原图像的轮廓
'''
# 参数含义(依次): 原始图像、像素上限值、自适应方法、赋值方法、邻域大小、常数
img_edge = cv2.adaptiveThreshold(img_median,
255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY,
blockSize=9,
C=2)
# 转回RGB方便合并
img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB)
复制代码
效果如下:
Step4:
将步骤一中获得的图像与步骤三中获得的图像轮廓合并即可实现将照片变为卡通图片的效果了。
代码如下:
'''
Step4: 将步骤一中获得的图像与步骤三中获得的图像轮廓合并即可实现将照片变为卡通图片的效果了
'''
img_cartoon = cv2.bitwise_and(img_bilateral, img_edge)
cv2.imwrite(os.path.join(savepath, savename), img_cartoon)
# cv2.imshow('cartoonise', img_cartoon)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
复制代码
效果如下:
方案二
Step1:
图像从BGR空间转HSV空间,在HSV空间进行直方图均衡化、中值滤波和形态学变换。
代码如下:
'''
步骤一: 图像BGR空间转HSV空间,在HSV空间进行直方图均衡化、中值滤波和形态学变换
'''
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(img_hsv)
# 直方图均衡化
v = cv2.equalizeHist(v)
img_hsv = cv2.merge((h, s, v))
# 中值滤波
img_hsv = cv2.medianBlur(img_hsv, 7)
# 形态学变换-开/闭运算
kernel = np.ones((5, 5), np.uint8)
# img_hsv = cv2.morphologyEx(img_hsv, cv2.MORPH_OPEN, kernel, iterations=3)
img_hsv = cv2.morphologyEx(img_hsv, cv2.MORPH_CLOSE, kernel, iterations=2)
# 中值滤波
img_hsv = cv2.medianBlur(img_hsv, 7)
复制代码
效果如下:
Step2:
对步骤一中获得的图像使用自适应阈值从而获得原图像的轮廓。
代码如下:
'''
步骤二: 对步骤一中获得的图像使用自适应阈值从而获得原图像的轮廓
'''
img_mask = cv2.cvtColor(img_hsv, cv2.COLOR_HSV2BGR)
img_mask = cv2.cvtColor(img_mask, cv2.COLOR_RGB2GRAY)
img_mask = cv2.medianBlur(img_mask, 7)
img_edge = cv2.adaptiveThreshold(img_mask,
255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY,
blockSize=9,
C=2)
img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB)
复制代码
效果如下:
Step3:
将步骤二中获得的图像轮廓与原图像合并即可实现将照片变为卡通图片的效果了。
代码如下:
'''
步骤三: 将步骤二中获得的图像轮廓与原图像合并即可实现将照片变为卡通图片的效果了
'''
img_cartoon = cv2.bitwise_and(img, img_edge)
cv2.imwrite(os.path.join(savepath, savename), img_cartoon)
复制代码
效果如下:
换成闭运算的效果是这样的:
文章到这里就结束了,感谢你的观看,下个分享Python实现一波刮刮卡效果。
为了感谢读者们,我想把我最近收藏的一些编程干货分享给大家,回馈每一个读者,希望能帮到你们。
干货主要有:
① 2000多本Python电子书(主流和经典的书籍应该都有了)
② Python标准库资料(最全中文版)
③ 项目源码(四五十个有趣且经典的练手项目及源码)
④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)
⑤ Python学习路线图(告别不入流的学习)
All done~详见个人主页简介获取完整源代码。。




近期评论