Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之三 简单卡通漫画风格效果

目录

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之三 简单卡通漫画风格效果

一、简单介绍

二、简单卡通漫画风格效果实现原理

A、边缘蒙版的处理说明:

B、减少原图色调说明

C、缘蒙版与经过颜色处理的图像相结合说明

三、简单卡通漫画风格效果案例实现简单步骤


一、简单介绍

Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。

这里使用 Python  基于 OpenCV 进行视觉图像处理,......

二、简单卡通漫画风格效果实现原理

可能涉及的算法:

  1. 边缘检测: 使用边缘检测算法检测图像中的边缘。常用的边缘检测算法包括 Sobel 算子、Canny 边缘检测算法等。这些算法可以提取图像中的边缘信息,并将边缘信息表示为明暗不同的像素值。

  2. 轮廓增强: 对检测到的边缘进行增强,使得图像中的轮廓更加清晰和突出。可以采用增强对比度、二值化等方法来实现。例如,可以通过增强边缘处的对比度或者二值化边缘图像来突出图像的轮廓。

  3. 颜色增强: 增强图像的色彩,使得图像看起来更加丰富和鲜艳。可以采用调整色相、饱和度和亮度等方法来实现。例如,可以使用直方图均衡化或者颜色映射等技术来增强图像的色彩。

  4. 纹理增强: 增强图像的纹理,使得图像看起来更加生动和有趣。可以采用图像滤波或者纹理合成等方法来实现。例如,可以使用高斯滤波或者双边滤波来平滑图像的纹理,从而减少噪声并增强细节。

A、边缘蒙版的处理说明:

常见的卡通效果强调图像中边缘的厚度。可以通过cv2.adaptiveThreshold() 函数来检测图像中的边缘。可以将egde_mask函数定义为:

def edge_mask(img, line_size, blur_value):
    """
    创建边缘蒙版
    :param img:
    :param line_size:
    :param blur_value:
    :return:
    """
    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来减少模糊的灰度图像的噪点。模糊值越大,意味着图像中出现的黑色噪点越少。

接着,应用adaptiveThreshold函数,定义边缘的线条粗细。线条越粗,意味着图像中强调的边缘越厚。

cv2.adaptiveThreshold() 是 OpenCV 中的一个函数,用于对给定的图像执行自适应阈值处理。阈值处理是一种常用的图像处理技术,用于将图像分割成两个区域,通常是将感兴趣的物体与背景分开。在阈值处理中,像素值与阈值进行比较,如果超过阈值,则被赋予一定的值,否则被赋予另一个值。

在自适应阈值处理中,阈值值不是固定的,而是根据每个像素附近的图像特征局部变化。这可以更好地处理图像中的光照、对比度和噪声等变化。

B、减少原图色调说明

在颜色方面,照片和素描的主要区别是它们各自的颜色数量。素描的颜色比照片少。因此,使用颜色量化来减少照片中的颜色数量。

要进行颜色量化,应用OpenCV库提供的K均值聚类算法。为了在接下来的步骤中使用更方便,可以定义color_quantization函数如下:

def color_quantization(img, k):
    """
    减少图片色调
    :param img:
    :param k: 调整k值来确定想要应用到图像的颜色数量
    :return:
    """
    # 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

C、缘蒙版与经过颜色处理的图像相结合说明

把之前的边缘蒙版与经过颜色处理的图像相结合。做到这一点,需要使用cv2.bitwise_and函数。

def img_and(blurred, edges):
    """
    将边缘蒙版与经过颜色处理的图像相结合
    :param blurred:
    :param edges:
    :return:
    """
    cartoon = cv2.bitwise_and(blurred, blurred, mask=edges)
    return cartoon

cv2.bitwise_and() 是 OpenCV 中的位运算函数之一,用于对两幅二值图像进行按位“与”操作。具体来说,对于每个像素,将两幅输入图像相应位置的像素值分别进行按位“与”运算,输出的结果图像的对应像素值即为这两幅输入图像对应像素值的按位与结果。

dst = cv2.bitwise_and(src1, src2[, mask])

三、简单卡通漫画风格效果案例实现简单步骤

1、编写代码

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之三 简单卡通漫画风格效果-LMLPHP

2、运行结果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之三 简单卡通漫画风格效果-LMLPHP

3、具体代码

"""
卡通漫画风格效果
    1)载入图像
    2)创建边缘蒙版
    3)减少调色板
    4)将边缘蒙版与经过颜色处理的图像结合起来

"""

import cv2
import numpy as np


def read_file(filename):
    """
    读取显示,并返回图片
    :param filename:
    :return:
    """
    img = cv2.imread(filename)
    # 设置窗口属性,并显示图片
    cv2.namedWindow("Dog", cv2.WINDOW_KEEPRATIO)
    cv2.imshow("Dog", img)
    return img


def edge_mask(img, line_size, blur_value):
    """
    创建边缘蒙版
    :param img:
    :param line_size:
    :param blur_value:
    :return:
    """
    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


def color_quantization(img, k):
    """
    减少图片色调
    :param img:
    :param k: 调整k值来确定想要应用到图像的颜色数量
    :return:
    """
    # 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


def color_blur(img, d, sigmaColor, sigmaSpace):
    """
    图像简单模糊处理
    :param img:
    :param d:每个像素邻域的直径
    :param sigmaColor:该参数的值越大,表示半等色的区域越大
    :param sigmaSpace:该参数的值越大,意味着较远的像素只要其颜色足够接近,就会相互影响
    :return:
    """
    blurred = cv2.bilateralFilter(img, d=d, sigmaColor=sigmaColor, sigmaSpace=sigmaSpace)
    return blurred


def img_and(blurred, edges):
    """
    将边缘蒙版与经过颜色处理的图像相结合
    :param blurred:
    :param edges:
    :return:
    """
    cartoon = cv2.bitwise_and(blurred, blurred, mask=edges)
    return cartoon


def main():
    img = read_file("Images/DogFace.jpg")
    edge_img = edge_mask(img, 11, 7)
    color_img = color_quantization(img, 9)
    blurred_color_img = color_blur(color_img, 7, 7, 200)
    cartoon_effect = img_and(blurred_color_img, edge_img)

    # 设置窗口属性,并显示图片
    cv2.namedWindow("cartoon_effect", cv2.WINDOW_KEEPRATIO)
    cv2.imshow("cartoon_effect", cartoon_effect)

    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == "__main__":
    main()

4、一些效果注意事项:

1)参数调整: 不同的图像可能需要不同的参数设置才能达到最佳的漫画效果。因此,在应用漫画效果之前,需要对算法中的参数进行适当的调整和优化。

2)效率问题: 漫画效果的实现可能会消耗较多的计算资源,特别是在处理大尺寸图像时。因此,在实现漫画效果时,需要考虑算法的效率和性能,尽量避免出现卡顿或者内存溢出等问题。

3)效果评估: 在实现漫画效果后,需要对生成的图像进行评估,确保达到了预期的效果。可以通过比较生成图像和原始图像的差异来评估漫画效果的好坏,并进行必要的调整和改进。

03-20 10:03