OpenCV实现图片漫画风格特效:边缘提取与颜色填充详解

Finn
Finn
发布时间:2026-10-12 | 2人浏览过
原创

本文介绍使用Python和OpenCV库实现图片漫画风格特效的方法。通过灰度化、中值滤波及自适应阈值二值化提取轮廓,利用图像金字塔降分辨率结合双边滤波简化色彩,最后通过位‘与’运算合并轮廓与颜色,生成具有手绘感的漫画图像。

日常拍摄的照片往往难以达到专业摄影师的水准,因此无论是手机端还是电脑端,都有各类软件提供特效美化功能,部分手机甚至在拍摄时即提供即时美颜效果。然而,针对漫画风格的特效软件较少见,多数情况下只能看到他人制作的成品。出于好奇与探索,笔者尝试自行开发实现该功能,尽管与专业级作品仍有差距,但整体效果令人满意。

本次实现基于OpenCV库,编程语言选用Python。

模仿现实绘画流程,通常先勾勒边缘轮廓以确立整体构图,随后填充颜色以完善画面。在图像处理中,我们采取类似策略:对原始图片进行两次独立处理,分别提取轮廓和简化色彩,最后将两者叠加合成最终图像。

边缘轮廓处理

漫画作品在刻画人物或风景时,细节表现有限,重点在于突出关键特征与特色部分,且细节数量需适度控制。

轮廓提取主要通过四个步骤完成:

import cv2

img = cv2.imread("example.jpg")
img_copy = img

# 灰度处理
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 平滑操作,去除噪声
img_blur = cv2.medianBlur(img_gray, 5)
# 通过阈值提取轮廓
img_edge = cv2.adaptiveThreshold(img_blur,
                 255,
                 cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                 cv2.THRESH_BINARY,
                 blockSize=9,
                 C=3)
# 将灰度图片变成 3 通道,用于后续合并
img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2BGR)

此处采用二值化技术提取轮廓,具体使用自适应阈值二值化函数。该函数基于像素周围小区域确定阈值,从而精准提取出有差异部分的边界,效果类似于漫画中黑色粗体轮廓,且细节处理得当。由于阈值处理仅适用于灰度图像,需先将彩色图像转换为单通道灰度图。此外,为去除对象内部冗余细节,还需对图像进行平滑处理,使颜色过渡更加平缓。漫画中的色彩应用通常不如现实生活复杂,经过上述处理得到的轮廓效果更佳。

处理效果如下:


与原图对比:


以下介绍两个关键方法:

中值滤波:cv2.medianBlur(img, ksize) 主要关注后续参数,即内核区域的边长,该值必须为大于1的奇数,例如3、5、7等。该方法提取内核区域内所有像素的中值,并将中心元素替换为该中值。

自适应阈值二值化:cv2.adaptiveThreshold(src, maxval, thresh_type, type, Block Size, C)

  • src:输入图像,仅支持单通道图像,通常为灰度图。
  • dst:输出图像。
  • maxval:当像素值超过阈值(或低于阈值,具体取决于type参数)时赋予的值。
  • thresh_type:阈值计算方法,包含两种类型:cv2.ADAPTIVE_THRESH_MEAN_C;cv2.ADAPTIVE_THRESH_GAUSSIAN_C。
  • type:二值化操作类型,与固定阈值函数相同,包含以下5种类型:cv2.THRESH_BINARY;cv2.THRESH_BINARY_INV;cv2.THRESH_TRUNC;cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV。
  • Block Size:图像分块的大小。
  • C:阈值计算方法中的常数项。

颜色填充处理

在描绘好边缘轮廓后,添加色彩即可使图像完整。此步骤相对简单,主要目的是降低原图片的色彩细致度。

具体代码如下:

for _ in range(2)
	# 降低分辨率
  img_copy = cv2.pyrDown(img_copy)
for _ in range(5):
	# 图像平滑,保留边缘
  img_copy = cv2.bilateralFilter(img_copy, d=9, sigmaColor=9, sigmaSpace=7)
img_copy = cv2.resize(img_copy, (img.shape[1], img.shape[0]),
            interpolation=cv2.INTER_CUBIC)

漫画色彩需较为平滑,避免现实生活中的过度细腻。首先采用图像金字塔降低分辨率,随后使用双边滤波去除噪声,这既能平滑平面区域,又能保持边缘清晰。由于分辨率降低导致图像尺寸变小,最后需将图像放大至原始尺寸。虽然图像金字塔提供专门的放大方法,但可能导致尺寸出现微小偏差。为确保合并过程中两幅图像尺寸完全一致,此处直接按尺寸进行放大处理。

颜色填充效果如下:

以下介绍两个关键方法:

分辨率降低:cv2.pyrDown(src, dst=None, dstsize=None, borderType=None) 通常只需输入图像,该方法会直接将图像的长宽减半。

双边滤波:cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])

  • src:输入图像。
  • d:过滤时周围每个像素邻域的直径。
  • sigmaColor:颜色空间中的过滤sigma参数。该参数越大,远处邻近像素混合程度越高。
  • sigmaSpace:坐标空间中的过滤sigma参数。该参数越大,颜色足够相近的像素影响范围越大。

图像合并

img_cartoon = cv2.bitwise_and(img_copy, img_edge)
cv2.imshow("cartoon", img_cartoon)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.bitwise_and() 对二进制数据执行“与”操作,即对图像(支持灰度或彩色)的每个像素值进行二进制“与”运算:1&1=1,1&0=0,0&1=0,0&0=0。

最终结果展示:

至此,关于OpenCV实现图片漫画风格特效的示例介绍完毕。如需了解更多OpenCV图片漫画相关内容,欢迎查阅本站往期文章或继续浏览后续文章,感谢大家的支持!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表