当前位置: 首页 > news >正文

机器学习实战项目一(卡通化图像)

目录

在 Python 中使用 OpenCV 卡通化图像

什么是OpenCV?

我们要建造什么?

开发Image Cartoonifier的步骤

下载图片卡通化代码

第 1 步:导入所需的模块

步骤 2:构建文件框以选择特定文件

第 3 步:如何存储图像?

第 4 步:将图像转换为灰度

第 5 步:平滑灰度图像

第 6 步:检索图像的边缘

第 7 步:准备蒙版图像

第 8 步:赋予卡通效果

第 9 步:将所有过渡绘制在一起

步骤10:保存按钮的功能

第 11 步:制作主窗口

第 12 步:制作 卡通化 主窗口中的按钮

第 13 步:在主窗口中制作“保存”按钮

第 14 步:构建 tkinter 窗口的 main 函数


此为开源项目(法典结合代码一起看)

在 Python 中使用 OpenCV 卡通化图像

什么是OpenCV?

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它由Intel于1999年发起,现在由Willow Garage主导,并由全世界开源社区共同维护。OpenCV是一个跨平台库,可以在Windows、Linux、macOS、Android和iOS等操作系统上运行。它包含了大量的计算机视觉算法,如图像处理、特征检测与描述、运动跟踪、目标识别、三维重建以及机器学习等。

OpenCV的主要应用领域包括实时计算机视觉、机器人技术、人机交互、物体识别、运动分析、安全监控、图像分割、自动驾驶等。由于其丰富的功能和高效的性能,OpenCV已经成为计算机视觉领域最受欢迎的库之一。

使用OpenCV,开发者可以轻松地处理和分析图像和视频数据,实现各种复杂的计算机视觉任务。它提供了大量的API和工具,使得开发者能够快速地构建出高效的计算机视觉应用。

如果你对计算机视觉或图像处理感兴趣,学习OpenCV将是一个很好的选择。

我们要建造什么?

我们的目标是将图像转换为卡通。我们将构建一个 python 应用程序,该应用程序将使用 OpenCV 将图像转换为其卡通。

我们的目标是构建一个应用程序,如下所示:

卡通化输出

原始图像:

原始图像

广告

开发Image Cartoonifier的步骤

下载图片卡通化代码

请下载Image Cartoonfier Project的源代码:Cartoonify an Image in Python

或者

import cv2 #for image processing
import easygui #to open the filebox
import numpy as np #to store image
import imageio #to read image stored at particular pathimport sys
import matplotlib.pyplot as plt
import os
import tkinter as tk
from tkinter import filedialog
from tkinter import *
from PIL import ImageTk, Imagetop=tk.Tk()
top.geometry('400x400')
top.title('Cartoonify Your Image !')
top.configure(background='white')
label=Label(top,background='#CDCDCD', font=('calibri',20,'bold'))def upload():ImagePath=easygui.fileopenbox()cartoonify(ImagePath)def cartoonify(ImagePath):# read the imageoriginalmage = cv2.imread(ImagePath)originalmage = cv2.cvtColor(originalmage, cv2.COLOR_BGR2RGB)#print(image)  # image is stored in form of numbers# confirm that image is chosenif originalmage is None:print("Can not find any image. Choose appropriate file")sys.exit()ReSized1 = cv2.resize(originalmage, (960, 540))#plt.imshow(ReSized1, cmap='gray')#converting an image to grayscalegrayScaleImage= cv2.cvtColor(originalmage, cv2.COLOR_BGR2GRAY)ReSized2 = cv2.resize(grayScaleImage, (960, 540))#plt.imshow(ReSized2, cmap='gray')#applying median blur to smoothen an imagesmoothGrayScale = cv2.medianBlur(grayScaleImage, 5)ReSized3 = cv2.resize(smoothGrayScale, (960, 540))#plt.imshow(ReSized3, cmap='gray')#retrieving the edges for cartoon effect#by using thresholding techniquegetEdge = cv2.adaptiveThreshold(smoothGrayScale, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 9)ReSized4 = cv2.resize(getEdge, (960, 540))#plt.imshow(ReSized4, cmap='gray')#applying bilateral filter to remove noise #and keep edge sharp as requiredcolorImage = cv2.bilateralFilter(originalmage, 9, 300, 300)ReSized5 = cv2.resize(colorImage, (960, 540))#plt.imshow(ReSized5, cmap='gray')#masking edged image with our "BEAUTIFY" imagecartoonImage = cv2.bitwise_and(colorImage, colorImage, mask=getEdge)ReSized6 = cv2.resize(cartoonImage, (960, 540))#plt.imshow(ReSized6, cmap='gray')# Plotting the whole transitionimages=[ReSized1, ReSized2, ReSized3, ReSized4, ReSized5, ReSized6]fig, axes = plt.subplots(3,2, figsize=(8,8), subplot_kw={'xticks':[], 'yticks':[]}, gridspec_kw=dict(hspace=0.1, wspace=0.1))for i, ax in enumerate(axes.flat):ax.imshow(images[i], cmap='gray')save1=Button(top,text="Save cartoon image",command=lambda: save(ReSized6, ImagePath),padx=30,pady=5)save1.configure(background='#364156', foreground='white',font=('calibri',10,'bold'))save1.pack(side=TOP,pady=50)plt.show()def save(ReSized6, ImagePath):#saving an image using imwrite()newName="cartoonified_Image"path1 = os.path.dirname(ImagePath)extension=os.path.splitext(ImagePath)[1]path = os.path.join(path1, newName+extension)cv2.imwrite(path, cv2.cvtColor(ReSized6, cv2.COLOR_RGB2BGR))I= "Image saved by name " + newName +" at "+ pathtk.messagebox.showinfo(title=None, message=I)upload=Button(top,text="Cartoonify an Image",command=upload,padx=10,pady=5)
upload.configure(background='#364156', foreground='white',font=('calibri',10,'bold'))
upload.pack(side=TOP,pady=50)top.mainloop()
第 1 步:导入所需的模块

我们将导入以下模块:

  • CV2:导入以使用 OpenCV 进行图像处理
  • easygui:导入以打开文件框。它允许我们从系统中选择任何文件。
  • Numpy:图像以数字的形式存储和处理。这些被当作数组。我们使用 NumPy 来处理数组。
  • Imageio:用于读取使用路径的文件框选择的文件。
  • Matplotlib:此库用于可视化和绘图。因此,它被导入以形成图像的情节。
  • 操作系统:用于操作系统交互。在这里,读取路径并将图像保存到该路径。

法典:

导入 CV2 #for 图像处理
导入 Easygui #to 打开文件框
将 numpy 导入为 NP #to 存储映像
导入 imageio #to 读取存储在特定路径上的图像
导入系统
导入 matplotlib。pyplot 作为 plt
导入操作系统
将 tkinter 导入为 tk
从 tkinter 导入文件对话框
从 TKINTER 导入*
从 PIL 导入 ImageTk, Image
步骤 2:构建文件框以选择特定文件

在此步骤中,我们将构建应用程序的主窗口,按钮、标签和图像将驻留在其中。我们还通过 title() 函数给它一个标题。

法典:

""“ fileopenbox 打开框以选择文件
并帮助我们将文件路径存储为字符串”""
def upload()
ImagePath=easygui。文件OpenBox()
卡通化ImagePath)

解释:

上面的代码打开文件框,即从设备中选择文件的弹出框,每次运行代码时都会打开。fileopenbox() 是 easyGUI 模块中的方法,它将所选文件的路径以字符串形式返回。

注意:现在,所有操作都将在单击按钮时完成,因此以下所有步骤都是函数 cartoonify (ImagePath) 的一部分

def cartoonifyImagePath
第 3 步:如何存储图像?

现在,试想一下,程序将如何读取图像?对于计算机来说,一切都只是数字。因此,在下面的代码中,我们将图像转换为numpy数组。

法典:

#read 图像
原始法师 = CV2。imread图像路径)
原始法师 = CV2。cvtColororiginalmage, cv2.COLOR_BGR2RGB)
#print(image) # 图像以数字形式存储
# 确认镜像被选中
如果 originalmage 为 None:
print“找不到任何图像。选择合适的文件”)
系统。退出()
ReSized1 = cv2。resize原始法师, 960540))
#plt.imshow(ReSized1, cmap='gray')

解释:

Imread 是 cv2 中的一种方法,用于以数字形式存储图像。这有助于我们根据需要执行操作。图像被读取为numpy数组,其中单元格值描述了像素的R、G和B值。

注意:我们在每次转换后调整图像大小,以最终以相似的比例显示所有图像。

从图像转换开始:

要将图像转换为卡通,需要进行多次转换。首先,将图像转换为灰度图像。是的,和以前的照片差不多。!然后,对灰度图像进行平滑处理,并尝试提取图像中的边缘。最后,我们形成一个彩色图像并用边缘遮罩它。这将创建一个美丽的卡通图像,其边缘和原始图像的颜色变浅。

让我们从这些转换开始,将图像转换为卡通图像。

第 4 步:将图像转换为灰度

法典:

#converting 图像转换为灰度
grayScaleImage = cv2。cvtColororiginalmage, cv2.COLOR_BGR2GRAY)
ReSized2 = cv2。resizegrayScaleImage, 960540))
#plt.imshow(ReSized2, cmap='gray')

解释:

cvtColor(image, flag) 是 cv2 中的一种方法,用于将图像转换为称为“flag”的颜色空间。在这里,我们的第一步是将图像转换为灰度。因此,我们使用 BGR2GRAY 标志。这将以灰度返回图像。灰度图像存储为 grayScaleImage。

每次转换后,我们使用 cv2 中的 resize() 方法调整生成的图像大小,并使用 imshow() 方法显示它。这样做是为了更清楚地了解每个转型步骤。

上面的代码将生成以下输出:

灰色图像

第 5 步:平滑灰度图像

法典:

#applying 中位模糊以平滑图像
smoothGrayScale = cv2。medianBlur灰度图像,5)
ReSized3 = cv2。调整大小smoothGrayScale, 960540))
#plt.imshow(ReSized3, cmap='gray')

解释:

为了使图像平滑,我们只需应用模糊效果即可。这是使用 medianBlur() 函数完成的。在这里,中心像素被分配了属于内核的所有像素的平均值。反过来,创建模糊效果。

上面的代码生成以下输出:

光滑的灰色

第 6 步:检索图像的边缘

法典:

#retrieving the edges for cartoon effect
#by using thresholding technique
getEdge = cv2.adaptiveThreshold(smoothGrayScale, 255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, 9, 9)
ReSized4 = cv2.resize(getEdge, (960, 540))
#plt.imshow(ReSized4, cmap='gray')

解释:

卡通效果有两个特点:

  1. 突出显示的边缘
  2. 平滑的色彩

在此步骤中,我们将研究第一个专业。在这里,我们将尝试检索边缘并突出显示它们。这是通过自适应阈值技术实现的。阈值是邻域像素值面积减去常数 C 的平均值,C 是从邻域像素的平均值或加权和中减去的常数。Thresh_binary 是应用的阈值类型,其余参数确定块大小。

第 7 步:准备蒙版图像

法典:

#applying 双边滤波器,可消除噪声
#and 根据需要保持边缘锋利
colorImage = cv2。bilateralFilteroriginalmage, 9300300)
ReSized5 = cv2。resizecolorImage, 960540))
#plt.imshow(ReSized5, cmap='gray')

解释:

在上面的代码中,我们终于研究了第二个专业。我们准备一个浅色的彩色图像,最后用边缘遮罩以产生卡通图像。我们使用 bilateralFilter 来消除噪声。它可以在一定程度上被视为图像的平滑化。

第三个参数是像素邻域的直径,即某个像素周围的像素数,这将决定其值。第四个和第五个参数定义 signmaColor 和 sigmaSpace。这些参数用于产生西格玛效果,即使图像看起来恶毒,像水漆一样,去除颜色的粗糙度。

是的,它类似于现代手机相机中的美化或AI效果。

上面的代码生成以下输出:

颜色蒙版

第 8 步:赋予卡通效果

法典:

使用我们的“美化”图像 #masking 边缘图像
卡通图像 = cv2。bitwise_andcolorImage, colorImage, mask=getEdge)
ReSized6 = cv2。resize卡通图像, 960540))
#plt.imshow(ReSized6, cmap='gray')

解释:

所以,让我们把这两个专业结合起来。这将使用 MASKING 完成。我们按位执行,并对两个图像进行遮罩。还记得,图像只是数字吗?

是的,这就是我们在“美化”图像上遮盖边缘图像的方式。

这终于卡通化了我们的形象!

上面的代码将生成如下所示的输出:

卡通效果

第 9 步:将所有过渡绘制在一起

法典:

# 绘制整个过渡
图像=[ReSized1, ReSized2, ReSized3, ReSized4, ReSized5, ReSized6]
图,轴 = PLT。subplots3,2, figsize=8,8, subplot_kw={'xticks'[]'yticks'[]}, gridspec_kw=dicthspace=0.1, wspace=0.1))
对于 i,exnumerate axes.
斧头。imshowimages[i], cmap='灰色')
保存按钮代码
PLT。显示()

解释:

要绘制所有图像,我们首先列出所有图像。此处的列表名为“images”,包含所有调整大小的图像。现在,我们在图中创建类似 subl=plots 的轴,并使用 imshow() 方法在轴上的每个块中显示一对一的图像。

plt.show() 在绘制每个子图后立即绘制整个图。

上面的代码将生成如下所示的输出:

卡通化输出

 

步骤10:保存按钮的功能
def saveReSized6, ImagePath
使用 imwrite() #saving 图像
newName=“cartoonified_Image”
path1 = 操作系统。路径dirnameImagePath)
扩展=操作系统。路径splitext图像路径)[1]
路径 = 操作系统。路径joinpath1, newName+扩展名)
简历2。imwrite路径,cv2.cvtColorReSized6, cv2.COLOR_RGB2BGR))
I = “按名称保存的图像” + newName +“ 在 ”+ 路径
传统知识。message框showinfotitle=None, message=I)

解释:

在这里,我们的想法是保存生成的图像。为此,我们采用旧路径,只需将尾部(旧文件的名称)更改为新名称,并通过将新名称附加到文件的头部,将具有新名称的卡通化图像存储在同一文件夹中。

为此,我们通过 os.path.dirname() 方法提取文件路径的头部。同样,os.path.splitext(ImagePath)[1] 用于从路径中提取文件的扩展名。

在这里,newName 将“Cartoonified_Image”存储为新文件的名称。os.path.join(path1, newName + extension) 将路径的头部连接到 newname 和扩展名。这将形成新文件的完整路径。

cv2 的 imwrite() 方法用于将文件保存在提到的路径中。cv2.cvtColor(ReSized6, cv2.COLOR_RGB2BGR) 用于确保在保存图像时不会提取或突出显示任何颜色。因此,最后,用户将获得确认图像已保存为文件的名称和路径。

使用按钮执行后,此函数将产生以下输出:

第 11 步:制作主窗口
top=tk。Tk的()
返回页首。几何'400x400')
返回页首。title'卡通化你的形象!)
返回页首。配置background='白色')
label=Labeltop,background='#CDCDCD', font='calibri'20'粗体'))
第 12 步:制作 卡通化 主窗口中的按钮
upload=Buttontop,text=“卡通化图像”,command=upload,padx=10,pady=5)
上传。configurebackground='#364156', foreground='white',font='calibri'10'粗体'))
上传。packside=TOP,pady=50)
第 13 步:在主窗口中制作“保存”按钮
save1=Buttontop,text=“保存卡通图片”,command=lambda: saveImagePath, ReSized6,padx=30,pady=5)
保存 1。configurebackground='#364156', foreground='white',font='calibri'10'粗体'))
保存 1。packside=TOP,pady=50)

上面的代码在图像转换完成后立即创建一个按钮。它为用户提供了保存卡通化图像的选项。

第 14 步:构建 tkinter 窗口的 main 函数
返回页首。主循环()

最终结果:

图片保存

相关文章:

  • Linux命令篇(一):文件管理部分
  • 阿里云短信服务使用(Java)
  • C# 语言类型(二)—预定义类型之字符串及字符类型简述
  • 深入理解Java中的List集合:解析实例、优化技巧与最佳实践
  • HackTheBox-Machines--Lazy
  • 数据结构——图
  • Lua的几个特殊用法
  • PHP面向对象编程总结
  • Flutter 中的 SliverCrossAxisGroup 小部件:全面指南
  • C++ 变量的声明和初始化方式
  • <Rust><iced>基于rust使用iced库构建GUI实例:动态改变主题色
  • 使用Spring的@Scheduled注解实现定时任务
  • 关于高版本 Plant Simulation 每次保存是 提示提交comm对话框的处理方法
  • 使用axios+vue在离开页面时中断网络请求
  • MATLAB算法实战应用案例精讲-【数模应用】Turf组合模型(附MATLAB、python和R语言代码实现)
  • 【剑指offer】让抽象问题具体化
  • 2018一半小结一波
  • js操作时间(持续更新)
  • JS函数式编程 数组部分风格 ES6版
  • Mac转Windows的拯救指南
  • PHP变量
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • Spring Cloud Feign的两种使用姿势
  • vue 个人积累(使用工具,组件)
  • 创建一种深思熟虑的文化
  • 动态规划入门(以爬楼梯为例)
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 说说动画卡顿的解决方案
  • 想写好前端,先练好内功
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • $refs 、$nextTic、动态组件、name的使用
  • (3)医疗图像处理:MRI磁共振成像-快速采集--(杨正汉)
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (四)鸿鹄云架构一服务注册中心
  • (算法二)滑动窗口
  • (转)程序员技术练级攻略
  • .NET Core 版本不支持的问题
  • .net core开源商城系统源码,支持可视化布局小程序
  • .NET 回调、接口回调、 委托
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布
  • .NET中的十进制浮点类型,徐汇区网站设计
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • [Algorithm][动态规划][子序列问题][最长递增子序列][摆动序列]详细讲解
  • [android] 请求码和结果码的作用
  • [autojs]autojs开关按钮的简单使用
  • [BZOJ1053][HAOI2007]反素数ant
  • [C++] 如何使用Visual Studio 2022 + QT6创建桌面应用
  • [CF226E]Noble Knight's Path
  • [CISCN2019 华北赛区 Day1 Web5]CyberPunk --不会编程的崽
  • [codeforces]Recover the String
  • [Codeforces1137D]Cooperative Game