基于Python实现简易的动漫图片转换器
作者:Sir 发布时间:2022-12-25 23:23:11
标签:Python,动漫,图片
本文旨在制作一个将普通照片转换成动漫图片的小工具,其中使用opencv的非标准库实现对图片完成转换。
UI界面的制作使用的还是pyqt5,因为用习惯了使用起来相当方便,接下来还是先将使用到的python非标准库列举一下。
#?PyQt5相关模块
from?PyQt5.QtWidgets?import?*
from?PyQt5.QtCore?import?*
from?PyQt5.QtGui?import?*
#?动漫图片制作的业务模块
import?cv2
import?sys
import?os
#?日志模块
from?loguru?import?logger
制作UI界面,创建CartoonUI类,用于初始化图片转换器的应用。CartoonUI类继承自QWidget,因为这里只需要制作一个单页面的应用,因此,这里只继承了QWidget。
class?CartoonUI(QWidget):
????def?__init__(self):
????????'''
????????初始化UI界面应用
????????'''
????????super(CartoonUI,?self).__init__()
????????self.init_ui()
????def?init_ui(self):
????????'''
????????自定义实现的ui应用函数
????????:return:
????????'''
????????self.setWindowTitle('动漫图片转换器??公众号:Python 集中营')
????????self.setWindowIcon(QIcon('ico.png'))
????????self.setFixedWidth(500)
????????hbox?=?QHBoxLayout()
????????self.input_image_path?=?QLineEdit()
????????self.input_image_path.setPlaceholderText('源图片路径')
????????self.input_image_path.setReadOnly(True)
????????self.input_image_btn?=?QPushButton()
????????self.input_image_btn.setText('导入源图片')
????????self.input_image_btn.clicked.connect(self.input_image_btn_click)
????????self.generate_btn?=?QPushButton()
????????self.generate_btn.setText('一键生成动漫图片')
????????self.generate_btn.clicked.connect(self.generate_btn_click)
????????hbox.addWidget(self.input_image_path)
????????hbox.addWidget(self.input_image_btn)
????????hbox.addWidget(self.generate_btn)
????????self.thread_?=?WorkThread(self)
????????self.thread_.finished.connect(self.finished)
????????self.setLayout(hbox)
????def?input_image_btn_click(self):
????????'''
????????input_image_btn按钮绑定的槽函数,
????????用于实现打开文件浏览项
????????:return:
????????'''
????????im_path?=?QFileDialog.getOpenFileName(self,?os.getcwd(),?'打开图片',
??????????????????????????????????????????????'Image?File(*.jpg);;Image?File(*.png);;Image?File(*.jpeg)')
????????self.input_image_path.setText(im_path[0])
????def?generate_btn_click(self):
????????'''
????????generate_btn按钮绑定的槽函数,
????????用于启动业务子线程
????????:return:
????????'''
????????self.thread_.start()
????????self.generate_btn.setEnabled(False)
????def?finished(self,finished):
????????'''
????????接收子线程中finished变量,
????????判定子线程业务是否执行完成,若执行完成则将按钮状态改变为可点击状态
????????:param?finished:
????????:return:
????????'''
????????if?finished?is?True:
????????????self.generate_btn.setEnabled(True)
创建WorkThread类,继承自QThread子线程,子线程这里专门用来实现对普通图片的准换过程。之所以使用子线程来完成业务实现,是因为通常直接在主线程中完成业务会导致主线程异常卡死的情况。
单独使用子线程来完成业务会保证PyQt5的主线程正常的运行,将业务实现和界面应用分离开来。
class?WorkThread(QThread):
????finished?=?pyqtSignal(bool)
????def?__init__(self,?parent=None):
????????'''
????????子线程初始化函数
????????:param?parent:
????????'''
????????super(WorkThread,?self).__init__(parent)
????????self.parent?=?parent
????????self.working?=?True
????def?__del__(self):
????????'''
????????子线程停止函数
????????:return:
????????'''
????????self.working?=?False
????????self.wait()
????def?run(self):
????????'''
????????子线程执行函数
????????:return:
????????'''
????????try:
????????????input_picture_name?=?os.path.basename(self.parent.input_image_path.text().strip())
????????????logger.info(input_picture_name)
????????????output_picture_name?=?'cartoon_'?+?input_picture_name
????????????num_down?=?2??#?缩减像素采样的数目
????????????num_bilateral?=?7??#?定义双边滤波的数目
????????????img_rgb?=?cv2.imread(input_picture_name)??#?读取图片
????????????#?用高斯金字塔降低取样
????????????img_color?=?img_rgb
????????????for?_?in?range(num_down):
????????????????img_color?=?cv2.pyrDown(img_color)
????????????#?重复使用小的双边滤波代替一个大的滤波
????????????for?_?in?range(num_bilateral):
????????????????img_color?=?cv2.bilateralFilter(img_color,?d=9,?sigmaColor=9,?sigmaSpace=7)
????????????#?升采样图片到原始大小
????????????for?_?in?range(num_down):
????????????????img_color?=?cv2.pyrUp(img_color)
????????????#?转换为灰度并且使其产生中等的模糊
????????????img_gray?=?cv2.cvtColor(img_color,?cv2.COLOR_RGB2GRAY)
????????????img_blur?=?cv2.medianBlur(img_gray,?7)
????????????#?检测到边缘并且增强其效果
????????????img_edge?=?cv2.adaptiveThreshold(img_blur,?255,
?????????????????????????????????????????????cv2.ADAPTIVE_THRESH_MEAN_C,
?????????????????????????????????????????????cv2.THRESH_BINARY,
?????????????????????????????????????????????blockSize=9,
?????????????????????????????????????????????C=2)
????????????#?转换回彩色图像
????????????img_edge?=?cv2.cvtColor(img_edge,?cv2.COLOR_GRAY2RGB)
????????????img_cartoon?=?cv2.bitwise_and(img_color,?img_edge)
????????????#?保存转换后的图片
????????????cv2.imwrite(output_picture_name,?img_cartoon)
????????????logger.info('动漫图片转换完成!')
????????????self.finished.emit(True)
????????except?Exception?as?e:
????????????logger.error(e)
实现完成上述所有的业务之后,需要使用main函数将PyQt5应用加入到主体循环中,这样整个UI应用就直接拉起了。
if?__name__?==?'__main__':
????app?=?QApplication(sys.argv)
????main?=?CartoonUI()
????main.show()
????sys.exit(app.exec_())
来源:https://mp.weixin.qq.com/s/CRUdE-F53RSmxYjyrGsyUA


猜你喜欢
- Python中的random模块用于生成随机数。下面介绍一下random模块中最常用的几个函数。random.randomrandom.ra
- 问题:python+Flask 反复调用model报错ValueError: Tensor Tensor("dense_2/Sof
- 一、 QingScan介绍QingScan是一个安全工具整合系统,解决你平时使用各种工具一个个打 开填写扫描目标的麻烦过程;QingScan
- 这篇论坛文章着重介绍了SQL Server数据库简体繁体数据混用的问题,详细内容请参考下文:我现在要说的是一个在简体繁体数据混用的时候很容易
- 1、创建保存mysql备份文件的路径 /mysqldata #mkdir /mysqldata 2、创建/usr/sbin/bakmysql
- 目录方案一:重建 Replicas前提条件优点缺点操作步骤MasterSlave方案二:使用percona-toolkit进行数据修复前提条
- 1. 起因当我们需要写一个非常非常长的循环时,通常在某个循环如果出现error,那么整个代码后面的循环就不能进行。这时候试想,如果你在服务器
- 错误如图所示:图一 如果不能很好地执行登录触发器,那么将会导致登录失败。 例如,如果创建了这个触发器,那么就可以设计下面的代码来达到失败的目
- 注:此方法可用于配置gitlab也可用于配置github1.在github中创建一个账号:https://github.com/join?s
- 本文实例为大家分享了vue实现价格日历效果的具体代码,供大家参考,具体内容如下1、效果图2、下载全局安装:npm install ele-c
- 使用pycharm创建新项目,使用虚拟环境,但是进入到项目的cainiao_guoguo_health\venv\Scripts目录启动虚拟
- 在 vue 项目,有时请求返回的数据 中会有含有 \n 的字符串,如果直接渲染的话无法实现换行。 一、通过 css属性
- 实现原理PS的扩散效果可以产生类似毛玻璃质感的效果,使画面有些毛毛的感觉。其实现可通过操作像素三通道数值的方式实现,定义一个随机数器,将图像
- 本文实例讲述了Vue + Node.js + MongoDB图片上传组件实现图片预览和删除功能。分享给大家供大家参考,具体如下:公司要写一些
- bcp是SQL Server中负责导入导出数据的一个命令行工具,它是基于DB-Library的,并且能以并行的方式高效地导入导出大批量的数据
- 1. 递归概述递归( recursion)是一种编程技巧,某些情况下,甚至是无可替代的技巧。递归可以大幅简化代码,看起来非常简洁,但递归设计
- 一、写在前面本文基于64位windows系统(鼠标右键点击桌面“此电脑”图标——属性可查看电脑系统版本)、python3.x(pycharm
- 今天想用ruby on rails做一个小项目,需要用到mysql数据库,项目中的数据已经有了,只不过是保存在Sql Server中,用ra
- function is_email($str){ //检验email return preg_match("/
- 一、pyqt5的UI中嵌入matplotlib的方法1、导入模块导入模块比较简单,首先声明使用pyqt5,通过FigureCanvasQTA