OpenCV实现图片漫画风格特效:边缘提取与颜色填充详解
本文介绍使用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图片漫画相关内容,欢迎查阅本站往期文章或继续浏览后续文章,感谢大家的支持!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













