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.shape
            ori_img_data_type = self.ori_img.dtype

            ori_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. 总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ThinkPad T480(20L5,20L6)原装出厂Win10系统镜像下载

lenovo联想ThinkPad系列 T480笔记本电脑20L5、20L6原厂OEM预装Windows10系统,恢复开箱状态一模一样,带有恢复重置功能 链接:https://pan.baidu.com/s/1NqqBKC_v2mPDs2qTxsYvxA?pwdeivm 提取码:eivm 原装出厂系统自带所有驱动…

【机器学习】AI在空战决策中的崛起:从理论到实践的跨越

AI在空战决策中的崛起:从理论到实践的跨越 一、引言二、AI技术的崛起与空军决策技术层面作战结构 三、AI在空战决策中的前景展望四、结语 一、引言 随着科技的不断进步,现代战争已经步入了一个全新的时代。其中,空战作为战争的重要组成部分&a…

PG pageinspect使用与块空间清理学习

1.创建有时候会报错 ERROR: could not open extension control file "/usr/local/pgsql/share/extension/pageinspect.control": No such file or directory 解决方案: 2.使用 PostgreSQL中,对于每一行数据(称为一个tuple&#…

caj文件是什么?caj是什么文件?考研学生赶紧收藏!

在学术研究的广阔领域中,尤其是对于那些致力于深入研究、不断拓宽知识边界的考研学子们来说,了解并掌握各种学术资源的获取与利用方法显得尤为重要。其中,CAJ文件作为一种常见的学术文件格式,其重要性和使用频率不容忽视。那么&am…

深度学习之激活函数——Tanh

Tanh 双曲正切1函数(tanh),其图像与sigmoid函数十分相近,相当于sigmoid函数的放大版。在实际的使用中,tanh函数要优先于sigmoid函数。 函数表达式 t a n h e x − e − x e x e − x tanh\frac{e^x-e^{-x}}{e^xe^{-x}} tanhexe−xex−e−…

.NET WebService \ WCF \ WebAPI 部署总结 以及 window 服务 调试,webservice 的安全验证

一、webservice 部署只能部署IIS上, 比较简单,就不做说明了 安全验证: Formwindow身份加个参数,token 定时更新可以Soapheader 》》》soapheader验证 首先要新建一个类 且这个类必须继承SoapHeader类 且这个类型必须有一个无参…

23、Flink 的 Savepoints 详解

Savepoints 1.什么是 Savepoints Savepoint 是依据 Flink checkpointing 机制所创建的流作业执行状态的镜像,可以使用 Savepoint 进行 Flink 作业的停止、重启或更新。 Savepoint 由两部分组成:稳定存储(例如 HDFS,S3&#xff…

深度践行“IaaS on DPU”理念,中科驭数正式发布“驭云”高性能云异构算力解决方案

5月10日至14日,由国家发展改革委联合国务院国资委、市场监管总局、国家知识产权局共同主办的第八届中国品牌日活动在上海世博展览馆举行。中科驭数高级副总裁张宇在中国品牌日新品首发首秀环节正式发布驭云高性能云异构算力解决方案,为企业提供更快部署、…

干部谈话考察:精准洞悉,助推成长

在组织人事管理的精细布局中,干部谈话考察扮演着举足轻重的角色。它不仅是组织深度了解干部、精准评价其表现的重要窗口,更是推动干部个人成长、优化组织人才配置的关键一环。通过深入的谈话考察,我们能够全面把握干部的思想脉搏、工作能力、…

Vmware ESXi无法创建虚拟机

点击创建虚拟机,没有反应 esxi在网页端无法创建虚拟机,与浏览器插件supercopy超级复制有关。 关闭插件在此页面运行,即可解决问题。 这个插件严重影响虚拟机正常的操作, 我还以为我的虚拟机炸了,格式化后,又…

冯喜运:5.14黄金大幅度修正?原油价格下跌成拖累?

【黄金消息面分析】:本周重要的美国数据的发布可能会对美元以及黄金产生重大影响。周四将公布更多经济指标,包括新屋开工和许可证、费城联储指数、工业生产数据和每周初请失业金人数。对于黄金而言,人们的注意力集中在经济和劳动力市场疲软对…

【回溯 代数系统】679. 24 点游戏

本文涉及知识点 回溯 代数系统 LeetCode679. 24 点游戏 给定一个长度为4的整数数组 cards 。你有 4 张卡片,每张卡片上都包含一个范围在 [1,9] 的数字。您应该使用运算符 [‘’, ‘-’, ‘*’, ‘/’] 和括号 ‘(’ 和 ‘)’ 将这些卡片上的数字排列成数学表达式…

Java面试八股之Java中的IO流分为几种

Java中的IO流分为几种 按数据单位分类: 字节流(Byte Stream):以字节(8位二进制数)为基本单位进行数据读写。字节流适合处理所有类型的数据,包括文本、图像、音频、视频等二进制文件。抽象基类…

小米打印机Mi All-in-One Inkjet Printer进行扫描

1,打开电脑的控制面板,找到打印机 2,,选择小米打印机【Mi All-in-One Inkjet Printer】;右键,选择开始扫描 3,可以预览,或者直接扫描 4,点击下一步,导入图片 …

redis深入理解之实战

1、SpringBoot整合redis 1.1 导入相关依赖 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId&g…

高校普法|基于SSM+vue的高校普法系统的设计与实现(源码+数据库+文档)

高校普法系统 目录 基于SSM&#xff0b;vue的高校普法系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3律师功能模块 4学生功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获…

sklearn中多分类和多标签分类评估方法总结

一、任务区分 多分类分类任务&#xff1a;在多分类任务中&#xff0c;每个样本只能被分配到一个类别中。换句话说&#xff0c;每个样本只有一个正确的标签。例如&#xff0c;将图像分为不同的物体类别&#xff0c;如猫、狗、汽车等。 多标签分类任务&#xff1a;在多标签分类任…

抖音小店无货源怎么做?超详细教程,新手看这一篇就够了!

哈喽~我是电商月月 实体店做生意开店或是卖菜摆地摊&#xff0c;商家大部分都不是厂家自销&#xff0c;基本都是从批发厂里进货&#xff0c;然后加价卖出去的 “中间商赚差价”的行为在网上做店也是一种合理的行为 抖音小店里面的商家大部分选择的都是无货源模式运营 无货源…

Jmeter接口测试之参数化

在接口测试中&#xff0c;某些时候一些场景会使用到参数化的场景&#xff0c;参数化简单的说就是同一个请求需要不同的数据&#xff0c;比如在性能测试中需要并发多个用户的场景&#xff0c;这样的目的是为了模拟真实的用户场景&#xff0c;需要模拟不同的账号&#xff0c;这里…

2. C++入门:缺省参数及函数重载

缺省参数 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时&#xff0c;如果没有指定实参则采用该形参的缺省值&#xff0c;否则使用指定的实参。 void Func(int a 0) {cout << a << endl; }int main() {Func();Func(10);return 0; }在形…