欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(转)照片卡通化

程序员文章站 2022-04-09 09:14:18
...

第1步:减少图像色彩

因为双边滤波器平滑平坦区域同时能保持边缘清晰,所以很适合于将RGB图像转换为卡通。虽然速度好像慢一些一个技巧是重复(例如,通过num_bilateral = 7七次)应用小双边滤波器,而不是只用一次大双边滤波器。

import cv2
 
num_down = 2       # 缩减像素采样的数目
num_bilateral = 7  # 定义双边滤波的数目
 
img_rgb = cv2.imread("img_example.jpg")
 
# 用高斯金字塔降低取样
img_color = img_rgb
for _ in xrange(num_down):
    img_color = cv2.pyrDown(img_color)
 
# 重复使用小的双边滤波代替一个大的滤波
for _ in xrange(num_bilateral):
    img_color = cv2.bilateralFilter(img_color, d=9,
                                    sigmaColor=9,
                                    sigmaSpace=7)
 
# 升采样图片到原始大小
for _ in xrange(num_down):
    img_color = cv2.pyrUp(img_color)

cv2.bilateralFilter中的三个参数控制像素邻域的直径(d)和颜色空间中的滤波器的标准偏差(sigmaColor)以及坐标空间(sigmaSpace)。

第2步:转换为灰度,并使用中值滤波器减少噪点

OpenCV在边缘检测方面提供了多种选择,自适应阈值处理的优点是可以检测图像的每个小领域中最突出的特征,独立于图像的整体属性。

应用中值滤波器减少图像的色彩。将原始的彩色图片转换为灰度图片,接着应用中值模糊来减少灰度图像中的噪声。

# 转换为灰度并使其产生中等的模糊
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)
img_blur = cv2.medianBlur(img_gray, 7)

第3步:创建轮廓

在降噪之后,就可以安全地应用自适应阈值来创建轮廓。 即使存在一些图像噪声,blockSize = 9的cv2.ADAPTIVE_THRESH_MEAN_C算法也会确保将阈值应用于9x9邻域的平均值减去C = 2。
# 检测到边缘并且增强其效果
img_edge = cv2.adaptiveThreshold(img_blur, 255,
                                 cv2.ADAPTIVE_THRESH_MEAN_C,
                                 cv2.THRESH_BINARY,
                                 blockSize=9,
                                 C=2)

第4步:合并轮廓与彩色图片

最后一步是将经处理的彩色图像(img_color)与边缘掩码(img_edge)组合。至此,一个可以卡通化图片的原始代码就写好了。图片效果有点理工的审美,不够文艺,效果上输给了Photoshop,但是在效率上扳回一城。

# 转换回彩色图像
img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB)
img_cartoon = cv2.bitwise_and(img_color, img_edge)
 
# 显示图片
cv2.imshow("cartoon", img_cartoon)
最后将上述代码封装成函数。导入python的os模块来方便文件处理。
# -*- coding: utf-8 -*-

import cv2
import os


def cartoonise(picture_name):

    imgInput_FileName = picture_name
    imgOutput_FileName = "D:\pythonpractice\CartoonImage\cartoon" + picture_name
    num_down = 2         #缩减像素采样的数目
    num_bilateral = 7    #定义双边滤波的数目
    img_rgb = cv2.imread(imgInput_FileName)     #读取图片
    #用高斯金字塔降低取样
    img_color = img_rgb
    for _ in xrange(num_down):
        img_color = cv2.pyrDown(img_color)
    #重复使用小的双边滤波代替一个大的滤波
    for _ in xrange(num_bilateral):
        img_color = cv2.bilateralFilter(img_color,d=9,sigmaColor=9,sigmaSpace=7)
    #升采样图片到原始大小
    for _ in xrange(num_down):
        img_color = cv2.pyrUp(img_color)
    #转换为灰度并且使其产生中等的模糊
    img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)
    img_blur = cv2.medianBlur(img_gray, 7)
    #检测到边缘并且增强其效果
    img_edge = cv2.adaptiveThreshold(img_blur,255,
                                     cv2.ADAPTIVE_THRESH_MEAN_C,
                                     cv2.THRESH_BINARY,
                                     blockSize=9,
                                     C=2)
    #转换回彩色图像
    img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB)
    img_cartoon = cv2.bitwise_and(img_color, img_edge)
    # 保存转换后的图片
    cv2.imwrite(imgOutput_FileName, img_cartoon)


ImageList = []  #建立空的List
#循环读取"D:\pythonpractice\Image"中的文件名
for filename in os.listdir(r"D:\pythonpractice\Image"):   
    ImageList.append(filename)      #将文件名添加到ImageList
for i in ImageList:   #循环读取ImageList中的文件名,将其进行卡通化处理
    print("正在卡通化" + i)
    cartoonise(i)
相关标签: 图片处理