使用 Python OpenCV 创建图像到卡通转换器

https://pyseek.com/2022/07/image-to-cartoon-converter-in-python/

一、说明

你有没有试过把自己的照片转换成卡通画?顺便说一句,这不是开玩笑。很多人喜欢把他们的照片变成卡通画并在社交媒体上分享。就连我自己也多次尝试过这种技术。有很多在线工具可以完成这项任务。但是如果我们自己制作一个图像到卡通画的转换器呢?听起来很棒吧?

在本教程中,我们将在OpenCV 和 Tkinter 库的帮助下,使用 Python 语言创建这样一个图像到卡通转换器。但是,在进入主要项目讨论之前,我们必须了解卡通化过程背后的核心逻辑以及如何通过 Python 编程实现它。

因此,我将整个主题分为两部分。在第一部分中,您将学习如何通过 Python 程序逐步为图像添加卡通效果。在第二部分中,我们将应用相同的逻辑来创建一个 Python 应用程序,只需单击几下即可实现卡通化效果。任何人都可以轻松使用该应用程序。

那么,让我们继续我们的精彩讨论。

二、算法和思路

2.1 使用

首先,我们需要安装 OpenCV 库(文档)。要获取它,请使用以下命令:

pip install opencv-python 

不用担心 Tkinter 库(文档)。大多数 Python 安装都已预装它。如果您没有它,可以使用以下命令安装它:

pip install tk 

2.2 导入模块

我建议您为该项目创建一个名为“ Cartoon-Maker ”的单独文件夹,并在其中声明一个 Python 文件“ cartoon_maker.py ”。

现在,让我们开始导入cv2模块。

import cv2 

2.3 打开图像

让我们打开您的图库并挑选一张您自己的高质量照片。现在将其保存在项目文件夹中。

在名为“ img_path ”的变量中提及图像的名称,并使用函数加载图像cv2.imread

img_path =“woman.jpg”
img = cv2.imread(img_path) 

2.4 调整图像大小并显示

并非所有计算机或笔记本电脑用户的屏幕尺寸都相同,这意味着显示的图像可能不会对每个人都完美显示。

为了确保统一性并避免任何不一致,调整图像大小非常重要,以便所有用户都能看到相同的图像。您可以使用此cv2.imread功能来实现这一点。

img = cv2.resize(img, (820,540))

在我们进入编辑阶段之前,让我们使用该cv2.imshow函数显示原始图像。

cv2.imshow("Result Image", img)
cv2.waitKey()
cv2.destroyAllWindows()

输出

2.5 转换为灰度

我们首先将图像转换为灰度以创建卡通效果。为此,我们将使用函数cv2.cvtColor。在此函数中,我们需要将初始加载的图像指定为初始参数,然后指定代码值,该代码值需要一个整数输入。

gray_img = cv2.cvtColor(src=img, code=cv2.COLOR_BGR2GRAY)

代码选项有很多,每个选项都与一个不同的整数相关联。记住这些数值可能很困难,这就是为什么我们选择使用更容易记住的代码名称(如cv2.COLOR_BGR2GRAY本例所示)而不是处理数字表示。

这是颜色空间转换的文档:  OpenCV 文档。

现在,为了显示转换后的灰度图像,我们将使用上一节中用于显示的相同代码块。唯一需要调整的是更新函数中的第二个参数cv2.imshow,将其指定为“ gray_img ”。

cv2.imshow("Result Image", gray_img)
cv2.waitKey()
cv2.destroyAllWindows()

输出

2.6 平滑图像

平滑图像是图像到卡通转换过程中的关键步骤。

平滑处理是模糊图像同时保留其基本特征的技术。它有助于简化图像的细节、减少噪音并为卡通化过程做好准备。

在此步骤中,我们将对灰度图像应用中值模糊以实现我们现在的目标。

smooth_image = cv2.medianBlur(src=gray_img, ksize=5)

在上面的代码中,

  • src '代表我们之前转换为灰度图像的图像(“gray_img”)。
  • “ ksize ”表示用于模糊的内核的大小。在我们的例子中,我们取值为“5”。请注意,它只接受奇数整数值。您可以调整此值来控制平滑级别,请记住,值越高,平滑效果越好。

再次,我们将使用与上一节相同的技术显示平滑后的图像。

cv2.imshow("Result Image", smooth_img)
cv2.waitKey()
cv2.destroyAllWindows()

输出

2.7 应用边缘检测

现在我们将边缘检测技术应用于之前过滤的图像。

边缘检测是一种基本过程,可以增强图像中物体的轮廓,使其具有独特的卡通外观。在这里,我们将使用自适应阈值技术来实现这一点。为此,我们将cv2.adaptiveThreshold在代码中使用该函数。

edges = cv2.adaptiveThreshold(src=smooth_image, maxValue=255, adaptiveMethod=cv2.ADAPTIVE_THRESH_MEAN_C, thresholdType=cv2.THRESH_BINARY, blockSize=7, C=6)

在上面的代码中,

  • src ' 是我们在流程早期准备的平滑图像(“smooth_image”)。
  • maxValue '代表可能的最高像素值,在我们的上下文中,它设置为'255',并分配给满足阈值条件的像素。
  • adaptiveMethod '(cv2.ADAPTIVE_THRESH_MEAN_C)指定自适应阈值方法,该方法将每个邻域的阈值计算为邻域面积的平均值。
  • 'thresholdType ' ( cv2.THRESH_BINARY) 表示超过阈值的像素值将被设置为最大值 ( 255 ),而低于阈值的像素值将被设置为零。

现在,让我们展示一下最近添加的过滤图像。

cv2.imshow("Result Image", edges)
cv2.waitKey()
cv2.destroyAllWindows()

输出

2.8 应用卡通效果

在本节中,我们将使用双边滤波为图像提供卡通效果。它是图像处理中的关键工具,因为它可以同时平滑图像并保留边缘等重要细节。

我们来做一下代码:

color_img = cv2.bilateralFilter(src=img, d=9, sigmaColor=300, sigmaSpace=300)

在上面的代码中,

  • 'img ' 是您的图像的原始版本。
  • 参数“ d ”代表过滤过程中考虑的每个像素邻域的直径。
  • sigmaColor ' 根据颜色控制滤镜的影响。要获得卡通效果,您需要为其选择> 150 的值。
  • “ sigmaSpace ”根据空间距离或坐标控制滤镜的影响。要获得微调艺术效果,请为最后两个参数选择较高的值。

它会是什么样子?让我们再次显示它。

cv2.imshow("Result Image", color_img)
cv2.waitKey()
cv2.destroyAllWindows()

输出

2.9 应用风格化

我们正处于卡通化过程的最后一步。在本节中,我们将使用按位 AND函数将风格化应用于卡通化图像。

此功能使我们能够将卡通图像边缘检测图像相结合,突出图像的轮廓和特征,就像手绘插图一样。

以下是在 Python 中应用按位 AND 函数的方法:

cartoon_img = cv2.bitwise_and(src1=color_img, src2=color_img, mask=edges)

在上面的代码中:

  • color_image`是我们使用以前的技术卡通化的图像。
  • edges`是我们之前使用自适应阈值准备的边缘检测图像。

我们的卡通形象现在已经准备好了。让我们显示它。

cv2.imshow("Result Image", cartoon_img)
cv2.waitKey()
cv2.destroyAllWindows()

输出

2.10 保存图像

我们已经将原始图像转换为卡通图像,但要在其他地方使用它,我们必须保存它。在程序末尾添加此代码片段,以将卡通化图像保存在当前工作目录中。

cv2.imwrite("result.jpg", cartoon_img)

三、将程序变成应用程序

现在是时候通过使用 Tkinter 库提供图形界面来改善程序的用户体验了。我们将创建一个使用 Python 将图像转换为卡通的应用程序。

程序的核心逻辑是一样的。在本例中,我们将创建一个 GUI 窗口和一些小部件来选择、显示、卡通化和保存图像。

因此,在复制整个代码之前,请在“Cartoon-Maker”文件夹中创建一个名为“ app.py ”的 Python 文件。

import cv2
import pathlib
import pyautogui
from tkinter import *
from PIL import ImageTk, Image
from tkinter import filedialogclass Image_Cartoonify:def __init__(self, root):self.window = rootself.window.geometry("960x560")self.window.title('Cartoonify')self.window.resizable(width=False, height=False)self.width = 740self.height = 480self.Image_Path = ''# ==============================================# ================Menubar Section===============# ==============================================# Creating Menubarself.menubar = Menu(self.window)# Adding Edit Menu and its sub menusedit = Menu(self.menubar, tearoff=0)self.menubar.add_cascade(label='Open', menu=edit)edit.add_command(label='Open Image', command=self.open_image)# Menu widget to cartoonify the imagecartoonify = Menu(self.menubar, tearoff=0)self.menubar.add_cascade(label='Cartoonify', menu=cartoonify)cartoonify.add_command(label='Create Cartoon', command=self.cartoonify)# Exit the Applicationexit = Menu(self.menubar, tearoff=0)self.menubar.add_cascade(label='Exit', menu=exit)exit.add_command(label='Exit', command=self._exit)# Configuring the menubarself.window.config(menu=self.menubar)# ===================End=======================# Creating a Frameself.frame = Frame(self.window,width=self.width, height=self.height)self.frame.pack()self.frame.place(anchor='center', relx=0.5, rely=0.5)# Open an Image through filedialogdef open_image(self):self.clear_screen()self.Image_Path = filedialog.askopenfilename(title="Select an Image",filetypes=(("Image files", "*.jpg *.jpeg *.png"),))if len(self.Image_Path) != 0:self.show_image(self.Image_Path)# Display the Imagedef show_image(self, Img):# Opening the imageimage = Image.open(Img)# resize the image, so that it fits to the screenresized_image = image.resize((self.width, self.height))# Create an object of tkinter ImageTkself.img = ImageTk.PhotoImage(resized_image)# A Label Widget for displaying the Imagelabel = Label(self.frame, image=self.img)label.pack()def cartoonify(self):# Storing the image path to a variableImgPath = self.Image_Path# If any image is not selectedif len(ImgPath) == 0:passelse:# Get the file name to be saved after cartoonify the imagefilename = pyautogui.prompt("Enter the filename to be saved")# Filename with the extension (extension of the original image)filename = filename + pathlib.Path(ImgPath).suffix# Read the imageImg = cv2.imread(ImgPath)Img = cv2.resize(Img, (740, 480))GrayImg = cv2.cvtColor(src=Img, code=cv2.COLOR_BGR2GRAY)SmoothImg = cv2.medianBlur(src=GrayImg, ksize=5)Edges = cv2.adaptiveThreshold(src=SmoothImg, maxValue=255, adaptiveMethod=cv2.ADAPTIVE_THRESH_MEAN_C,thresholdType=cv2.THRESH_BINARY, blockSize=9, C=9)# Adjust the the values of sigmaColor and sigmaSpace to get a proper cartoon effectColorImg = cv2.bilateralFilter(src=Img, d=9, sigmaColor=300, sigmaSpace=300)CartoonImg = cv2.bitwise_and(src1=ColorImg, src2=ColorImg, mask=Edges)cv2.imwrite(filename, CartoonImg)self.clear_screen()self.show_image(filename)# Remove all widgets from the framedef clear_screen(self):for widget in self.frame.winfo_children():widget.destroy()# It destroys the main GUI window of the# applicationdef _exit(self):self.window.destroy()if __name__ == "__main__":root = Tk()# Creating an object of Image_Cartoonify classobj = Image_Cartoonify(root)root.mainloop()

在上面的程序中,我们创建一个名为的类Image_Cartoonify并声明六个方法。__init__创建一个 GUI 窗口和所有小部件。该open_image方法打开一个 tkinter 对话框来选择图像。

show_image方法在框架上显示所选图像。卡通化方法负责为所选图像赋予卡通效果。clear_screen_exit方法分别用于删除窗口上显示的所有小部件并关闭窗口。

四、总结

在本教程中,我们探索使用 Python 和 OpenCV 库创建图像到卡通转换器。

本教程分为两部分,第一部分重点介绍核心程序,分解每个步骤,从导入 OpenCV 模块到将图像转换为卡通。该过程包括图像加载、调整大小、灰度转换、平滑、边缘检测、应用卡通效果和风格化。

这还不是全部。在第二部分中,我们通过使用 Tkinter 库添加图形用户界面 (GUI) 来增强程序。它创建了一个用于将图像转换为卡通的应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/376211.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全局代理的判断维度与实用分析

在这个数字化时代,全局代理成为了许多用户保护隐私、加速访问的必备工具。然而,面对市场上琳琅满目的代理服务,如何做出明智的选择?作为您的专业测评团队,我们深入探索了全局代理的多个判断维度,并精选了极…

隔离驱动-视频课笔记

目录 1、需要隔离的原因 1.2、四种常用的隔离方案 2、脉冲变压器隔离 2.1、脉冲变压器的工作原理 2.2、泄放电阻对开关电路的影响 2.3、本课小结 3、光耦隔离驱动 3.1、光耦隔离驱动原理 3.2、光耦隔离驱动的电源进行分析 3.3、本课小结 4、自举升压驱动 4.1…

CANoe:为什么两个VLAN接口不能设置同一个网络的IP地址呢?

经常玩CANoe的人应该配置过TCP/IP Stack中网络节点的网卡信息,基本的信息包含:MAC地址、IP地址、子网掩码、默认网关、MTU值、IPv6地址。 如果你想让发送出去的报文携带VLAN tag,可以在网卡上添加VLAN tag信息。 此时你就能得到两个新的网卡V…

MongoDB教程(一):Linux系统安装mongoDB详细教程

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 文章目录 引言一、Ubuntu…

卷积神经网络——LeNet——FashionMNIST

目录 一、文件结构二、model.py三、model_train.py四、model_test.py 一、文件结构 二、model.py import torch from torch import nn from torchsummary import summaryclass LeNet(nn.Module):def __init__(self):super(LeNet,self).__init__()self.c1 nn.Conv2d(in_channe…

一文了解MySQL的表级锁

文章目录 ☃️概述☃️表级锁❄️❄️介绍❄️❄️表锁❄️❄️元数据锁❄️❄️意向锁⛷️⛷️⛷️ 介绍 ☃️概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外&#xff0…

【深度学习基础】MacOS PyCharm连接远程服务器

目录 一、需求描述二、建立与服务器的远程连接1. 新版Pycharm的界面有什么不同?2. 创建远程连接3. 建立本地项目与远程服务器项目之间的路径映射4.设置保存自动上传文件 三、设置解释器总结 写在前面,本人用的是Macbook Pro, M3 MAX处理器&am…

开发个人Ollama-Chat--6 OpenUI

开发个人Ollama-Chat–6 OpenUI Open-webui Open WebUI 是一种可扩展、功能丰富且用户友好的自托管 WebUI,旨在完全离线运行。它支持各种 LLM 运行器,包括 Ollama 和 OpenAI 兼容的 API。 功能 由于总所周知的原由,OpenAI 的接口需要密钥才…

创建地形——笔记

1、创建地面 (1) 3D Object-Terrain (2) 导入资源 (3) 选中Terrain,绘制贴图 (4) 新建一个沙土层 (5) 编辑沙土层——选中Inspector中的新建沙土层,出现编辑面板 依次点击Nomal Map和Mask Map右侧的Slect,增加法线贴图(紫&…

Run LoongArch64 Alpine VM on x86_64

一、Build from source(build on x86_64) Obtain the latest libvirt, virt-manager, and qemu source code, compile and install them. 1.1 Build libvirt from source sudo apt-get update sudo apt-get install augeas-tools bash-completion debhelper-compat dh-apparm…

深入理解FFmpeg--libavformat接口使用(一)

libavformat(lavf)是一个用于处理各种媒体容器格式的库。它的主要两个目的是去复用(即将媒体文件拆分为组件流)和复用的反向过程(以指定的容器格式写入提供的数据)。它还有一个I/O模块,支持多种…

加密与安全_密钥体系的三个核心目标之完整性解决方案

文章目录 Pre机密性完整性1. 哈希函数(Hash Function)定义特征常见算法应用散列函数常用场景散列函数无法解决的问题 2. 消息认证码(MAC)概述定义常见算法工作原理如何使用 MACMAC 的问题 不可否认性数字签名(Digital …

Objective-C 自定义渐变色Slider

文章目录 一、前情概要二、具体实现 一、前情概要 系统提供UISlider,但在开发过程中经常需要自定义,本次需求内容是实现一个拥有渐变色的滑动条,且渐变色随着手指touch的位置不同改变区域,类似如下 可以使用CAGradientLayer实现渐…

SpringBoot相关

SpringBoot 1. what springboot也是spring公司开发的一款框架。为了简化spring项目的初始化搭建的。 spring项目搭建的缺点: 配置麻烦依赖繁多tomcat启动慢 2 .springboot的特点(why) 自动配置 springboot的自动配置是一个运行时(更准确地说,是应用程…

基于JAVA+SpringBoot+Vue+uniApp小程序的心理健康测试平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背景介绍: 该系统由三个核心角色…

数据库MySQL下载安装

MySQL下载安装地址如下: MySQL :: Download MySQL Community Server 1、下载界面 2、点击下载 3、解压记住目录 4、配置my.ini文件 未完..

走进linux

1、为什么要使用linux 稳定性和可靠性: Linux内核以其稳定性而闻名,能够持续运行数月甚至数年而不需要重新启动。这对于服务器来说至关重要,因为它们需要保持长时间的稳定运行,以提供持续的服务 安全性: Linux系统…

【python算法学习1】用递归和循环分别写下 fibonacci 斐波拉契数列,比较差异

问题: fibonacci 斐波拉契数列,用递归和循环的方法分别写,比较递归和循环的思路和写法的差别 最直接的思路,是写递归方法 循环方法的稍微有点绕,我觉得问题主要是出在,总结循环的通项公式更麻烦,难在数学…

《Linux系统编程篇》vim的使用 ——基础篇

引言 上节课我们讲了,如何将虚拟机的用户目录映射到自己windows的z盘,虽然这样之后我们可以用自己的编译器比如说Visual Studio Code,或者其他方式去操作里面的文件,但是这是可搭建的情况下,在一些特殊情况下&#xf…

【深度学习基础】MAC pycharm 专业版安装与激活

文章目录 一、pycharm专业版安装二、激活 一、pycharm专业版安装 PyCharm是一款专为Python开发者设计的集成开发环境(IDE),旨在帮助用户在使用Python语言开发时提高效率。以下是对PyCharm软件的详细介绍,包括其作用和主要功能&…