python实现图片转换成素描和漫画格式

1.背景介绍

在数字图像处理中,图像渲染为素描和漫画是常见的需求。素描是一种黑白绘画,常见的有铅笔素描和碳素素描。漫画是指以卡通或动漫形式表现场景或人物的图画。这种图画通常具有浓郁的画面色彩和形式化的造型风格。Python作为一门全面、跨平台、易用的编程语言,拥有广泛的图像处理库,例如Pillow、OpenCV和Scikit-Image等。这些库提供了强大的图像转换功能,可以让我们快速地把平凡的照片转化为艺术作品。

2.图片转换成素描

2.1 素描的基本原理

素描通常采用了黑白与明暗两个因素来表现图像。在数字图像处理中,我们可以通过以下方法实现素描效果:

将图片灰度化,只保留黑白色彩。

根据像素的亮度值,将图片转换为线条描绘的形式,描绘线条的宽度与亮度值成正比。

在Python中,可以使用Pillow库实现这些操作。

2.2 Pillow库的使用

Pillow是Python的一个第三方图像处理库,可以处理多种图像格式,包括BMP、PNG、JPEG、GIF、WEBP、TIFF等。Pillow的Image模块提供了丰富的图像处理方法,如open()方法用于打开图片,convert()方法用于转换图片格式,show()方法用于显示图片。下面的代码演示了如何使用Pillow将一张图片转换为灰度图:

from PIL import Image

image = Image.open("input.png")

gray_image = image.convert('L')

gray_image.show()

上面的代码中,我们首先通过open()方法打开输入图片,然后使用convert()方法将图片转换为灰度图,并最后使用show()方法将灰度图显示在屏幕上。

2.3 图片的线条描绘

这里,我们需要将图片转换为线条描绘的形式。我们可以使用Scikit-Image库的Sobel边缘检测算法来获取图片的边缘,并使用线条描绘的方式展示。具体操作如下:

将图片转换为灰度图。

使用Sobel算法获取灰度图的边缘。

将边缘转换为线条描绘的形式。

下面的代码演示了如何使用Scikit-Image将一张图片进行线条描绘:

import numpy as np

from skimage import io, feature

# 读取图片并转换为灰度图

image = io.imread("input.png", as_gray=True)

# 计算图片边缘

edges = feature.canny(image)

# 边缘转化为线条描绘的形式

lines = np.zeros_like(image)

line_width = 2

for y in range(edges.shape[0]):

for x in range(edges.shape[1]):

if edges[y, x] == 1:

lines[y-line_width:y+line_width, x-line_width:x+line_width] = 1

io.imshow(lines)

io.show()

上面的代码中,我们通过feature.canny()方法获取灰度图的边缘,并将边缘转换为线条描绘的形式。可以看到,得到的结果是黑底白线的线条描绘图。

2.4 将线条描绘图和原图叠加

我们可以将线条描绘图和原图进行叠加,以实现素描效果。具体操作如下:

将线条描绘图反色。

将反色后的线条描绘图和原图进行亮度叠加。

下面的代码演示了如何使用Pillow实现这些操作:

import numpy as np

from PIL import Image, ImageOps

# 读取图片并转换为灰度图

orig_image = Image.open("input.png")

gray_image = orig_image.convert('L')

# 计算图片边缘

edges = feature.canny(np.array(gray_image))

# 边缘转化为线条描绘的形式

lines = np.zeros_like(gray_image)

line_width = 2

for y in range(edges.shape[0]):

for x in range(edges.shape[1]):

if edges[y, x] == 1:

lines[y-line_width:y+line_width, x-line_width:x+line_width] = 255

# 反色线条描绘图

lines = Image.fromarray(255 - lines)

# 将反色后的线条描绘图和原图进行亮度叠加

temperature = 0.6

output_image = Image.blend(orig_image.convert('L'), lines.convert('L'), temperature)

output_image.show()

上面的代码中,我们使用ImageOps.invert()方法将线条描绘图进行反色,并使用Image.blend()方法将反色后的线条描绘图和原图进行亮度叠加。其中,变量temperature是叠加的比例系数。

3.图片转换成漫画

3.1 漫画的基本原理

与素描不同的是,漫画是一种典型的卡通风格,通常采用了多种色彩,并且造型更加夸张、夸张、形式化和简化。在数字图像处理中,我们可以通过以下方法实现漫画效果:

将图片转换为边缘图,只保留黑白图像。

使用漫画特效,对图像进行平滑、亮度、对比度等调整。

3.2 边缘检测

我们可以使用Scikit-Image库的Canny算法来获取图片的边缘,并使用线条描绘的方式展示。操作如下:

将图片转换为灰度图。

使用Canny算法获取灰度图的边缘。

将边缘转换为线条描绘的形式。

下面的代码演示了如何使用Scikit-Image将一张图片进行边缘检测:

import numpy as np

from skimage import io, feature

# 读取图片并转换为灰度图

image = io.imread("input.png", as_gray=True)

# 计算图片边缘

edges = feature.canny(image)

# 边缘转化为线条描绘的形式

lines = np.zeros_like(image)

line_width = 5

for y in range(edges.shape[0]):

for x in range(edges.shape[1]):

if edges[y, x] == 1:

lines[y-line_width:y+line_width, x-line_width:x+line_width] = 1

io.imshow(lines)

io.show()

上面的代码中,我们通过feature.canny()方法获取灰度图的边缘,并将边缘转换为线条描绘的形式。可以看到,得到的结果是黑底白线的线条描绘图。

3.3 漫画特效

为了实现漫画特效,我们需要对线条描绘图进行一系列的调整。具体操作如下:

对线条描绘图进行高斯模糊。

对线条描绘图进行反色。

将反色后的描绘图与原始图像进行平滑处理,以获取色彩平滑的有机感觉。

调整图像的对比度、亮度等参数。

下面的代码演示了如何使用Pillow库实现这些操作:

import numpy as np

from PIL import Image, ImageOps, ImageFilter

# 读取图片并转换为灰度图

orig_image = Image.open("input.png")

gray_image = orig_image.convert('L')

# 计算图片边缘

edges = feature.canny(np.array(gray_image))

# 边缘转化为线条描绘的形式

lines = np.zeros_like(gray_image)

line_width = 5

for y in range(edges.shape[0]):

for x in range(edges.shape[1]):

if edges[y, x] == 1:

lines[y-line_width:y+line_width, x-line_width:x+line_width] = 255

# 反色线条描绘图

lines = Image.fromarray(255 - lines)

# 图像平滑

smooth_image = np.array(orig_image.filter(ImageFilter.GaussianBlur()).filter(ImageFilter.CONTOUR))

# 图像调整

color_image = Image.fromarray(smooth_image).convert('RGB')

enhancer = ImageOps.colorize(color_image, (0, 0, 0), (255, 255, 255))

enhancer = ImageEnhance.Contrast(enhancer).enhance(1.5)

enhancer = ImageEnhance.Brightness(enhancer).enhance(1.2)

enhancer = ImageEnhance.Sharpness(enhancer).enhance(1.1)

# 合并图像

temperature = 0.4

output_image = Image.blend(enhancer.convert('L'), lines.convert('L'), temperature)

output_image.show()

上面的代码中,我们使用Pillow提供的ImageFilter.GaussianBlur()方法对图像进行高斯模糊,然后调用ImageOps.colorize()方法调整图像的颜色,并使用Pillow提供的ImageEnhance.Contrast()、ImageEnhance.Brightness()和ImageEnhance.Sharpness()方法调整图像对比度、亮度和锐度等参数。

总结

通过本文的介绍,我们了解了如何使用Python和图像处理库将图片转换为素描和漫画效果。具体来说,我们介绍了使用Pillow实现灰度化和亮度叠加,使用Scikit-Image实现边缘检测,以及使用Pillow和Scikit-Image实现漫画特效。在实际应用中,可以根据需要微调参数,获得更加逼真的效果。

后端开发标签