Python+PyQT5实现手绘图片生成器

手绘图片生成器可以将导入的彩色图片通过python分析光源、灰度等操作生成手绘图片。

UI界面的整体部分代码块,UI界面的设计比较简单。效果在上面的图片展示。

class HandImage(QWidget):
    def __init__(self):
        super(HandImage, self).__init__()
        self.init_ui()

    def init_ui(self):
        '''
        UI界面组件及布局
        :return:
        '''
        self.setWindowTitle('手绘图片生成器   公众号:[Python 集中营]')
        self.setWindowIcon(QIcon('手绘图标.ico'))

        self.setFixedWidth(500)

        self.sou_im_path = QLineEdit()
        self.sou_im_path.setReadOnly(True)

        self.sou_im_path_btn = QPushButton()
        self.sou_im_path_btn.setText('源图片')
        self.sou_im_path_btn.clicked.connect(self.sou_im_path_btn_clk)

        self.dir_path = QLineEdit()
        self.dir_path.setReadOnly(True)

        self.dir_path_btn = QPushButton()
        self.dir_path_btn.setText('存储')
        self.dir_path_btn.clicked.connect(self.dir_path_btn_clk)

        self.start_btn = QPushButton()
        self.start_btn.setText('开始绘制图像')
        self.start_btn.clicked.connect(self.start_btn_clk)

        grid = QGridLayout()
        grid.addWidget(self.sou_im_path, 0, 0, 1, 1)
        grid.addWidget(self.sou_im_path_btn, 0, 1, 1, 1)
        grid.addWidget(self.dir_path, 1, 0, 1, 1)
        grid.addWidget(self.dir_path_btn, 1, 1, 1, 1)
        grid.addWidget(self.start_btn, 2, 0, 1, 2)

        self.thread_ = WorkThread(self)
        self.thread_.finished.connect(self.finished)

        self.setLayout(grid)

    # UI界面上的槽函数

    def sou_im_path_btn_clk(self):
        '''
        选择源图片并设置路径
        :return:
        '''
        im_path = QFileDialog.getOpenFileName(self, os.getcwd(), '打开图片', 'Image File(*.jpg);;Image File(*.png)')
        self.sou_im_path.setText(im_path[0])

    def dir_path_btn_clk(self):
        '''
        选择存储路径并设置路径
        :return:
        '''
        dir_path = QFileDialog.getExistingDirectory(self, os.getcwd(), '选择路径')
        self.dir_path.setText(dir_path)

    def start_btn_clk(self):
        '''
        开始按钮绑定的槽函数
        :return:
        '''
        self.start_btn.setEnabled(False)
        self.thread_.start()

    def finished(self, finished):
        '''
        用于子线程传递完成信号的槽函数
        :param finished: 信号变量
        :return:
        '''
        if finished is True:
            self.start_btn.setEnabled(True)

其中绘图用到的第三方库只有两个,主要的还是Pillow图像处理库,还有就是numpy科学计算库用于一些数组计算等的操作。

将第三方的处理库导入到代码块中

from PIL import Image  # 图像处理模块
import numpy as np  # 科学计算库

# PyQt5界面制作及样式、核心组件
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

# 应用基础操作相关
import sys
import os

创建用于专门手绘图像的子线程类,将UI界面的处理逻辑和生成图像的处理逻辑分开不至于产生无响应的卡死状态。

class WorkThread(QThread):
    finished = pyqtSignal(bool)

    def __init__(self, parent=None):
        super(WorkThread, self).__init__(parent)
        self.parent = parent
        self.working = True

    def __del__(self):
        self.working = False
        self.wait()

    def run(self):
        # 源图片路径
        sou_im_path = self.parent.sou_im_path.text().strip()
        # 存储路径
        dir_path = self.parent.dir_path.text().strip()
        if sou_im_path == '' or dir_path == '':
            self.finished.emit(True)
            return
        # 打开需要进行转的图像,并进行参数设置,取出来的参数主要图像的一些梯度值。最后进行数组保存。
        vals = np.asarray(Image.open(sou_im_path).convert('L')).astype('float')

        '''图像参数处理'''
        depth = 12.0  # 设置初始化深度
        gray_vals = np.gradient(vals)  # 提取图像灰度的梯度值
        gray_x, gray_y = gray_vals  # 单独提取横坐标与纵坐标的灰度值
        print('当前横坐标的灰度值:', gray_x)
        print('当前纵坐标的灰度值:', gray_y)

        # 重新设置横坐标合纵坐标的灰度值
        gray_x = gray_x * depth / 100.0
        gray_y = gray_y * depth / 100.0

        # 根据numpy.sqrt()函数计算横坐标和纵坐标灰度值的平方根
        gray_sqrt = np.sqrt(gray_x ** 2 + gray_y ** 2 + 1.0)

        # 重新计算X轴、Y轴、Z轴的光源
        light_x = gray_x / gray_sqrt
        light_y = gray_y / gray_sqrt
        light_z = 1.0 / gray_sqrt

        # 计算光源的方位角度、俯视角度
        agnle_el = np.pi / 2.2  # 俯视角度
        agnle_az = np.pi / 4.  # 方位角度

        # 分别计算光源对X轴、Y轴、Z轴的影响
        dx = np.cos(agnle_el) * np.cos(agnle_az)  # 光源对x 轴的影响
        dy = np.cos(agnle_el) * np.sin(agnle_az)  # 光源对y 轴的影响
        dz = np.sin(agnle_el)  # 光源对z 轴的影响

        # 设置光源归一化处理
        light = 255 * (dx * light_x + dy * light_y + dz * light_z)
        light = light.clip(0, 255)

        # 重新构建图像
        image = Image.fromarray(light.astype('uint8'))
        image.save(dir_path + '/手绘图像.jpg')
        self.finished.emit(True)
        print('手绘图像绘制完成!')

主要代码块实现都在上面了,下面将展示完整的代码

完整代码

# -*- coding:utf-8 -*-
# @author Python 集中营
# @date 2022/2/10
# @file test2.py

# done

# 手绘图片生成器:以雪容融为例一键生成...

# 手绘图片生成器可以将导入的彩色图片通过python分析光源、灰度等操作生成手绘图片。

# 其中绘图用到的第三方库只有两个,主要的还是Pillow图像处理库,还有就是numpy科学计算库用于一些数组计算等的操作。

# 将第三方的处理库导入到代码块中
from PIL import Image  # 图像处理模块
import numpy as np  # 科学计算库

# PyQt5界面制作及样式、核心组件
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

# 应用基础操作相关
import sys
import os

# 创建用于专门手绘图像的子线程类,将UI界面的处理逻辑和生成图像的处理逻辑分开不至于产生无响应的卡死状态。
class WorkThread(QThread):
    finished = pyqtSignal(bool)

    def __init__(self, parent=None):
        super(WorkThread, self).__init__(parent)
        self.parent = parent
        self.working = True

    def __del__(self):
        self.working = False
        self.wait()

    def run(self):
        # 源图片路径
        sou_im_path = self.parent.sou_im_path.text().strip()
        # 存储路径
        dir_path = self.parent.dir_path.text().strip()
        if sou_im_path == '' or dir_path == '':
            self.finished.emit(True)
            return
        # 打开需要进行转的图像,并进行参数设置,取出来的参数主要图像的一些梯度值。最后进行数组保存。
        vals = np.asarray(Image.open(sou_im_path).convert('L')).astype('float')

        '''图像参数处理'''
        depth = 12.0  # 设置初始化深度
        gray_vals = np.gradient(vals)  # 提取图像灰度的梯度值
        gray_x, gray_y = gray_vals  # 单独提取横坐标与纵坐标的灰度值
        print('当前横坐标的灰度值:', gray_x)
        print('当前纵坐标的灰度值:', gray_y)

        # 重新设置横坐标合纵坐标的灰度值
        gray_x = gray_x * depth / 100.0
        gray_y = gray_y * depth / 100.0

        # 根据numpy.sqrt()函数计算横坐标和纵坐标灰度值的平方根
        gray_sqrt = np.sqrt(gray_x ** 2 + gray_y ** 2 + 1.0)

        # 重新计算X轴、Y轴、Z轴的光源
        light_x = gray_x / gray_sqrt
        light_y = gray_y / gray_sqrt
        light_z = 1.0 / gray_sqrt

        # 计算光源的方位角度、俯视角度
        agnle_el = np.pi / 2.2  # 俯视角度
        agnle_az = np.pi / 4.  # 方位角度

        # 分别计算光源对X轴、Y轴、Z轴的影响
        dx = np.cos(agnle_el) * np.cos(agnle_az)  # 光源对x 轴的影响
        dy = np.cos(agnle_el) * np.sin(agnle_az)  # 光源对y 轴的影响
        dz = np.sin(agnle_el)  # 光源对z 轴的影响

        # 设置光源归一化处理
        light = 255 * (dx * light_x + dy * light_y + dz * light_z)
        light = light.clip(0, 255)

        # 重新构建图像
        image = Image.fromarray(light.astype('uint8'))
        image.save(dir_path + '/手绘图像.jpg')
        self.finished.emit(True)
        print('手绘图像绘制完成!')

# UI界面的整体部分代码块,UI界面的设计比较简单。效果在下面的图片展示。

class HandImage(QWidget):
    def __init__(self):
        super(HandImage, self).__init__()
        self.init_ui()

    def init_ui(self):
        '''
        UI界面组件及布局
        :return:
        '''
        self.setWindowTitle('手绘图片生成器   公众号:[Python 集中营]')
        self.setWindowIcon(QIcon('手绘图标.ico'))

        self.setFixedWidth(500)

        self.sou_im_path = QLineEdit()
        self.sou_im_path.setReadOnly(True)

        self.sou_im_path_btn = QPushButton()
        self.sou_im_path_btn.setText('源图片')
        self.sou_im_path_btn.clicked.connect(self.sou_im_path_btn_clk)

        self.dir_path = QLineEdit()
        self.dir_path.setReadOnly(True)

        self.dir_path_btn = QPushButton()
        self.dir_path_btn.setText('存储')
        self.dir_path_btn.clicked.connect(self.dir_path_btn_clk)

        self.start_btn = QPushButton()
        self.start_btn.setText('开始绘制图像')
        self.start_btn.clicked.connect(self.start_btn_clk)

        grid = QGridLayout()
        grid.addWidget(self.sou_im_path, 0, 0, 1, 1)
        grid.addWidget(self.sou_im_path_btn, 0, 1, 1, 1)
        grid.addWidget(self.dir_path, 1, 0, 1, 1)
        grid.addWidget(self.dir_path_btn, 1, 1, 1, 1)
        grid.addWidget(self.start_btn, 2, 0, 1, 2)

        self.thread_ = WorkThread(self)
        self.thread_.finished.connect(self.finished)

        self.setLayout(grid)

    # UI界面上的槽函数

    def sou_im_path_btn_clk(self):
        '''
        选择源图片并设置路径
        :return:
        '''
        im_path = QFileDialog.getOpenFileName(self, os.getcwd(), '打开图片', 'Image File(*.jpg);;Image File(*.png)')
        self.sou_im_path.setText(im_path[0])

    def dir_path_btn_clk(self):
        '''
        选择存储路径并设置路径
        :return:
        '''
        dir_path = QFileDialog.getExistingDirectory(self, os.getcwd(), '选择路径')
        self.dir_path.setText(dir_path)

    def start_btn_clk(self):
        '''
        开始按钮绑定的槽函数
        :return:
        '''
        self.start_btn.setEnabled(False)
        self.thread_.start()

    def finished(self, finished):
        '''
        用于子线程传递完成信号的槽函数
        :param finished: 信号变量
        :return:
        '''
        if finished is True:
            self.start_btn.setEnabled(True)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = HandImage()
    main.show()
    sys.exit(app.exec_())

以上就是Python+PyQT5实现手绘图片生成器的详细内容,更多关于Python PyQT5手绘图片生成器的资料请关注我们其它相关文章!

(0)

相关推荐

  • 利用Python制作百度图片下载器

    前段时间写了一个百度图片下载器,结果发现有很多人需要使用.说实话之前写的那一款百度图片下载器比较LOW,今天刚好有时间就做了一下升级. 更新了两个BUG,一个是图片下载达到几千张的时候就没有图片可以下载了.另一个是下载进度不能实时的展示出来不知道下载到什么程度了. 同样的,我们先把需要的第三方库导入进来. '''UI界面相关的库''' from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import

  • Python编程利用Numpy和PIL库将图片转化为手绘

    目录 主要采用的技术点 读取图片,转化为数组 计算 x,y,z 轴梯度值,归一化 加入光源效果 导出图片,并保存 主要采用的技术点 Python + Numpy + PIL 在正文代码开始前,大家先看看最初原图和转换手绘风图片前后对比. 当然了,我先查了手绘的三个基本特点: 图片可单通道灰度图 边缘线条较重可当成黑色,相同或相近像素值趋向白色 光源效果下,灰度变化类似于人类视觉的远近 下面开始介绍,手绘照实现步骤: 读取图片,转化为数组 因为要对图像的像素计算,可以先把图片先转化为数组.代码如下

  • 基于PyQt5制作一个gif动态图片生成器

    这个小工具制作的目的是为了将多张图片组合后生成一张动态的GIF图片.设置界面化的操作,只需要将选中的图片导入最后直接生成动态图片. 导入界面相关的第三方库 from PyQt5.QtWidgets import * from PyQt5.QtGui import * 动态图片处理模块 import imageio 应用操作相关库 import sys import os from datetime import datetime 这是用图片生成器生成的一张GIF图片,大家在生成时尽量选择两张大小

  • PyQt5 实现百度图片下载器GUI界面

    通过 Pyqt5 实现一个界面化的下载器,在通过网络请求实现各种类型的图片的下载.可以通过界面上输入不同图片的关键字从而实现下载图片并将下载好的图片保存到自定义的文件路径中. 在介绍代码块内容之前,先来看一下需要用到的三方的 python 库. from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * import os from scripy_images import ScripyIm

  • python+pyqt5实现图片批量缩放工具

    批量修改图片大小好像用PS也可以,不过我不会,程序猿就用程序来解决. 这段时间学了下Python,很强大,之前一些不知道怎么处理的东西在Python里面都能找到解决方法. 工具界面如下图 这个工具需要用到第三方库 Pillow 和 Pyqt5,可通过命令行安装. pip install pillow pip install pyqt5 代码: #!-*-coding:utf-8-*- from PIL import Image import hashlib, os, sys from PyQt5

  • Python批量添加图片水印的实现

    目录 一.前言 二.文字水印 三.图片水印 一.前言 现在盗图是非常常见的事情,许多人在使用图片时都不会标注图片的出处或者提及作者,这个时候水印就是个很好的东西了.我们可以给图片添加水印后再分享出去,这样就可以让其它人知道图片作者相关的信息.今天我们就带大家来实现水印的添加. 二.文字水印 在添加水印的时候,我们比较常用的就是文字水印.比如@ZackSock.@juejin:ZackSock等.这种水印的添加非常简单,只需要使用到Pillow模块的添加文字的操作即可,代码如下: from PIL

  • Python+PyQT5实现手绘图片生成器

    手绘图片生成器可以将导入的彩色图片通过python分析光源.灰度等操作生成手绘图片. UI界面的整体部分代码块,UI界面的设计比较简单.效果在上面的图片展示. class HandImage(QWidget): def __init__(self): super(HandImage, self).__init__() self.init_ui() def init_ui(self): ''' UI界面组件及布局 :return: ''' self.setWindowTitle('手绘图片生成器

  • 使用python+Pyqt5实现串口调试助手

    python可以利用serial模块来和串口设备进行485或者232通讯. 当然,网上这类串口调试助手的小程序有很多,不过这些程序要么是要收费,只能试用30天,要么是不好用. 况且,别人写的程序,你只能使用,无法取出其中的数据来进行处理,所以,如果可以自己写一个程序,既方便使用,又可以随时随地使用其中的数据. 软件:python3.10pycharm2021硬件:window10电脑串口485设备(国产流量计)串口转usb线(电脑不带串口,只能转接) 准备好了后,就可以开始写程序了. 串口通讯程

  • python+pyqt5编写md5生成器

    本文实例为大家分享了python+pyqt5编写md5生成器的具体代码,供大家参考,具体内容如下 学了一下pyqt5,写一个小程序来实践一下. 下图是程序界面: 下面是代码: import hashlib, os, sys from PyQt5.QtGui import QFont, QIcon from PyQt5.QtWidgets import (QFileDialog, QGridLayout, QLineEdit, QTextEdit,QLabel, QWidget, QToolTip

  • Python实现手绘图效果实例分享

    首先我们来看看原图: 接着我们来看看效果图: 通过分析我们不难发现以下特征: 主要颜色为黑白灰 边界线条较重 相同或相近色趋于白色 略有光源效果 需要用到的库有: numpy PIL 代码实现: import numpy as np from PIL import Image baseImg = Image.open("./img/myimg2.jpg").convert("L")  # 这里放置你要手绘的图片原图 a = np.array(baseImg).ast

  • python PyQt5 爬虫实现代码

    搞一个图形化界面还是挺酷的,是吧 安装库什么的应该不用多说了吧.. 一般来说会让你把 designer.exe(编辑图形化界面的东西,跟vb差不多) 当作外部工具导入到 pycharm 界面里(这里不写了),其实就是打开方便点,不做也没什么关系,没有非要从pycharm打开,界面是这样的: 还要导入一个PyUIC 工具包,这个东西好像还是导入比较好,(写文件目录的时候可能由于安装的问题找不到那个文件,我刚开始也没找到,还不如直接在C盘搜索那个东西来的直接)不然挺麻烦的.UIC 是用来把你做的图形

  • 基于PyQt5制作一个数据图表生成器

    我的需求:手动配置X轴.Y轴.图表标题等参数自动通过Pyecharts模块生成可视化的html数据图表,并将浏览器图表展示到UI界面上. 制作出图表后的效果展示如下: 另外,生成后的图表结果会使用 html 的形式保存下来. 导入 UI 界面相关的 PyQt5 第三方模块库. from PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import * 若是使用PyQt5的版本是5.10.1以上,则需要单独安

  • Python PyQt5实现的简易计算器功能示例

    本文实例讲述了Python PyQt5实现的简易计算器功能.分享给大家供大家参考,具体如下: 这里剩下计算函数(self.calculator)未实现,有兴趣的朋友可以实现它 [知识点] 1.利用循环添加按钮部件,及给每个按钮设置信号/槽 2.给按钮设置固定大小:button.setFixedSize(QtCore.QSize(60,30)) 3.取事件的的发送者(此例为各个按钮)的文本: self.sender().text() [效果图] [源代码] import sys from PyQt

  • 关于python pyqt5安装失败问题的解决方法

    前言 最近在工作中遇到一个问题,python pyqt5在安装的时候居然提示失败了,无奈只能找解决的办法,发现网上有同样遇到这个问题的同学,所以就总结了解决的方法分享出来,下面话不多说了,来一起看看详细的介绍: 发现问题 以前装命令都是pip一条命令搞定,会自动安装依赖的库,但在安装pyqt5时却遇到了问题 在下载完pyqt5时,会提示找不到合适的SIP版本 Could not find a version that satisfies the requirement sip>=4.19 (fr

  • Python PyQt5标准对话框用法示例

    本文实例讲述了Python PyQt5标准对话框用法.分享给大家供大家参考,具体如下: 很全的Qt的标准对话框,包含QInputDialog.QColorDialog.QFontDialog.QMessageBox.QOpenFileDialog... 全部是由官网的C++版本,转换成PyQt5版本. 有些细节忽略了,因为实在不知怎么转换过来.捣鼓了一晚上,总算完成了,好累啊,不过很开心! 效果图: 完整代码: # -*- coding: utf-8 -*- from PyQt5.QtGui i

  • Python实现识别手写数字 Python图片读入与处理

    写在前面 在上一篇文章Python徒手实现手写数字识别-大纲中,我们已经讲过了我们想要写的全部思路,所以我们不再说全部的思路. 我这一次将图片的读入与处理的代码写了一下,和大纲写的过程一样,这一段代码分为以下几个部分: 读入图片: 将图片读取为灰度值矩阵: 图片背景去噪: 切割图片,得到手写数字的最小矩阵: 拉伸/压缩图片,得到标准大小为100x100大小矩阵: 将图片拉为1x10000大小向量,存入训练矩阵中. 所以下面将会对这几个函数进行详解. 代码分析 基础内容 首先我们现在最前面定义基础

随机推荐