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

news2024/11/16 5:32:25

文章目录

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

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

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

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

相关文章

三、安装node_exporter

目录 一、简介 二、下载安装 一、简介 Exporter是Prometheus的指标数据收集组件。它负责从目标Jobs收集数据,并把收集到的数据转换为Prometheus支持的时序数据格式。 和传统的指标数据收集组件不同的是,他只负责收集,并不向Server端发送数据…

百度文心一言 java 支持流式输出,Springboot+ sse的demo

参考&#xff1a;GitHub - mmciel/wenxin-api-java: 百度文心一言Java库&#xff0c;支持问答和对话&#xff0c;支持流式输出和同步输出。提供SpringBoot调用样例。提供拓展能力。 1、依赖 <dependency> <groupId>com.baidu.aip</groupId> <artifactId…

Vue3使用datav3报错的三个问题解决

我这里写的是按需引入 报错问题Cannot find module dataview/datav-vue3 修改datav源码中的package.json文件 修改为 "module": "./es/index.mjs", 然就就会遇见新的报错问题 报错问题TypeError: Cannot read properties of null (reading $el) 然后修改…

Day 46 139.单词拆分

单词拆分 给定一个非空字符串 s 和一个包含非空单词的列表 wordDict&#xff0c;判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。 说明&#xff1a; 拆分时可以重复使用字典中的单词。 你可以假设字典中没有重复的单词。 示例 1&#xff1a; 输入: s “leet…

智能监控与安全管理:安全帽检测算法的实践与应用

在工地、煤矿等高危工作环境中&#xff0c;安全帽的佩戴至关重要。安全帽能够有效防止因坠落物体或碰撞等引起的头部伤害&#xff0c;从而保护工作人员的生命安全。然而&#xff0c;传统的检查人员佩戴安全帽的方式主要依赖于现场监督和巡查&#xff0c;这种方法不仅耗费大量人…

PDF编辑阅读器PDF Expert for Mac v3.10.1中文激活版

PDF Expert for Mac是一款易于使用的 PDF 编辑器和注释器&#xff0c;专为 Mac 设备设计。它允许用户轻松查看、编辑、签名、注释和共享 PDF。该软件使用户能够向他们的 PDF 添加文本、图像、链接和形状&#xff0c;突出显示和标记文本&#xff0c;填写表格以及签署数字文档。它…

更高、更快、更强,受管文件传输应该注意的三个要素

受管文件在很多公司内部都存在这个分类&#xff0c;受管文件不是特定的某一文件&#xff0c;而是指的是在一个组织或企业内&#xff0c;被正式管理和控制的文件。这些文件通常包含重要的信息&#xff0c;如技术规格、标准操作程序&#xff08;SOPs&#xff09;、质量手册、设计…

SDN 实现 vxlan隧道

SDN vxlan隧道 官方介绍&#xff1a; VXLAN&#xff08;Virtual eXtensible Local Area Network&#xff0c;虚拟扩展局域网&#xff09;&#xff0c;是由IETF定义的NVO3&#xff08;Network Virtualization over Layer 3&#xff09;标准技术之一&#xff0c;是对传统VLAN协议…

社交媒体数据恢复:如流

如流&#xff0c;原名百度Hi&#xff0c;是百度公司开发的一款即时通讯软体。百度Hi具备文字消息、视讯、通话、文件传输等功能。 查找备份&#xff1a;如果您之前有备份如流中的数据&#xff0c;您可以尝试从备份中恢复。如流支持备份至云端&#xff0c;如百度网盘等。 联系客…

C++auto关键字、范围for循环

一、auto关键字 1.1auto简介 在早期C/C中auto的含义是&#xff1a;使用auto修饰的变量&#xff0c;是具有自动存储器的局部变量。 C11中&#xff0c;标准委员会赋予了auto全新的含义即&#xff1a;auto不再是一个存储类型指示符&#xff0c;而是作为一个新的类型指示符来指示编…

前端铺子后台管理系统:基于Vue3与Ant Design Vue的轻量级解决方案

一、引言 随着前端技术的飞速发展&#xff0c;构建高效、轻量且易于维护的后台管理系统成为了企业信息化建设的重要一环。前端铺子后台管理系统&#xff0c;作为一款基于Vue的前端框架&#xff0c;结合Ant Design Vue的UI组件库&#xff0c;为企业提供了一个高效、灵活的后台管…

视频推拉流/视频直播点播平台EasyDSS使用Mysql数据库接口报错502如何处理?

视频推拉流/视频直播点播EasyDSS互联网直播平台支持一站式的上传、转码、直播、回放、嵌入、分享功能&#xff0c;具有多屏播放、自由组合、接口丰富等特点。平台可以为用户提供专业、稳定的直播推流、转码、分发和播放服务&#xff0c;全面满足超低延迟、超高画质、超大并发访…

计算思维的理解

2006年&#xff0c;卡内基梅隆大学周以真教授首次系统性地定义了计算思维。这一年&#xff0c;她在美国计算机权威期刊《Communications of the ACM》上发表了题为《Computational Thinking》的论文&#xff0c;由此开启了计算思维大众化的全新历程。 周以真&#xff08;Jeanne…

指针(4)

目录 1. 字符指针变量 2.数组指针 2.1 数组指针和指针数组的区别 2.2访问数组指针 3. ⼆维数组传参的本质 4. 函数指针变量 4.1两段有趣的代码 4.2 typedef 关键字 5.函数指针数组 6.转移表 1. 字符指针变量 在指针的类型中我们知道有⼀种指针类型为字符指针 char* …

【devops】Linux 日常磁盘清理 ubuntu 清理大文件 docker 镜像清理

日常磁盘清理 1、查找大文件 find / -type f -size 1G2、清理docker无用镜像&#xff08;drone产生的残余镜像文件&#xff09; docker system prune -a一、清理服务器磁盘 1、查找大文件 在Ubuntu系统中&#xff0c;你可以使用find命令来查找大文件。find命令是一个强大的…

渣土车上路识别报警摄像机

随着城市建设的不断推进&#xff0c;渣土车在城市道路上的数量也逐渐增加。然而&#xff0c;一些不法渣土车司机往往会超载、超速行驶或者闯红灯&#xff0c;给道路交通安全和城市环境带来了一定的隐患。为了有效监管渣土车上路行驶的情况&#xff0c;渣土车上路识别报警摄像机…

企业微信hook接口协议,ipad协议http,获取二次验证二维码接口

获取二次验证二维码接口 参数名必选类型说明uuid是String每个实例的唯一标识&#xff0c;根据uuid操作具体企业微信 请求示例 {"uuid":"f5a22e9b-9664-4250-b40a-08741dba549c" } 返回示例 {"data": {"qrcode": "http://47.9…

Linux之内存管理-malloc \kmalloc\vmalloc\dma

1、malloc 函数 1.1分配内存小于128k,调用brk malloc是C库实现的函数&#xff0c;C库维护了一个缓存&#xff0c;当内存够用时&#xff0c;malloc直接从C库缓存分配&#xff0c;只有当C库缓存不够用&#xff1b; 当申请的内存小于128K时&#xff0c;通过系统调用brk&#xff…

C++的数据结构(八):线段树

线段树是一种高效的树形数据结构&#xff0c;用于处理区间查询和区间更新问题。它的基本思想是将一个大的区间分解为若干个小的、不相交的区间&#xff0c;每个小区间对应线段树中的一个节点。线段树的每个节点保存了该区间的信息&#xff08;如区间最大值、区间和等&#xff0…

Spring Boot实现多数据源快速入门

1.为什么需要多数据源&#xff1f; 多数据源既动态数据源&#xff0c;项目开发逐渐扩大&#xff0c;单个数据源、单一数据源已经无法满足需求项目的支撑需求。本文采用dynamic-datasource-spring-boot-starter实现多数据源&#xff0c; 主要特性 支持 数据源分组 &#xff0…