PyQT5实现图像处理应用(含Windows7下完整打包方案)

news2024/12/26 11:45:02

目录

  • 1、任务概述
  • 2、环境安装
    • 2.1 创建虚拟环境
    • 2.2 安装依赖库
  • 3、程序开发
    • 3.1 框架搭建
    • 3.2 读取图像
    • 3.3 图像处理
  • 4、打包部署
  • 5、小结

1、任务概述

本篇博文将通过PyQT5来实现一个简单的图像处理应用,并完成打包部署。

本文开发平台:Windows10 64位系统。部署平台:Windows7 64位系统

具体实现效果如下:
在这里插入图片描述
由于PyQT依赖Python,因此在学习下面的章节前,请先安装好Python。本教程使用的Python版本为3.8.0(由于部署平台为Windows7,因此不能使用Python3.8以上版本)。

2、环境安装

2.1 创建虚拟环境

为方便后面打包部署,我们将相关Python的依赖库存放到虚拟环境中,因此需要先创建一个虚拟环境。

Windows平台下的虚拟环境需要使用第三方工具virtualenv来创建,打开命令终端,输入下面的命令即可完成安装:

pip install virtualenv -i https://mirror.baidu.com/pypi/simple

创建一个项目文件夹demo,我们现在的目标就是在这个demo项目中创建python虚拟环境,这个虚拟环境是专门为demo项目成立的。在命令行终端中通过cd命令进入项目目录中(假设demo文件夹位于D:\code目录下):

输入下面的命令用来创建名为venv的虚拟环境:

virtualenv env

这样我们就在demo文件夹下有了一个名为env的子文件夹,它保存了一个全新的虚拟环境,其中有一个私有的Python解释器位于demo/env/Scripts,在该虚拟环境中安装的python包会存放在demo/env/Lib路径下。

最后,在Windows平台下激活并使用该虚拟环境:

env\Scripts\activate

如下图所示:
在这里插入图片描述
成功激活之后,虚拟环境解释器的路径就被加入PATH中,但这种改变不是永久的,他只会影响当前的命令行终端。

2.2 安装依赖库

在虚拟环境中安装pyqt5和opencv:

pip install pyqt5 opencv-python -i https://mirror.baidu.com/pypi/simple

其中pyqt5用于开发界面程序,而opencv用于图像处理算法操作。

3、程序开发

3.1 框架搭建

在demo文件夹下面创建一个名为main.py的脚本,内容如下:

# -*- coding:utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QLabel, QFileDialog
from PyQt5.QtCore import QRect,QCoreApplication,Qt
from PyQt5.QtGui import QPixmap,QImage

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        # 调整窗体
        self.resize(500, 300)  # 主窗体宽高设置
        self.setWindowTitle("示例程序")  # 主窗体名称
        # 创建2个图像标签
        self.preImgLabel = QLabel("", self)
        self.preImgLabel.setGeometry(QRect(30, 30, 200, 200))
        self.preImgLabel.setStyleSheet("background-color: rgb(232, 232, 232);")
        self.preImgLabel.setScaledContents(True)
        self.aftImgLabel = QLabel("", self)
        self.aftImgLabel.setGeometry(QRect(270, 30, 200, 200))
        self.aftImgLabel.setStyleSheet("background-color: rgb(232, 232, 232);")
        self.aftImgLabel.setScaledContents(True)
        # 创建2个按钮组件
        self.chooseBtn = QPushButton("选择图片", self)
        self.chooseBtn.clicked.connect(self.choosePic)
        self.chooseBtn.setGeometry(QRect(170, 250, 60, 30))
        self.processBtn = QPushButton("图片处理", self)
        self.processBtn.clicked.connect(self.imgProcess)
        self.processBtn.setGeometry(QRect(270, 250, 60, 30))
        
        self.imgName = ''

    def choosePic(self):
        """选择图片"""
        pass
        
    def imgProcess(self):
        """图片处理"""
        pass
        self.aftImgLabel.setStyleSheet("border: 2px solid red")

if __name__ == "__main__":
    """程序主入口"""
    QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) # 设置屏幕分辨率自适应
    app = QApplication(sys.argv)  # 创建应用
    main = MainWindow()  # 创建主窗体
    main.show()          # 显示主窗体
    sys.exit(app.exec()) # 进入主窗体生命周期

上述脚本创建了一个主窗体,包括2个label组件、2个按钮组件,同时对两个按钮组件创建了对应的槽函数choosePic和imgProcess。

运行该脚本,效果如下图所示:
在这里插入图片描述
可以看到,使用PySide6来开发界面程序非常简单,代码量很少。

3.2 读取图像

下面完善main.py文件的代码,单击选择图片按钮可以浏览本地计算机里的图像,并且将图像显示到左侧图像面板中。

具体的,只需要修改choosePic函数即可:

def choosePic(self):
    """选择图片"""
    self.imgName, _ = QFileDialog.getOpenFileName(self, "打开图片", "", "*.jpg;;*.png;;All Files(*)")
    if self.imgName == '':
        return
    pix = QPixmap(self.imgName)
    self.preImgLabel.setPixmap(pix)
    self.preImgLabel.setStyleSheet("border: 2px solid blue")

3.3 图像处理

这里我们将使用opencv完成图像gamma矫正,提升图像整体亮度,完整代码如下:

# -*- coding:utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QLabel, QFileDialog
from PyQt5.QtCore import QRect,QCoreApplication,Qt
from PyQt5.QtGui import QPixmap,QImage
import cv2
import numpy as np


def adjust_gamma(image, gamma=1.0):
    '''gamma矫正'''
    invGamma = 1.0 / gamma
    table = np.array(
        [((i / 255.0) ** invGamma) * 255 for i in np.arange(0, 256)]
    ).astype("uint8")
    return cv2.LUT(image, table)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        # 调整窗体
        self.resize(500, 300)  # 主窗体宽高设置
        self.setWindowTitle("示例程序")  # 主窗体名称
        # 创建2个图像标签
        self.preImgLabel = QLabel("", self)
        self.preImgLabel.setGeometry(QRect(30, 30, 200, 200))
        self.preImgLabel.setStyleSheet("background-color: rgb(232, 232, 232);")
        self.preImgLabel.setScaledContents(True)
        self.aftImgLabel = QLabel("", self)
        self.aftImgLabel.setGeometry(QRect(270, 30, 200, 200))
        self.aftImgLabel.setStyleSheet("background-color: rgb(232, 232, 232);")
        self.aftImgLabel.setScaledContents(True)
        # 创建2个按钮组件
        self.chooseBtn = QPushButton("选择图片", self)
        self.chooseBtn.clicked.connect(self.choosePic)
        self.chooseBtn.setGeometry(QRect(170, 250, 60, 30))
        self.processBtn = QPushButton("图片处理", self)
        self.processBtn.clicked.connect(self.imgProcess)
        self.processBtn.setGeometry(QRect(270, 250, 60, 30))
        
        self.imgName = ''

    def choosePic(self):
        """选择图片"""
        self.imgName, _ = QFileDialog.getOpenFileName(self, "打开图片", "", "*.jpg;;*.png;;All Files(*)")
        if self.imgName == '':
            return
        pix = QPixmap(self.imgName)
        self.preImgLabel.setPixmap(pix)
        self.preImgLabel.setStyleSheet("border: 2px solid blue")
        

    def imgProcess(self):
        """图片处理"""
        # 读取图像
        img = cv2.imread(self.imgName)  # OpenCV 读取图像
        if img is None:
            print('图像读取失败')
            return
        # gamma矫正
        img = adjust_gamma(img, gamma=1.8)
        # 转qt格式
        qtImg = QImage(img.data, img.shape[1], img.shape[0], QImage.Format_RGB888).rgbSwapped() 
        self.aftImgLabel.setPixmap((QPixmap.fromImage(qtImg)))  
        self.aftImgLabel.setStyleSheet("border: 2px solid red")


if __name__ == "__main__":
    """程序主入口"""
    QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) # 设置屏幕分辨率自适应
    app = QApplication(sys.argv)  # 创建应用
    main = MainWindow()  # 创建主窗体
    main.show()          # 显示主窗体
    sys.exit(app.exec()) # 进入主窗体生命周期

运行效果如本文开篇图片所示。

4、打包部署

我们最终希望交给用户是一个纯粹的exe可执行文件(可以包含一些dll之类的动态库或配置文件),用户不需要安装Python依赖,直接双击就可以运行展示。下面我们来实现最后的这个环节。

首选安装打包工具:

pip install pyinstaller auto-py-to-exe -i https://mirror.baidu.com/pypi/simple

在终端中运行:auto-py-to-exe,会自动打开浏览器,然后进入打包部署配置页面。对于本项目按照下图所示进行勾选即可:
在这里插入图片描述
最后单击执行即可。打包好的程序位于demo/output/main文件夹中,如下图所示:
在这里插入图片描述
其中main.exe就是最后的可执行程序,_internal就是该程序的依赖库。部署时将整个main文件夹拷贝到部署机器上运行即可。

部署运行时部分机器可能会出现下图所示错误:
在这里插入图片描述
这里只需要下载一个64位的api-ms-win-core-path-l1-1-0.dll文件然后将其拷贝到输出目录的main/_internal文件夹下面即可。

5、小结

使用PyQT开发界面程序可以充分利用python简洁易用的特性,开发效率较高。缺点就是部署文件夹比较大,并且代码的安全性(版权)要比C++等弱一些。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Vue3】2-6 : 计算属性与侦听器区别与原理(一)

本书目录:点击进入 一、计算属性 - computed:{} 1.1 目的 1.2 写法 代码 二、特征 2.1 调用时当属性调用 2.2 缓存 2.3 默认只读 2.4 可赋值:需要定义成对象,并写get,set方法 (类似于java) 三、原…

《More Effective C++》学习

条款1:仔细区别 pointers 和 references 引用应该被初始化,指针可以不被初始化。不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。指针与引用的另一个重要的不同是指针可以被重新赋值…

IDC MarketScape 低/无代码厂商评估:得帆信息被评为领导者

《IDC MarketScape:中国低代码/无代码开发平台2023年厂商评估 》报告正式发布。报告从战略与能力两大方向,在产品和功能、客户交付服务能力、营销和销售能力、伙伴与生态、商业战略模式等多个维度对国内低/无代码厂商进行全面评估。 得帆信息凭借战略与能力双项领先…

电子电器架构网络演化 —— 车载以太网TSN

电子电器架构网络演化 —— 车载以太网TSN 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消…

VBA中类的解读及应用第八讲:实现定时器功能的自定义类事件

《VBA中类的解读及应用》教程【10165646】是我推出的第五套教程,目前已经是第一版修订了。这套教程定位于最高级,是学完初级,中级后的教程。 类,是非常抽象的,更具研究的价值。随着我们学习、应用VBA的深入&#xff0…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -用户信息修改实现

锋哥原创的uniapp微信小程序投票系统实战: uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

如何通过bat文件启动应用程序

说明:在windows上,任何应用程序都是通过.exe启动的。我们可以通过配置环境的方式,将应用程序的路径配置到环境变量path变量里,这样就可以使用cmd窗口,敲应用程序的名称来启动应用程序。 如下,可启动wps应用…

Vue-8、Vue事件处理

1、点击事件 <!DOCTYPE html> <html lang"en" xmlns:v-model"http://www.w3.org/1999/xhtml" xmlns:v-bind"http://www.w3.org/1999/xhtml"xmlns:v-on"http://www.w3.org/1999/xhtml"> <head><meta charset&quo…

Nginx location 配置 - Part 2

接上文 链接: Nginx 简介和入门 - part1 上文 我们简单地在 nginx 创建了3个虚拟主机&#xff0c; 虽然这个3个主机都是用占用80端口 但是我们可以用不同的域名来实现区分访问3台虚拟主机。 但是&#xff0c; 实际项目上&#xff0c; 我们更加多地会使用location 配置而不是…

Docker实战08|Docker管道及环境变量识别

上一篇文章中&#xff0c;讲解了如何通过Go语言实现对Docker Cgroup的资源限制 具体文章可见《Docker就应该这么学-07》 有需要的小伙伴可以回顾一下。 接下来本文会详细介绍一下Docker 管道及环境变量识别 管道及环境变量识别 获取代码 git clone https://gitee.com/mjr…

物理机部署三节点Kafka集群

一、部署Kafka集群 官方下载地址&#xff1a;http://kafka.apache.org/downloads.html上传安装包到102的/opt/software目录下 解压安装包到/opt/module/目录下&#xff0c;修改解压包名为kafka 修改config目录下的配置文件server.properties内容 #broker的全局唯一编号&#…

【漏洞复现】ActiveMQ文件上传漏洞(CVE-2016-3088)

Nx01 产品简介 Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件。ActiveMQ是消息队列服务&#xff0c;是面向消息中间件&#xff08;MOM&#xff09;的最终实现&#xff0c;它为企业消息传递提供高可用、出色性能、可扩展、稳定和安全保障。 Nx02 漏洞描述 Ap…

excel统计分析——LSD多重比较

参考资料&#xff1a;生物统计学 一篇教你搞定显著性差异分析abcd字母标记法 LSD&#xff08;least significant difference&#xff0c;最小显著差数法&#xff09;是R. A. Fisher提出的&#xff0c;又称为Fisher LSD检验法&#xff0c;是最早用于检验各组均数间两两差异的方…

Unity | 渡鸦避难所-6 | 有限状态机控制角色行为逻辑

1 有限状态机简介 有限状态机&#xff08;英语&#xff1a;finite-state machine&#xff0c;缩写&#xff1a;FSM&#xff09;&#xff0c;简称状态机&#xff0c;是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型 在游戏开发中应用有限状态机&#xff…

NoSQL概述与Redis入门-redis安装与测试

一、Nosql概述 1、为什么使用Nosql 1、单机Mysql时代 90年代,一个网站的访问量一般不会太大&#xff0c;单个数据库完全够用。随着用户增多&#xff0c;网站出现以下问题 数据量增加到一定程度&#xff0c;单机数据库就放不下了数据的索引&#xff08;B Tree&#xff09;,一个…

38.深入MySQL

深入MySQL 索引 索引是关系型数据库中用来提升查询性能最为重要的手段。关系型数据库中的索引就像一本书的目录&#xff0c;我们可以想象一下&#xff0c;如果要从一本书中找出某个知识点&#xff0c;但是这本书没有目录&#xff0c;这将是意见多么可怕的事情&#xff01;我们…

【JaveWeb教程】(16) SpringBootWeb之 分层解耦 详细代码示例讲解

目录 SpringBootWeb请求响应3. 分层解耦3.1 三层架构3.1.1 介绍3.1.2 代码拆分 3.2 分层解耦3.2.1 耦合问题3.2.2 解耦思路 3.3 IOC&DI3.3.1 IOC&DI入门3.3.2 IOC详解3.3.2.1 bean的声明3.3.2.2 组件扫描 3.3.3 DI详解 SpringBootWeb请求响应 3. 分层解耦 3.1 三层架…

【UE Niagara学习笔记】01 - 浮动的蒲公英

目录 效果 步骤 一、创建材质 二、创建Niagara粒子 2.1 创建Niagara模板 2.2 通过用户参数设置粒子大小 2.3 设置数量、风速、透明度变化 2.4 设置粒子旋转 效果 步骤 一、创建材质 1. 在虚幻商城中把“Realistic Starter VFX Pack Vol 2”添加到项目中&#xff…

机器学习周刊 第4期:动手实战人工智能、计算机科学热门论文、免费的基于ChatGPT API的安卓端语音助手、每日数学、检索增强 (RAG) 生成技术综述

LLM开发者必读论文&#xff1a;检索增强&#xff08;RAG&#xff09;生成技术综述&#xff01; 目录&#xff1a; 1、动手实战人工智能 Hands-on Al2、huggingface的NLP、深度强化学习、语音课3、Awesome Jupyter4、计算机科学热门论文5、LLM开发者必读论文:检索增强 (RAG) 生…

用css给宽高不固定的矩形画对角线

.kong{width: 200rpx;height: 76rpx;background: linear-gradient(to bottom right, #E5E5E5 0%, rgba(0, 0, 0, 0.1) calc(50% - 1px),#175CFF 50%, rgba(0, 0, 0, 0.1) calc(50% 1px),rgba(0, 0, 0, 0.1) 100%);}参考&#xff1a; https://blog.csdn.net/weixin_38779534/a…