深入了解Python和OpenCV:图像的卡通风格化
前言
当今数字时代,图像处理和美化已经变得非常普遍。从社交媒体到个人博客,人们都渴望分享独特且引人注目的图片。本文将介绍如何使用Python编程语言和OpenCV库创建令人印象深刻的卡通风格图像。卡通风格的图像具有艺术性和创意,它们可以用于图像编辑、创意表达以及增加娱乐价值。
文章目录
- 前言
- 1. 准备工作
- 2. 读取和显示图像
- 3. 创建边缘掩膜
- 4. 颜色量化
- 5. 图像处理和效果增强
- 6. 完整代码
- 总结
1. 准备工作
在开始之前,您需要安装以下必要的库:
- OpenCV (cv2)
- NumPy
如果您还没有安装这些库,可以使用pip进行安装。
pip install opencv-python numpy
2. 读取和显示图像
首先,我们将介绍如何使用OpenCV读取图像文件并在窗口中显示它们。这是我们处理图像的第一步。
# 读取文件
def read_file(filename: str) -> np.ndarray:try:img = cv2.imread(filename)if img is None:raise ValueError("Invalid file path or file format.")return imgexcept:raise ValueError("Invalid file path or file format.")# 显示图片
def display_image(img: np.ndarray, window_name: str) -> None:cv2.imshow(window_name, img)cv2.waitKey()
在这个步骤中,我们定义了一个名为read_file的函数,它接受一个文件名作为参数,并返回一个NumPy数组表示的图像。如果文件路径无效或图像格式不受支持,函数将引发异常。
我们定义了一个名为display_image的函数,它接受两个参数:要显示的图像和窗口的名称。函数将图像显示在指定的窗口中,并等待用户按下任意键后关闭窗口。这个简单的步骤允许我们在进行后续处理之前,查看原始照片的外观。
3. 创建边缘掩膜
接下来,我们将图像转化为卡通风格的第一步是创建边缘掩膜。我们将使用边缘检测技术来实现这一目标。
# 边缘掩膜
def edge_mask(image: np.ndarray, line_size: int, blur_value: int) -> np.ndarray:if not isinstance(line_size, int) or not isinstance(blur_value, int) or line_size < 1 or blur_value < 1:raise ValueError("Invalid value for 'line_size' or 'blur_value' parameter. Must be a positive integer.")gray = cv2.cvtColor(image, 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
在这个步骤中,我们定义了一个名为edge_mask的函数,它接受三个参数:图像、线条大小(控制边缘粗细)和模糊程度。函数将图像转换为灰度图,然后应用中值模糊和自适应阈值处理,以创建边缘掩膜。
4. 颜色量化
卡通风格的图像通常具有较少的颜色。我们将使用K-Means聚类算法来减少图像中的颜色数量。
# 颜色量化
def color_quantization(image: np.ndarray, num_colors: int) -> np.ndarray:if not isinstance(num_colors, int) or num_colors < 1:raise ValueError("Invalid value for 'num_colors' parameter. Must be a positive integer.")# 转换图片data = np.float32(image).reshape((-1, 3))# 设置KMeans聚类参数kmeans_criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.001)flags = cv2.KMEANS_RANDOM_CENTERS# 执行KMeans聚类_, labels, centers = cv2.kmeans(data, num_colors, None, kmeans_criteria, 10, flags)centers = np.uint8(centers)processed_image = centers[labels.flatten()]processed_image = processed_image.reshape(image.shape)# 应用颜色增强hsv_image = cv2.cvtColor(processed_image, cv2.COLOR_BGR2HSV)hsv_image[:, :, 1] = hsv_image[:, :, 1] * 1.5 # 增强饱和度enhanced_image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR)return enhanced_image
在这个步骤中,我们定义了一个名为color_quantization的函数,它接受两个参数:图像和要使用的颜色数量。函数首先将图像转换为数据矩阵,然后使用K-Means聚类算法将图像颜色量化为指定数量的颜色。最后,我们增强了图像的饱和度,以使颜色更加生动。
5. 图像处理和效果增强
在这一步骤中,我们将应用一些图像处理技术,如双边滤波,以增强最终的卡通效果图像。
def resize_crop(image):h, w, c = np.shape(image)if min(h, w) > 720:if h > w:h, w = int(720 * h / w), 720else:h, w = 720, int(720 * w / h)image = cv2.resize(image, (w, h), interpolation=cv2.INTER_AREA)h, w = (h // 8) * 8, (w // 8) * 8image = image[:h, :w, :]return image# 图像处理和效果增强
def cartoonize(load_folder, save_folder):name_list = os.listdir(load_folder)for name in name_list:try:load_path = os.path.join(load_folder, name)save_path = os.path.join(save_folder, name)if not save_path.endswith('.jpg'):raise ValueError("Invalid file format. Must be a '.jpg' file.")image = cv2.imread(load_path)image = resize_crop(image)display_image(image, "Image")# 设置边缘掩膜参数并应用line_size = 7blur_value = 7edges = edge_mask(image, line_size, blur_value)display_image(edges, "Edges")# 执行颜色量化num_colors = 9processed_image = color_quantization(image, num_colors)display_image(processed_image, "Processed_image")# 应用双边滤波blurred = cv2.bilateralFilter(processed_image, d=9, sigmaColor=200, sigmaSpace=200)display_image(blurred, "Blurred")# 应用掩膜cartoonized_image = cv2.bitwise_and(blurred, blurred, mask=edges)display_image(cartoonized_image, "Cartoonized Image")cv2.imwrite(save_path, cartoonized_image)except:print('cartoonize {} failed'.format(load_path))
在这个步骤中,我们首先调整图像的大小和裁剪,以确保它符合处理的要求。然后,我们依次应用边缘掩膜、颜色量化、双边滤波和最后的掩膜应用,将图像转换成卡通画风。
这是整个卡通化过程的关键部分,通过这些步骤,您可以将任何普通照片转换成具有卡通风格的艺术品。在接下来的文章中,我们将展示如何使用这些代码来卡通化您自己的照片。
6. 完整代码
# -*- coding = utf-8 -*-
"""
# @Time : 2023/9/22 20:18
# @Author : FriK_log_ff 374591069
# @File : newmyway.py
# @Software: PyCharm
# @Function: 请输入项目功能
"""
import cv2
import numpy as np
import os# 读取文件
def read_file(filename: str) -> np.ndarray:try:img = cv2.imread(filename)if img is None:raise ValueError("Invalid file path or file format.")return imgexcept:raise ValueError("Invalid file path or file format.")# 显示图片
def display_image(img: np.ndarray, window_name: str) -> None:cv2.imshow(window_name, img)cv2.waitKey()# 边缘掩膜
def edge_mask(image: np.ndarray, line_size: int, blur_value: int) -> np.ndarray:if not isinstance(line_size, int) or not isinstance(blur_value, int) or line_size < 1 or blur_value < 1:raise ValueError("Invalid value for 'line_size' or 'blur_value' parameter. Must be a positive integer.")gray = cv2.cvtColor(image, 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(image: np.ndarray, num_colors: int) -> np.ndarray:if not isinstance(num_colors, int) or num_colors < 1:raise ValueError("Invalid value for 'num_colors' parameter. Must be a positive integer.")# 转换图片data = np.float32(image).reshape((-1, 3))# 设置KMeans聚类参数kmeans_criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.001)flags = cv2.KMEANS_RANDOM_CENTERS# 执行KMeans聚类_, labels, centers = cv2.kmeans(data, num_colors, None, kmeans_criteria, 10, flags)centers = np.uint8(centers)processed_image = centers[labels.flatten()]processed_image = processed_image.reshape(image.shape)# 应用颜色增强hsv_image = cv2.cvtColor(processed_image, cv2.COLOR_BGR2HSV)hsv_image[:, :, 1] = hsv_image[:, :, 1] * 1.5 # 增强饱和度enhanced_image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR)return enhanced_imagedef resize_crop(image):h, w, c = np.shape(image)if min(h, w) > 720:if h > w:h, w = int(720 * h / w), 720else:h, w = 720, int(720 * w / h)image = cv2.resize(image, (w, h), interpolation=cv2.INTER_AREA)h, w = (h // 8) * 8, (w // 8) * 8image = image[:h, :w, :]return image# 上传文件
def cartoonize(load_folder, save_folder):name_list = os.listdir(load_folder)for name in name_list:try:load_path = os.path.join(load_folder, name)save_path = os.path.join(save_folder, name)if not save_path.endswith('.jpg'):raise ValueError("Invalid file format. Must be a '.jpg' file.")image = cv2.imread(load_path)image = resize_crop(image)display_image(image, "Image")# 设置边缘掩膜参数并应用line_size = 7blur_value = 7edges = edge_mask(image, line_size, blur_value)display_image(edges, "Edges")# 执行颜色量化num_colors = 9processed_image = color_quantization(image, num_colors)display_image(processed_image, "Processed_image")# 应用双边滤波blurred = cv2.bilateralFilter(processed_image, d=9, sigmaColor=200, sigmaSpace=200)display_image(blurred, "Blurred")# 应用掩膜cartoonized_image = cv2.bitwise_and(blurred, blurred, mask=edges)display_image(cartoonized_image, "Cartoonized Image")cv2.imwrite(save_path, cartoonized_image)except:print('cartoonize {} failed'.format(load_path))if __name__ == '__main__':load_folder = 'test_images'save_folder = 'cartoonized_images'if not os.path.exists(save_folder):os.mkdir(save_folder)cartoonize(load_folder, save_folder)
总结
在本文中,我们探讨了如何使用Python和OpenCV库创建卡通风格的图像。通过一系列图像处理步骤,我们将普通照片转化为有趣和具有创意的卡通风格图像。这个过程涵盖了图像读取、边缘检测、颜色量化、图像处理和效果增强等关键步骤。
卡通风格图像的制作涉及多个步骤,但通过掌握这些技巧,您可以自由发挥创造力,为照片增添新的趣味性。以下是本文中使用的一些关键技术的简要回顾:
-
图像读取和显示: 我们使用OpenCV库来读取图像文件并在窗口中显示它们。这是开始图像处理的第一步。
-
边缘掩膜: 为了创建卡通风格,我们使用了边缘检测技术,将图像中的边缘突出显示。
-
颜色量化: 卡通图像通常包含较少的颜色。我们使用K-Means聚类来减少图像中的颜色数量,从而实现卡通风格的色彩。
-
图像处理和效果增强: 我们应用了一些图像处理技术,例如双边滤波,以增强最终的卡通效果图像。
在完成所有处理步骤后,我们得到了有趣和独特的卡通风格图像。这个过程可以批量处理图像,使您能够轻松创建多个卡通化的照片。
希望本文对您有所帮助,能够启发您探索更多有趣的图像处理项目。 创造自己独特的卡通风格图像,让您的照片在社交媒体和网络上脱颖而出。
相关文章:
深入了解Python和OpenCV:图像的卡通风格化
前言 当今数字时代,图像处理和美化已经变得非常普遍。从社交媒体到个人博客,人们都渴望分享独特且引人注目的图片。本文将介绍如何使用Python编程语言和OpenCV库创建令人印象深刻的卡通风格图像。卡通风格的图像具有艺术性和创意,它们可以用…...
【算法挨揍日记】day06——1004. 最大连续1的个数 III、1658. 将 x 减到 0 的最小操作数
1004. 最大连续1的个数 III 1004. 最大连续1的个数 III 题目描述: 给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。 解题思路: 首先题目要我们求出的最多翻转k个0后&#x…...
华为云HECS安装docker
1、运行安装指令 yum install docker都选择y,直到安装成功 2、查看是否安装成功 运行版本查看指令,显示docker版本,证明安装成功 docker --version 或者 docker -v 3、启用并运行docker 3.1启用docker 指令 systemctl enable docker …...
力扣669 补9.16
最近大三上四天有早八,真的是受不了了啊,欧嗨呦,早上困如狗,然后,下午困如狗,然后晚上困如狗,尤其我最近在晚上7点到10点这个时间段看力扣,看得我昏昏欲睡,不自觉就睡了1…...
2023-9-22 没有上司的舞会
题目链接:没有上司的舞会 #include <cstring> #include <iostream> #include <algorithm>using namespace std;const int N 6010;int n; int happy[N]; int h[N], e[N], ne[N], idx; bool has_father[N];// 两个状态,选该节点或不选该…...
【HDFS】cachingStrategy的设置
org.apache.hadoop.hdfs.client.impl.BlockReaderFactory#getRemoteBlockReader: private BlockReader getRemoteBlockReader(Peer peer) throws IOException {int networkDistance = clientContext.getNetworkDistance(datanode);return BlockReaderRemote...
性能测试 —— 性能测试常见的测试指标 !
一、什么是性能测试 先看下百度百科对它的定义,性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。 我们可以认为性能测试是:通过在测试环境下对系统或构件的性能进行探测,用以验证在生产环…...
【学习草稿】背包问题
一、01背包问题 图解详细解析 (转载) https://blog.csdn.net/qq_37767455/article/details/99086678 :Vi表示第 i 个物品的价值,Wi表示第 i 个物品的体积,定义V(i,j):当前背包容量 j,前 i 个物…...
doxygen c++ 语法
c基本语法模板 以 /*! 开头, */ 结尾 /*!\关键字1\关键字2 */1 文件头部信息 /*! \file ClassA.h* \brief 文件说明 定义了类fatherA* \details This class is used to demonstrate a number of section commands.* \author John Doe* \author Jan Doe* \v…...
ChatGLM微调基于P-Tuning/LoRA/Full parameter(上)
1. 准备环境 首先必须有7个G的显存以上,torch >= 1.10 需要根据你的cuda版本 1.1 模型下载 $ git lfs install $ git clone https://huggingface.co/THUDM/chatglm-6b1.2 docker环境搭建 环境搭建 $ sudo docker pull slpcat/chatglm-6b:latest $ sudo docker run -it …...
BLE Mesh蓝牙mesh传输大数据包传输文件照片等大数据量通讯
1、BLE Mesh数据传输现状 BLE Mesh网络技术是低功耗蓝牙的一个进阶版,Mesh扩大了蓝牙在应用中的规模和范围,因为它同时支持超过三万个网络节点,可以跨越大型建筑物,不仅可以使得医疗健康应用更加方便快捷,还能监测像学…...
9.18 QT作业
mainwindow.h QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACEclass MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();signals:void jump(); //自定义跳转信号函数private slots:vo…...
【100天精通Python】Day67:Python可视化_Matplotlib 绘动画,2D、3D 动画 示例+代码
1 绘制2D动画(animation) Matplotlib是一个Python绘图库,它提供了丰富的绘图功能,包括绘制动画。要绘制动画,Matplotlib提供了FuncAnimation类,允许您创建基于函数的动画。下面是一个详细的Matplotlib动画示…...
Linux内核源码分析 (B.x)Linux页表的映射
Linux内核源码分析 (B.x)Linux页表的映射 文章目录 Linux内核源码分析 (B.x)Linux页表的映射一、ARM32页表1、页表术语2、虚拟地址到物理地址转换3、一级页表项4、二级页表项 二、ARM64页表1、ARMv8-A架构2、4KB大小页4级映射 三、Linux内核中关于页表的函数和宏1、查询页表2、…...
机器学习(15)---代价函数、损失函数和目标函数详解
文章目录 一、各自定义二、各自详解三、代价函数和损失函数区别四、例题理解 一、各自定义 1. 代价函数:代价函数(Cost Function)是定义在整个训练集上的,是所有样本误差的平均,也就是损失函数的平均。它用于衡量模型在…...
计算机专业大学规划之双非
亲爱的计算机专业大一学弟学妹们,欢迎来到充满挑战和机遇的大学校园!在经历了小半年的大学生活后,是否会对自己的未来感到一些迷茫,借着前几天给我大一的妹妹聊天的机会,我想发表一下关于我的建议(仅限个…...
2.策略模式
UML图 代码 main.cpp #include "Strategy.h" #include "Context.h"void test() {Context* pContext nullptr;/* StrategyA */pContext new Context(new StrategyA());pContext->contextInterface();/* StrategyB */pContext new Context(new Strat…...
算法通过村第七关-树(递归/二叉树遍历)黄金笔记|迭代遍历
文章目录 前言1. 迭代法实现前序遍历2. 迭代法实现中序遍历3. 迭代法实现后序遍历总结 前言 提示:在一个信息爆炸却多半无用的世界,清晰的见解就成了一种力量。 --尤瓦尔赫拉利《今日简史》 你是不是觉得上一关特别简单,代码少,背…...
MySQL数据库简介+库表管理操作+数据库用户管理
Mysql Part 1 一、数据库的基本概念1.1 使用数据库的必要性1.2 数据库基本概念1.2.1 数据(Data)1.2.2 表1.2.3 数据库1.2.4 数据库管理系统(DBMS)1.2.5 数据库系统 1.3 数据库的分类1.3.1 关系数据库 SQL1.3.2 非关系数据库 NoSQL…...
PyTorch实战:卷积神经网络详解+Python实现卷积神经网络Cifar10彩色图片分类
目录 前言 一、卷积神经网络概述 二、卷积神经网络特点 卷积运算 单通道,二维卷积运算示例 单通道,二维,带偏置的卷积示例 带填充的单通道,二维卷积运算示例 Valid卷积 Same卷积 多通道卷积计算 1.局部感知域 2.参数共…...
MapRdeuce工作原理
hadoop - (三)通俗易懂地理解MapReduce的工作原理 - 个人文章 - SegmentFault 思否 MapReduce架构 MapReduce执行过程 Map和Reduce工作流程 (input) ->map-> ->combine-> ->reduce-> (output) Map: Reduce...
完整指南:使用JavaScript从零开始构建中国象棋游戏
引言 中国象棋,又被称为国际象棋,是一款起源于中国的古老棋类游戏。本文旨在为大家提供一个简单明了的步骤,教你如何使用JavaScript从零开始构建这款经典的棋类游戏。 1. 游戏简介 在中国象棋中,两方各有一军队,包括…...
PG-DBA培训19:PostgreSQL高可用集群项目实战之Patroni
一、风哥PG-DBA培训19:PostgreSQL高可用集群项目实战之Patroni 课程目标: 本课程由风哥发布的基于PostgreSQL数据库的系列课程,本课程属于PostgreSQL主从复制与高可用集群阶段之PostgreSQL高可用集群项目实战之Patroni,学完本课…...
数据库管理-第105期 安装Database Valut组件(20230919)
数据库管理-第105期 安装Database Valut组件(20230919) 之前无论是是EXPDP还是PDB中遇到的一些问题,其实都跟数据库的DV(Database Valut)组件有关,因为目标库没有安装DV导致启动时会出现问题。 1 DV/OLS …...
企望制造ERP系统RCE漏洞 复现
文章目录 企望制造ERP系统RCE漏洞 复现0x01 前言0x02 漏洞描述0x03 影响平台0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 企望制造ERP系统RCE漏洞 复现 0x01 前言 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播…...
【unity小技巧】Unity 存储存档保存——PlayerPrefs、JsonUtility和MySQL数据库的使用
文章目录 前言PlayerPrefs一、基本介绍二、Demo三、优缺点 JsonUtility一、基本使用二、Demo三、优缺点 Mysql(扩展)完结 前言 游戏存档不言而喻,是游戏设计中的重要元素,可以提高游戏的可玩性,为玩家提供更多的自由和…...
2023-9-22 滑雪
题目链接:滑雪 #include <cstring> #include <algorithm> #include <iostream>using namespace std;const int N 310;int n, m; int h[N][N]; int f[N][N];int dx[4] {-1, 0, 1, 0}, dy[4] {0, 1, 0, -1};int dp(int x, int y) {int &v f…...
基于Yolov8的工业小目标缺陷检测(6):多检测头结合小缺陷到大缺陷一网打尽的轻量级目标检测器GiraffeDet,暴力提升工业小目标缺陷检测能力
💡💡💡本文改进:多头检测器结合大小缺陷一网打尽的GiraffeDet,进一步提升处理低分辨率图像和小物体等更困难的检测能力。 多头检测器+ GiraffeDet | 亲测在工业小目标缺陷涨点明显,原始mAP@0.5 0.679提升至0.734 收录专栏: 💡💡💡深度学习工业缺陷检测 :h…...
exe文件运行后无输出直接闪退如何找解决办法
一.搜索栏搜事件查看器 二.点开windows日志下的应用程序 三.找到错误处 四.搜索异常代码 点开有错误的详细信息,直接用搜索引擎搜索这个异常代码能大致判断是什么问题,给了一个解决思路,不至于不知道到底哪里出了问题...
OpenHarmony应用开发—ArkUI组件集合
介绍 本示例为ArkUI中组件、通用、动画、全局方法的集合。 效果预览 使用说明: 1.点击组件、通用、动画、全局方法四个按钮或左右滑动切换不同视图。 2.点击二级导航(如通用属性、通用事件等),若存在三级导航则展开三级导航&#…...
服务器域名是什么?/seo推广排名平台有哪些
小A是一个中度强迫症患者,每次做数组有关的题目都异常难受,他十分希望数组的每一个元素都一样大,这样子看起来才是最棒的,所以他决定通过一些操作把这个变成一个看起来不难受的数组,但他又想不要和之前的那个数组偏差那么大,所以他每次操作只给这个数组的其中n-1个元素加1, 输入…...
asp+sql server典型网站建设案例 光盘/最新旅游热点
如果不看glibc的代码,那么也许你永远也不知道什么叫境界,仅仅认为简单的可读性强的代码就是最好的代码的人也一定停留在应届毕业生的水平,程序很大意义上是给机器看的而不是给人看的,人看程序很大意义上是维护和经验学习ÿ…...
东莞网页制作招聘信息/怎样优化网站
一、 QT内置的ICON资源保存在QStyle类里。 可以通过成员函数 QStyle::standardIcon 来获取。 保存的icon有: enum QStyle::StandardPixmap This enum describes the available standard pixmaps. A standard pixmap is a pixmap that can follow some existing…...
做网站编辑好还是推广好/青岛百度代理公司
新安装的Linux mint 字体更新了以后,设置的全局字体不统一,部分字体偏小,部分字体甚至是比较小的楷体,模糊不清,十分影响观感和使用体验。终端使用命令fc-match sans-serif和fc-match serif和fc-match monospace均输出…...
美食网站建设的内容分析/促销活动推广方案
jQuery是一个当前依然非常流行的Web前端JavaScript框架,这次我们要分享的就是基于jQuery的日历时钟插件,部分日历插件还是基于HTML5技术实现的,因此动画效果都还不错。有兴趣的朋友可以接下去看看。1、jQuery多功能日历插件 带事件记录功能这…...
seo短视频网页入口引流在线看/木卢seo教程
系统进程管理 进程:进程是程序的一次动态执行守护进程:守护进程是在后台运行并提供系统服务的一些进程 top : 动态显示当前进程标签含义PID进程号PR、NI控制用户优先级,值越高,优先级越低VIRT虚拟内存S状态( S…...