现在玩图像是很多人的爱好。人们通常点击图片并添加滤镜,或者用不同的东西定制图片并将其发布到社交媒体上。将图像卡通化是一种新的趋势。人们使用不同的应用程序将他们的图像转换为卡通图像。
但是我们是程序员,我们不做普通人做的事情。我们更感兴趣的是将简单的RGB图像转换为卡通图像的过程。在这个图像处理部分,我们将使用OpenCV-Python来卡通化我们的图像。
图像到卡通的转换
那么从图像到卡通的转换,更多的是关于图像边缘的检测。如果你能很好地检测到图像的边缘,那么卡通效果在该图像上就会有效得多。有许多算法可用于此,因此有多种方法可以做到这一点。我们将使用OpenCV-Python中的bilateralFilter()函数。
我通常用Google Colab编写和运行代码。您可以在此处访问Google Colab中的完整代码。在此项目中,我们将完成以下主要步骤:here
我们必须经过这九个步骤才能得到想要的输出。那么,我们开始吧。
步骤1:
import cv2
import numpy as np
import matplotlib.pylab as plt
from google.colab.patches import cv2_imshow
from google.colab import files
步骤2:
def read_file(filename):
image = cv2.imread(filename)
cv2_imshow(image)
return image
如果你在Google Colab上工作,那么你可以写下上面的代码。但是,如果您使用的是Jupyter笔记本,那么只需添加您要使用的图像的路径即可。两者是一回事。
步骤3:
num_down = 2
num_bilateral = 7
w, h, _ = image.shape
初始化我们要使用的参数。NUM_DOWN表示下采样步数。NUM_TABILIARY表示双边过滤步骤的数量。
步骤4:
img_color = np.copy(image)
for _ in range(num_down):
img_color = cv2.pyrDown(img_color)
这里我们正在缩小图像的大小。为了减小尺寸,我们使用了高斯金字塔的下采样操作。我们正在减小图像的大小,以使后续操作更快。
步骤5:
for _ in range(num_bilateral):
img_color = cv2.bilateralFilter(img_color, d=9, sigmaColor=0.1, sigmaSpace=0.01)
这里,sigma Color表示颜色中的过滤sigma,sigma Space表示坐标空间。我们在这里迭代地应用具有小直径值的双边过滤器。参数d表示每个像素的邻域直径。
步骤6:
for _ in range(num_down):
img_color = cv2.pyrUp(img_color)
为了将图像放大到原始大小,我们在这里使用上采样。
步骤7:
img_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
img_blur = cv2.medianBlur(img_gray, 7)
我们正在将步骤6的输出图像转换为灰度图像,并使用称为中值的过滤对图像进行模糊处理。
步骤8:
img_edge = cv2.adaptiveThreshold((255*img_blur).astype(np.uint8), \
255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, \
blockSize=9, C=2)
正如我们上面所讨论的,图像的卡通化更多的是检测图像的边缘。因此,在这一步中,我们要检测并增强我们使用的图像的边缘。
步骤9:
img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB)
img_cartoon = cv2.bitwise_and(img_color, img_edge)
将灰度图像转换回RGB图像,并按位与RGB图像进行AND运算,得到最终输出的卡通图像。
步骤10:
fig = plt.figure(figsize=(20,10))
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)
plt.subplot(121)
plt.imshow(image)
plt.axis('off')
plt.title('Original Image', size=20)
plt.subplot(122)
plt.imshow(img_cartoon)
plt.axis('off')
plt.title('Cartoonized Image', size=20)
最后,显示输出。
卡通形象编码背后的逻辑
在该项目中,我们首先要去除图像的弱边缘,然后将图像转换为平坦的纹理,最后对图像的突出边缘进行增强。为此,我们使用了OpenCV-Python中的bilateralFilter()、medianBlur()、AdaptiveThreshold()和bitwise_and()函数。
为了保持边缘相当锐利和纹理平滑,我们使用了OpenCV-Python中的bilateralFilter()函数。更改sigmaColor和sigmaSpace的值并查看图像输出的变化。
此外,对图像进行下采样以创建图像金字塔。
接下来,我们使用双边滤波器去除不重要的细节,随后使用上采样将图像调整到其原始大小。
最后,为了平坦纹理,首先应用medianBlur,然后用自适应阈值得到的二值图像掩蔽原始图像,
成功执行上述代码后,您将看到输出图像。我试着用小罗伯特·唐尼的形象。我得到了这张输出图像。
这一点都不酷。超酷的。
感谢阅读!!,如果这篇文章对你有帮助,那就拍到你的手流血。
原创文章,作者:fendouai,如若转载,请注明出处:https://panchuang.net/2021/07/26/%e5%9b%be%e5%83%8f%e5%a4%84%e7%90%86%ef%bc%9a%e4%bd%bf%e7%94%a8opencv-python%e5%b0%86%e5%9b%be%e5%83%8f%e5%8d%a1%e9%80%9a%e5%8c%96/