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.rhkb.cn/news/327953.html

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

相关文章

【NR学习一】NR中的带宽、子载波间隔、PRB数量、FFT点数与采样率之间的关系

NR中的带宽、子载波间隔、PRB数量、FFT点数与采样率之间的运算关系 在5G NR(New Radio)系统设计中,带宽(Bandwidth)、子载波间隔(Subcarrier Spacing, SCS)、资源块(Resource Block…

仓库管理流程详解(附作业流程图)

仓库管理流程在企业的日常运营中至关重要。它不仅是物资流转的核心环节,更关乎着企业的运营效率、成本控制和客户服务水平。一个高效、规范的仓库管理流程能够确保货物从入库到出库的各个环节有序进行,减少资源浪费和时间成本,同时帮助企业实…

泽攸科技无掩模光刻机:引领微纳制造新纪元

在当今科技迅猛发展的时代,微纳制造技术正变得越来越重要。泽攸科技作为这一领域的先行者,推出了其创新的无掩模光刻机,这一设备在微电子制造、微纳加工、MEMS、LED、生物芯片等多个高科技领域展现出了其独特的价值和广泛的应用前景。 技术革…

数据分析(二)——导入外部数据,导入Excel数据,CSV文件,txt文件,HTML网页,数据抽取,DataFrame对象的loc属性与iloc属性

一.导入外部数据 1.导入.xIs或.xIsx文件 pd.read_ excel(io,sheet_ name,header) 1.1常用参数说明 ●io:表示.xIs或.xIsx文件路径或类文件对象 ●sheet name:表示工作表,取值如下表所示 ●header:默认值为0,取第一行的值为列名,数据为除列…

手撸XXL-JOB(四)——远程调用定时任务

Java Socket网络编程 网络编程是Java编程中的重要组成部分,包括服务端和客户端两部分内容。Socket是Java网络编程的基本组件之一,用于在应用程序之间提供双向通信,Socket提供了一种标准的接口,允许应用程序通过网络发送和接收数据…

数据中台管理系统原型

数据中台是一个通用性的基础平台,适用于各类行业场景,数据中台包含多元数据汇聚、数据标准化、数据开发、数据共享、数据智能、数据资产管理等功能,助力企业数字化转型。 数据汇聚 数据汇聚是将不同系统、不同类型的多元源数据汇聚至目标数据…

20.接口自动化-Git

1、Git和SVN–版本控制系统 远程服务出问题后,可以先提交commit到本地仓库,之后再提交push远程仓库 git有clone Git环境组成部分 常用Git代码仓库服务-远程仓库 GitHub-服务器在国外,慢 GitLab-开源,可以在自己服务器搭建&…

真JAVA代码审计之XSS漏洞

Part1 漏洞案例demo&#xff1a; 没有java代码审计XSS漏洞拿赏金的案例。 所以将就看看demo吧 漏洞原理&#xff1a;关于XSS漏洞的漏洞原理核心其实没啥好说的&#xff0c;网上一查一大堆。 反射性XSS漏洞 <% page language"java" contentType"text/ht…

2. 感知机算法和简单 Python 实现

目录 1. 感知机介绍 1.1 背景 1.2 定义 1.2.1 权重 1.2.2 阈值 1.2.3 偏置 1.3 逻辑处理&#xff1a;与门、非门、或门 2. 感知机实现 2.1 与门的 Python 实现 2.2 非门的 Python 实现 2.3 或门的 Python 实现 1. 感知机介绍 1.1 背景 感知机1957年由 Rosenblatt 提…

【全开源】JAVA国际版多语言语聊大厅语音聊天APP系统源码

国际版多语言语聊大厅语音聊天APP系统&#xff1a;跨越语言的界限&#xff0c;连接世界的声音 在全球化日益加速的今天&#xff0c;语言不再是沟通的障碍。我们很高兴地宣布&#xff0c;全新的“国际版多语言语聊大厅语音聊天APP系统”已经正式上线&#xff0c;旨在为全球用户…

【千帆AppBuidler】零代码构建AI人工智能应用,全网都在喊话歌手谁能应战,一键AI制作歌手信息查询应用

欢迎来到《小5讲堂》 这是《千帆平台》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 背景创建应用平台地址随机生成快速创建应用头像应用名称应用描述…

【基于element ui的color选择器】基于element ui的color选择器

技术版本如下&#xff1a; vue 2.6.14 less 3.13.1 element-ui 2.15.6 less-loader 5.0.0需求&#xff1a; 支持RGB、HEX编码、支持吸管吸取颜色、颜色选择器、颜色模板、透明度、色板、线性渐变颜色 效果图&#xff1a; 1.引入选择器的color-all文件 <template><…

[vue] nvm

nvm ls // 看安装的所有node.js的版本nvm list available // 查显示可以安装的所有node.js的版本可以在可选列表里。选择任意版本安装&#xff0c;比如安装16.15.0 执行&#xff1a; nvm install 16.15.0安装好了之后。可以执行&#xff1a; …

鸿蒙内核源码分析 (内核启动篇) | 从汇编到 main ()

这应该是系列篇最难写的一篇&#xff0c;全是汇编代码&#xff0c;需大量的底层知识&#xff0c;涉及协处理器&#xff0c;内核镜像重定位&#xff0c;创建内核映射表&#xff0c;初始化 CPU 模式栈&#xff0c;热启动&#xff0c;到最后熟悉的 main() 。 内核入口 在链接文件…

FreeRTOS开发一、FreeRTOS移植

1、FreeRTOS 源码下载 两个下载链接&#xff0c; 一个是官网&#xff1a;http://www.freertos.org/&#xff0c; 另外一个是代码托管网站&#xff1a;https://sourceforge.net/projects/freertos/files/FreeRTOS/ 打开代码托管网站链接&#xff0c;我们选择FreeRTOS 的版本 V9…

全域运营平台是什么?优缺点有哪些?

当下&#xff0c;全域运营赛道逐渐兴盛&#xff0c;全域运营服务商的数量也开始呈现爆发趋势。在此背景下&#xff0c;很多人都对某些品牌的全域运营平台优缺点产生了浓厚的兴趣。由于小编只使用过微火全域运营平台&#xff0c;因此&#xff0c;本期会着重分析微火运营平台的优…

【软考】设计模式之桥接模式

目录 1. 说明2. 应用场景3. 结构图4. 构成5. 适用性6. 优点7. 缺点8. java示例 1. 说明 1.将抽象部分与其实现部分分离&#xff0c;使它们都可以独立地变化。2.桥接模式&#xff08;Bridge Pattern&#xff09;属于对象结构型模式&#xff0c;又称为柄体&#xff08;Handle an…

Leetcode2105. 给植物浇水 II

Every day a Leetcode 题目来源&#xff1a;2105. 给植物浇水 II 解法1&#xff1a;双指针 设 Alice 当前下标为 i&#xff0c;初始化为 0&#xff0c;水量为 a&#xff0c;初始化为 capacityA&#xff1b;Bob 当前下标为 j&#xff0c;初始化为 n-1&#xff0c;水量为 b&am…

力扣98.验证二叉搜索树

法一&#xff08;自己思路&#xff0c;复杂了&#xff09;&#xff1a; from collections import dequeclass Solution(object):def isValidBST(self, root):""":type root: TreeNode:rtype: bool"""queue deque()if root.left!None:queue.app…

FOSS全闪对象存储--与AI/ML相向而行

行业解读需求剖析 目前&#xff0c;随着AI/ML技术得到了快速的发展及应用&#xff0c;AI/ML系统对底层高速数据访问的需求也日趋强烈&#xff0c;虽然当前业界有多种解决方案&#xff0c;但都存在一些成本或性能方面的挑战&#xff0c;就目前常用的文件存储系统来说&#xff0…