利用 Python 让图像变卡通

欢迎关注 “小白玩转Python”,发现更多 “有趣”

引言

正如你可能知道的,素描或创作卡通并不总是需要手动完成。现在,许多应用程序可以把你的照片变成卡通。但是如果我告诉你,你可以用几行代码来完成你自己想要的效果呢?

有一个叫做 OpenCV 的库,它为计算机视觉应用程序提供了一些通用的函数,并具有优化的机器学习算法。它可以用来识别物体,检测,并创建高分辨率的图像。

在本教程中,我将向您展示如何利用 OpenCV 为 Python 中的图像创建卡通效果。我用 Google Colab 编写并运行代码。你可以在这里访问 Google Colab 的完整代码(https://colab.research.google.com/drive/1lV5oJ_hI8PsSV1WDV

WWfL18-tMm4vnxe?usp=sharing)。

要创造卡通效果,我们需要注意两件事: 边缘和调色板。这就是照片和卡通的不同之处。为了调整这两个主要组成部分,我们将经历四个主要步骤:

  1. 加载图像

  2. 创建边缘

  3. 减少调色板

  4. 将边缘掩模与彩色图像结合

在进入主要步骤之前,不要忘记在代码中导入所需的库,特别是 cv2和 NumPy 两个库。

import cv2
import numpy as np


# required if you use Google Colab
from google.colab.patches import cv2_imshow
from google.colab import files

1. 加载图片

第一个主要步骤是加载图像。定义 read_file 函数,其中包括在 Google Colab 中通过 cv2.imshow 函数加载我们选择的图片。

def read_file(filename):
  img = cv2.imread(filename)
  cv2_imshow(img)
  return img

调用创建的函数来加载图像。

uploaded = files.upload()
filename = next(iter(uploaded))
img = read_file(filename)

我选择了下面的图片进行卡通转换。

2. 创建边缘掩模

通常,卡通效果强调图像边缘的宽度。我们可以使用 cv2.adaptiveThreshold()函数检测图像的边缘。

总的来说,我们可以将 egde_mask 函数定义为:

def edge_mask(img, line_size, blur_value):
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  gray_blur = cv2.medianBlur(gray, blur_value)
  edges = cv2.adaptiveThreshold(gray_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, line_size, blur_value)
  return edges

在这个函数中,我们先将图像转换为灰度图像。然后,利用 cv2.medianBlur 函数对模糊灰度图像进行去噪处理。模糊值越大,图像中出现的黑噪声越少。然后,应用 adaptiveThreshold 函数,并定义边缘的线条大小。更大的线条尺寸意味着更宽的边缘,这将在图像中得到展示。

定义函数之后,调用它并查看结果。

line_size = 7
blur_value = 7
edges = edge_mask(img, line_size, blur_value)
cv2_imshow(edges)

3. 减少调色板

照片和绘画的主要区别(就颜色而言)在于每张照片中不同颜色的数量,其中绘画的图像的颜色比照片少。因此,我们使用量化的方式来减少照片中的颜色数量。

量化

为了实现这个图像量化,我们应用了 OpenCV 库提供的 K-Means 算法。为了使下一步更容易,我们可以定义 color_quantization 函数如下。

def color_quantization(img, k):
# Transform the image
  data = np.float32(img).reshape((-1, 3))


# Determine criteria
  criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.001)


# Implementing K-Means
  ret, label, center = cv2.kmeans(data, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
  center = np.uint8(center)
  result = center[label.flatten()]
  result = result.reshape(img.shape)
  return result

我们可以调整 k 值来确定我们想要应用到图像的颜色数量。

total_color = 9
img = color_quantization(img, total_color)

在本例中,我使用了9作为图像的 k 值。

双边滤波器

做完图像量化后,我们可以通过使用双边滤波器来降低图像中的噪声。这会给图像带来一点模糊和锐度降低的效果。

blurred = cv2.bilateralFilter(img, d=7, sigmaColor=200,sigmaSpace=200)

你可以根据自己的喜好调整以下三个参数:

  • d:每个像素邻域的直径

  • sigmaColor:颜色空间滤波器的sigma值。这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。

  • sigmaSpace:坐标空间中滤波器的sigma值,坐标空间的标注方差。他的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。

4. 将边缘掩模和彩色图像结合起来

最后一步是将我们前面创建的边缘掩模与经过颜色处理的图像结合起来。为此,可以使用 cv2.bitwise_and 函数。

cartoon = cv2.bitwise_and(blurred, blurred, mask=edges)

我们可以看到下面原始照片的“卡通版”:

总结

现在你可以开始编写代码了,给自己的图像创建卡通效果。除了使用上面我们使用的参数值之外,还可以适当调整一下,看会不会有一些特殊效果。

·  END  ·

HAPPY LIFE

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值