PyQt5编写的一个简易图像处理软件

文章目录

    • 1. 简介
    • 2. 准备工作
    • 3. 主界面设计
    • 4. 功能构建
    • 5. 总结

1. 简介

通过编写简易图像处理软件,你可以学习如何使用 PyQt5 构建用户界面,以及如何与用户交互。同时,你还可以学习图像处理技术,如图像读取、傅里叶变换、滤波、增强、噪声添加等。如果你有一个更大的图像处理项目想法,但还没有明确的实现方案,可以先从简易软件开始。通过构建简易图像处理软件,你可以快速验证自己的想法,确定项目的方向和功能。这里帮你从零构建一个简易的图像处理软件,并具有很强的拓展功能

2. 准备工作

  • PyQt5 安装 (参考文章:PyQt5的基本安装与使用)
  • cv2 安装
pip install opencv-python
  • numpy 安装

3. 主界面设计

程序如下

import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QMenu,QAction, QMainWindow, QTableWidget, QTextEdit, QFrame)
from PyQt5.QtCore import Qt# 创建一个继承自 QWidget 的主窗口类
class MainWindow(QWidget):def __init__(self):super().__init__()# 初始化界面self.initUI()# 初始化界面的方法def initUI(self):# 设置窗口标题和大小self.setWindowTitle("数字图像处理")self.resize(1000, 600)# 创建一个垂直布局作为全局布局mainLayout = QVBoxLayout()# 创建布局1:文件路径布局(水平布局),包含路径标签,路径文本框,文件打开按钮layout_1 = QHBoxLayout()root_label = QLabel("文件路径: ", self)  # 路径标签self.root_line = QLineEdit(self)  # 路径文本框,用于显示路径self.file_open_button = QPushButton("选择", self)  # 文件打开按钮layout_1.addWidget(root_label)  # 添加组件到layout_1中layout_1.addWidget(self.root_line)layout_1.addWidget(self.file_open_button)# 添加水平分割线horizontal_line = QFrame()horizontal_line.setFrameShape(QFrame.HLine)horizontal_line.setFrameShadow(QFrame.Sunken)# 创建布局2:文件处理按钮(水平布局),包含傅里叶变换按钮和添加噪声按钮layout_2 = QHBoxLayout()self.fft_button = QPushButton("傅里叶变换", self)  # 傅里叶变换按钮self.noise_button = QPushButton("添加噪声", self)  # 添加噪声按钮layout_2.addWidget(self.fft_button)  # 添加组件到layout_2中layout_2.addWidget(self.noise_button)# 创建布局3:图片显示和处理区域(水平布局),左边用于显示原始图片,右边用于显示处理后的图片和处理信息layout_3 = QHBoxLayout()# 布局3左侧:用于显示原始图片和图片信息的垂直布局layout_3_left = QVBoxLayout()ori_img_label = QLabel("原始图片", self)  # 原始图片标签self.ori_img_display = QLabel(self)  # 原始图片显示标签self.ori_img_display.setFixedSize(256, 256)  # 设置图片显示标签的大小self.ori_img_info = QTextEdit(self)  # 文本框用于显示原始图片信息self.ori_img_info.setPlaceholderText("原始图片信息")  # 设置文本框的占位符文本layout_3_left.addWidget(ori_img_label)  # 添加组件到layout_3_left中layout_3_left.addWidget(self.ori_img_display)layout_3_left.addWidget(self.ori_img_info)# 添加竖直分割线vertical_line = QFrame()vertical_line.setFrameShape(QFrame.VLine)vertical_line.setFrameShadow(QFrame.Sunken)# 布局3右侧:用于显示处理后图片和处理信息的垂直布局layout_3_right = QVBoxLayout()pro_img_label = QLabel("处理后图片", self)  # 处理后图片标签self.pro_img_display = QLabel(self)  # 处理后图片显示标签self.pro_img_display.setFixedSize(256, 256)  # 设置图片显示标签的大小self.pro_img_info = QTextEdit(self)  # 文本框用于显示处理后图片信息self.pro_img_info.setPlaceholderText("处理后图片信息")  # 设置文本框的占位符文本layout_3_right.addWidget(pro_img_label)  # 添加组件到layout_3_right中layout_3_right.addWidget(self.pro_img_display)layout_3_right.addWidget(self.pro_img_info)# 将左右布局添加到布局3中layout_3.addLayout(layout_3_left)layout_3.addWidget(vertical_line)layout_3.addLayout(layout_3_right)# 将各个布局添加到全局布局中mainLayout.addLayout(layout_1)mainLayout.addLayout(layout_2)mainLayout.addWidget(horizontal_line)mainLayout.addLayout(layout_3)# 设置全局布局self.setLayout(mainLayout)if __name__ == "__main__":app = QApplication(sys.argv)ex = MainWindow()ex.show()sys.exit(app.exec_())

这个程序创建了一个数字图像处理软件的界面,包括了文件路径选择、图像处理按钮、原始图片显示、处理后图片显示等功能。界面使用了 PyQt5 的布局管理器来实现各个组件的排列。运行结果得到如下界面

在这里插入图片描述

4. 功能构建

程序如下

import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QMenu,QAction, QMainWindow, QTableWidget, QTextEdit, QFrame, QFileDialog)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QImageReader, QImage
from mainLayout import MainWindow  # 导入了自定义的 MainWindow 类
import cv2
import numpy as np# 继承了自定义的 MainWindow 类
class ImageProcess(MainWindow):def __init__(self):super().__init__()# 定义了一些属性来存储图像路径、原始图像和处理后的图像self.imagePaths = []self.originalImages = []self.processedImages = []# 连接了按钮的信号槽self.file_open_button.clicked.connect(self.file_open)self.fft_button.clicked.connect(self.fft_image)self.noise_button.clicked.connect(self.noise_add)# 打开文件对话框,加载图像文件,并在界面中显示原始图像和图像信息def file_open(self):file_path, _ = QFileDialog.getOpenFileName(self, "Open Image", '','Image Files (*.jpg *.png *.bmp *.jpeg *.tif)')if file_path:self.imagePaths.append(file_path)self.root_line.setText(file_path)pixmap = QPixmap(file_path)self.ori_img_display.setPixmap(pixmap)self.ori_img_display.setScaledContents(True)self.ori_img = cv2.imread(file_path)self.originalImages.append(self.ori_img)height, width, channels = self.ori_img.shapeori_img_data_type = self.ori_img.dtypeori_info = f"Original Image Information: \n" \f"Image dimesions: {height} x {width} \n" \f"Number of channels: {channels} \n" \f"Data type: {ori_img_data_type}"self.ori_img_info.setPlainText(ori_info)# 对图像进行傅里叶变换,并在界面中显示变换后的图像和图像信息def fft_image(self):ori_img = cv2.imread(self.imagePaths[-1], cv2.IMREAD_GRAYSCALE)ori_img_float32 = np.float32(ori_img)dft_ori_img = cv2.dft(ori_img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)dft_shift = np.fft.fftshift(dft_ori_img)magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))magnitude_spectrum = magnitude_spectrum / np.max(magnitude_spectrum)# 创建 QImage 对象,并在界面中显示变换后的图像和图像信息self.processed_image = np.clip(magnitude_spectrum * 255, 0, 255).astype(np.uint8)self.processedImages.append(self.processed_image)image = QImage(self.processed_image, magnitude_spectrum.shape[1], magnitude_spectrum.shape[0],QImage.Format_Grayscale8)pixmap = QPixmap.fromImage(image)self.pro_img_display.setPixmap(pixmap)self.pro_img_display.setScaledContents(True)pro_info = f"Processed Image Information: \n" \f"Image Operations: 2D Fourier transform \n" \self.pro_img_info.setPlainText(pro_info)# 添加高斯噪声,并在界面中显示添加噪声后的图像和图像信息def noise_add(self):ori_img = cv2.imread(self.imagePaths[-1], cv2.IMREAD_GRAYSCALE)ori_img_float32 = np.float32(ori_img)noise = np.zeros_like(ori_img_float32, np.float32)cv2.randn(noise, mean=0, stddev=25)noisy_image = cv2.add(ori_img_float32, noise)noisy_image = np.clip(noisy_image, 0, 255).astype(np.uint8)image = QImage(noisy_image, noisy_image.shape[1], noisy_image.shape[0],QImage.Format_Grayscale8)pixmap = QPixmap.fromImage(image)self.pro_img_display.setPixmap(pixmap)self.pro_img_display.setScaledContents(True)pro_info = f"Processed Image Information: \n" \f"Image Operations: Add Gaussian Noise \n" \self.pro_img_info.setPlainText(pro_info)# 创建应用程序实例,并运行应用程序
if __name__ == "__main__":app = QApplication(sys.argv)ex = ImageProcess()ex.show()sys.exit(app.exec_())

这个程序通过 PyQt5 构建了一个简易的图像处理软件。程序中主要包含了以下功能:

  1. 打开图像文件对话框,加载图像文件,并在界面中显示原始图像和图像信息。
  2. 对图像进行傅里叶变换,并在界面中显示变换后的图像和图像信息。
  3. 添加高斯噪声,并在界面中显示添加噪声后的图像和图像信息。

其中,图像处理操作通过 OpenCV 库实现。运行结果如下所示

在这里插入图片描述

5. 总结

这个界面设计采用了垂直和水平布局,使得各个组件排列有序,用户操作清晰明了,易于理解和使用。界面包含了文件路径选择、图像处理按钮、原始图片显示、处理后图片显示等功能,涵盖了基本的图像处理流程。通过按钮点击和文件路径选择,实现了用户与软件的交互,用户可以选择图片文件并进行相应的图像处理操作。用户也可以根据自己需要自行拓展功能。如果需要这个界面的源码,就帮忙点点关注,在评论区留言,我给你们私信下载链接。

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

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

相关文章

Ansible自动化运维中的User用户管理模块应用详解

作者主页:点击! Ansible专栏:点击! 创作时间:2024年5月14日14点12分 在Ansible中,user 模块主要用于管理系统用户账户。它可以创建、修改、删除用户,并管理用户的属性,比如密码、…

玩机进阶教程------MTK机型重置账号 去除FRP 去除开机密码 清除数据的几种方法步骤解析

目前的机型不管是高通芯片还是MTK芯片。都有账号类限制。包含云账号 frp账号和开机密码等等,他们在线刷包中对应的分区是不同的。例如针对开机图案密码这些,有些机型靠简单的恢复出厂是无效果的,其实对应的解决方法很简单。今天将针对MTK芯片机型的账号问题做个步骤解析。 …

Selenium 自动化 —— 四种等待(wait)机制

更多关于Selenium的知识请访问CSND论坛“兰亭序咖啡”的专栏:专栏《Selenium 从入门到精通》 ​ 目录 目录 需要等待的场景 自己实现等待逻辑 Selenium 提供的三种等待机制 隐式等待(Implicit Waits) 隐式等待的优点 隐式等待的缺点 …

pycharm如何有效读取到win10设置的环境变量

参考链接: 参考文章 该参考文章的第一种方法:设置win10环境变量。 在设置完环境变量后,在pycharm终端上不能有效读取到刚刚设置的环境变量的,需要启动win的cmd,在项目路径下执行脚本。如下所示的对比: cm…

金航标kinghelm萨科微slkor公司发展和品牌传播

为了金航标kinghelm萨科微slkor公司发展和品牌传播,推出了”金航标每日芯闻“与“萨科微每日芯闻“栏目,影响力非常好。这一构想并非一时的灵光乍现,而是经过深思熟虑和充分调研的结果。制定该栏目的模板时候时,就明确了要求语音版…

棒材直线度测量仪 专为圆形产品研发设计 在线无损检测

棒材直线度测量仪采用了先进的技术,能够实现在线无损检测,为生产过程提供了极大的便利。专为圆形产品设计,它能够精确测量棒材的米直线度及外径、椭圆度尺寸,为质量控制提供可靠的数据支持。 在线直线度测量仪不仅具有出色的性能…

Web前端开发 - 4 - CSS3动画

CSS3动画 一、 设计2D变换二、 设计3D变换三、 设计过渡动画四、设计帧动画 一、 设计2D变换 transform : none | <transform-function> /* <transform-function> 设置变换函数&#xff0c;可以是一个或多个变换函数列表。函数包括: martrix(x缩放,x倾斜,y倾斜,y…

刷代码随想录有感(66):回溯算法——组合问题的优化(剪枝)

代码&#xff1a;将for循环中i的搜索范围进行缩小&#xff0c;免去多余的不可能符合条件的操作。 for(int i start; i < n-(k-tmp.size())1;i) 实质是剪枝&#xff0c;拿n4,k4作比较&#xff1a; 显然结果只可能是[1,2,3,4]&#xff0c;选取顺序只可能是1-2-3-4&#xff…

c#多态性的应用

设计一个电脑游戏&#xff0c;游戏中有猪、牛、兔子、青蛙、鸭子等动物&#xff0c;这些动 物都继承于Vertebrata 类&#xff08;脊椎动物类&#xff09;&#xff0c;Vertebrata类有一个抽象方法Display()&#xff0c;每个动 物都从Vertebrata 类那里继承并重写了Display()方法…

windows下mysql5.6下载安装(多实例安装)

目录 1、下载 2、安装步骤 3、mysql多实例安装 1、下载 http://dev.mysql.com/downloads/windows/installer/5.6.html 2、安装步骤 我们采用自定义安装模式&#xff1a;选择32位或64位 默认即可&#xff1a; 说明&#xff0c;如果没有该页面就上一步&#xff0c;选择高级选…

OpenAI推出旗舰AI模型GPT-4o并免费开放

&#x1f989; AI新闻 &#x1f680; OpenAI推出旗舰AI模型GPT-4o并免费开放 摘要&#xff1a; OpenAI 未来的产品将以免费为优先&#xff0c;以让更多人使用为目标。OpenAI 发布了桌面版本的程序和更新后的 UI&#xff0c;更加简单自然。推出了新一代大模型 GPT-4o&#xf…

经典神经网络(8)GAN、CGAN、DCGAN、LSGAN及其在MNIST数据集上的应用

经典神经网络(8)GAN、CGAN、DCGAN、LSGAN及其在MNIST数据集上的应用 1 GAN的简述及其在MNIST数据集上的应用 GAN模型主导了生成式建模的前一个时代&#xff0c;但由于训练过程中的不稳定性&#xff0c;对GAN进行扩展需要仔细调整网络结构和训练考虑&#xff0c;因此GANs虽然在…

金融科技员工一年赚多少钱?富如恒生电子,穷如长亮科技

在本篇文章中&#xff0c;我们继续分析四家金融科技公司的数据&#xff0c;本次站在员工视角来看&#xff08;链接&#xff0c;这四家公司的更详细内容&#xff09;。 先说结论。 2023年&#xff0c;如果你是恒生电子的普通员工&#xff0c;那年薪在35万元&#xff1b;如果你在…

OSPF多区域通信基础实验

基本概念了解&#xff1a; 网络设备接口速率、 Ethernet 100MB GE 1000MB serial接口 1.544MB area 0 骨干区域&#xff08;backbone&#xff09; area 0area0.0.0.0 不是area 0 非骨干区域 ar area 256area 0.0.1.0 实验拓扑如下&#xff1a;要求PC1能够访问PC2 &#xff08;跨…

oracle多条重复数据,取最新的

1、原理讲解-可直接看2 筛选出最新的 SELECT * FROM ( SELECT t.*, ROW_NUMBER() OVER (PARTITION BY LOCALAUTHID ORDER BY LASTUPDATETIME DESC) AS rn FROM USER_LOCALAUTH_STATE t ) t WHERE t.rn 1; 解释&#xff1a; 这个序号是基于[LOCALAUTHID]字段进行分…

外网ip地址怎么获取?快解析

大家都清楚互联网是通过ip地址通信的&#xff0c;ip地址又分内网ip和外网ip。内网ip只能在内网使用&#xff1b;而外网ip作为电脑唯一标识&#xff0c;可在公网使用。那么外网ip地址怎么获取呢&#xff1f; 外网ip是网络运营商分配给用户的。目前最常见的两种上网方式一个是拉…

图文详解JUC:Wait与Sleep的区别与细节

目录 一.Wait() 二.Sleep() 三.总结Wait()与Sleep()的区别 一.Wait() 在Java中&#xff0c;wait() 方法是 Object类中的一个方法&#xff0c;用于线程间的协作。当一个线程调用wait() 方法时&#xff0c;它会释放对象的锁并进入等待状态&#xff0c;直到其他线程调用相同对…

JVM调优-调优原则和原理分析

1.写在前面 对于JVM调优这个话题&#xff0c;可能大部分程序员都听过这个名词。 但是绝大多数程序员&#xff0c;都没有真真实实去干过&#xff0c;都没有真实的实践过。也不懂得如何调优&#xff1f;不知道要调成怎么样&#xff1f; 那今天咋们就对这个话题来展开描述一下&…

洛谷 P3372:线段树 1 ← 分块算法模板(区间更新、区间查询)

【题目来源】https://www.luogu.com.cn/problem/P3372【题目描述】 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面两种操作&#xff1a; &#xff08;1&#xff09;将某区间每一个数加上 k。 &#xff08;2&#xff09;求出某区间每一个数的和。【输入格式】 第一行…

二叉树——初解

二叉树 树树的概念树的性质 二叉树二叉树的概念二叉树的性质二叉树的实现方式数组构建左孩子右兄弟法构建指针构建 树 树的概念 在计算机科学中&#xff0c;树&#xff08;Tree&#xff09;是一种重要的非线性数据结构&#xff0c;它由若干节点&#xff08;Node&#xff09;组…