正如你可能知道的,素描或创建一个卡通并不总是需要手动完成。如今,许多应用程序可以把你的照片变成卡通照片。但是如果我告诉你,你可以用几行代码创造属于自己的效果呢?
有一个名为OpenCV的库,它为计算机视觉应用程序提供了一个公共基础设施,并优化了机器学习算法。它可以用来识别物体,检测和产生高分辨率的图像。
本文,将向你展示如何利用OpenCV为Python中的图像提供卡通效果。使用google colab来编写和运行代码。你可以在这里访问Google Colab中的完整代码
https://colab.research.google.com/drive/1lV5oJ_hI8PsSV1WDVWWfL18-tMm4vnxe?usp=sharing 要创造卡通效果,我们需要注意两件事:边缘和调色板。这就是照片和卡通的区别所在。为了调整这两个主要部分,我们将经历四个主要步骤:
在开始主要步骤之前,不要忘记导入notebook中所需的库,尤其是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函数,其中包括cv2_imshow 以在Google Colab中加载所选图像。
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对模糊灰度图像进行去噪处理。
模糊值越大,图像中出现的黑色噪声就越少。然后,应用自适应阈值函数,定义边缘的线条尺寸。较大的线条尺寸意味着图像中强调的较厚边缘。
定义函数后,调用它并查看结果。
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\)
有三个参数可根据你的首选项进行调整:
sigmaColor :参数值越大,表示半等色区域越大。sigmaSpace :参数的值越大,意味着更远的像素将相互影响,只要它们的颜色足够接近。4. 结合边缘蒙版和彩色图像 最后一步是将我们之前创建的边缘蒙版与彩色处理图像相结合。为此,请使用cv2.bitwise_and函数。
cartoon = cv2.bitwise\_and\(blurred, blurred, mask=edges\)
我们可以在下面看到原始照片的“卡通版”。
现在你可以开始来创建你自己的卡通效果。除了在我们上面使用的参数中调整值之外,你还可以从OpenCV添加另一个函数来为你的照片提供特殊效果。代码库里还有很多东西我们可以探索。很高兴尝试!
参考文献:
https://www.programcreek.com/python/example/89394/cv2.kmeans http://datahacker.rs/002-opencv-projects-how-to-cartoonize-an-image-with-opencv-in-python/