Bootstrap

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

1. 简介

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

2. 准备工作

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

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

;