当前位置: 首页 > article >正文

pyQT + OpenCV 的三个练习

一、创建一个 PyQt 应用程序,该应用程序能够:

  1. 使用 OpenCV 加载一张图像。
  2. 在 PyQt 的窗口中显示这张图像。
  3. 提供四个按钮(QPushButton):
  • 一个用于将图像转换为灰度图
  • 一个用于将图像恢复为原始彩色图
  • 一个用于将图像进行翻转
  • 一个用于将图像进行旋转
  • 当用户点击按钮时,相应地更新窗口中显示的图像。

思路分析

  1. 加载图像
    • 使用 OpenCV 加载一张图像,并将其存储为类的一个属性,以便在后续操作中访问。
  2. 显示图像
    • 使用 PyQt6 的 QLabel 来显示图像。
    • 将图像转换为 QPixmap,然后设置为 QLabel 的图像。
  3. 创建按钮
    • 使用 PyQt6 的 QPushButton 创建四个按钮,每个按钮对应一个图像处理功能。
  4. 实现图像处理功能
    • 灰度图:使用 OpenCV 的 cv2.cvtColor 函数将图像转换为灰度图。
    • 恢复原始图像:重新加载或存储原始图像,并在需要时恢复。
    • 翻转图像:使用 OpenCV 的 cv2.flip 函数进行水平翻转。
    • 旋转图像:使用 OpenCV 的 cv2.getRotationMatrix2D 和 cv2.warpAffine 函数进行旋转。
  5. 更新显示
    • 每当用户点击按钮时,调用相应的图像处理函数,更新存储的图像,并刷新 QLabel 上的显示。

涉及到的函数方法

  • cv2.imread(filepath): 加载图像。
  • cv2.cvtColor(image, cv2.COLOR_BGR2GRAY): 将图像转换为灰度图。
  • cv2.flip(image, 1): 水平翻转图像。
  • cv2.getRotationMatrix2D(center, angle, scale): 获取旋转矩阵。
  • cv2.warpAffine(image, rotation_matrix, (width, height)): 使用旋转矩阵旋转图像。
  • QImage(data, width, height, format): 将图像数据转换为 QImage
  • QPixmap.fromImage(image): 将 QImage 转换为 QPixmap
  • QLabel.setPixmap(pixmap): 设置 QLabel 的图像。

代码实现

import sys
import cv2
from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QWidget
from PyQt6.QtGui import QImage, QPixmap
from PyQt6.QtCore import Qt
import numpy as np

class ImageProcessor(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Image Processor")
        self.setGeometry(100, 100, 800, 600)

        self.original_image = cv2.imread('path_to_your_image.jpg')
        self.current_image = self.original_image.copy()

        self.qimage = self.convert_cv_qt(self.current_image)
        self.image_label = QLabel(self)
        self.image_label.setPixmap(QPixmap.fromImage(self.qimage))
        self.image_label.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.gray_button = QPushButton('Gray Scale')
        self.restore_button = QPushButton('Restore Original')
        self.flip_button = QPushButton('Flip Image')
        self.rotate_button = QPushButton('Rotate Image')

        self.gray_button.clicked.connect(self.convert_to_gray)
        self.restore_button.clicked.connect(self.restore_original)
        self.flip_button.clicked.connect(self.flip_image)
        self.rotate_button.clicked.connect(self.rotate_image)

        layout = QVBoxLayout()
        layout.addWidget(self.image_label)
        layout.addWidget(self.gray_button)
        layout.addWidget(self.restore_button)
        layout.addWidget(self.flip_button)
        layout.addWidget(self.rotate_button)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

    def convert_cv_qt(self, cv_img):
        
        rgb_image = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
        h, w, ch = rgb_image.shape
        bytes_per_line = ch * w
        convert_to_Qt_format = QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format.Format_RGB888)
        return convert_to_Qt_format

    def update_image_display(self):
       
        self.qimage = self.convert_cv_qt(self.current_image)
        self.image_label.setPixmap(QPixmap.fromImage(self.qimage))

    def convert_to_gray(self):
        
        self.current_image = cv2.cvtColor(self.current_image, cv2.COLOR_BGR2GRAY)
        # Convert back to BGR for compatibility (if needed)
        self.current_image = cv2.cvtColor(self.current_image, cv2.COLOR_GRAY2BGR)
        self.update_image_display()

    def restore_original(self):
       
        self.current_image = self.original_image.copy()
        self.update_image_display()

    def flip_image(self):
        """Flip the image horizontally"""
        self.current_image = cv2.flip(self.current_image, 1)
        self.update_image_display()

    def rotate_image(self):
        """Rotate the image by 90 degrees"""
        (h, w) = self.current_image.shape[:2]
        center = (w // 2, h // 2)
        rotation_matrix = cv2.getRotationMatrix2D(center, 90, 1.0)
        self.current_image = cv2.warpAffine(self.current_image, rotation_matrix, (w, h))
        self.update_image_display()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = ImageProcessor()
    window.show()
    sys.exit(app.exec())

效果展示

QQ20241228-94934-HD

二、创建一个 PyQt 应用程序,该应用程序能够:

  1. 使用 OpenCV 加载一张彩色图像,并在 PyQt 的窗口中显示它。
  2. 提供一个滑动条(QSlider),允许用户调整图像的亮度。
  3. 当用户调整滑动条时,实时更新窗口中显示的图像亮度。
  4. 添加另一个滑动条(QSlider),允许用户调整图像的对比度。
  5. 当用户调整滚动条时,实时更新窗口中显示的图像对比度。
  6. 提供一个按钮(QPushButton),允许用户将图像保存为新的文件。
  7. 当用户点击保存按钮时,将调整后的图像保存到指定的路径,OpenCV中使用cv2.imwrite()来保存图片。

思路分析

  1. 创建 PyQt 应用程序
    • 使用 QApplication 创建应用程序实例。
    • 使用 QMainWindow 或 QWidget 创建主窗口。
  2. 加载和显示图像
    • 使用 OpenCV (cv2.imread()) 加载彩色图像。
    • 将 OpenCV 图像(NumPy 数组)转换为 QImage,以便在 PyQt 中显示。
    • 使用 QLabel 来显示 QImage。
  3. 实现亮度调整
    • 添加一个 QSlider 用于亮度调整。
    • 连接滑动条的 valueChanged 信号到一个槽函数,该槽函数根据滑动条的值调整图像的亮度。
    • 亮度调整可以通过将每个像素值加上一个偏移量来实现。
  4. 实现对比度调整
    • 添加另一个 QSlider 用于对比度调整。
    • 连接滑动条的 valueChanged 信号到一个槽函数,该槽函数根据滑动条的值调整图像的对比度。
    • 对比度调整可以通过线性变换(如 new_pixel = alpha * (old_pixel - 127) + 127)来实现,其中 alpha 是对比度因子。
  5. 保存图像
    • 添加一个 QPushButton 用于保存图像。
    • 连接按钮的 clicked 信号到一个槽函数,该槽函数使用 OpenCV 的 cv2.imwrite() 保存调整后的图像。

设计到的函数方法

  • cv2.imread(): 加载图像。
  • cv2.cvtColor(): 转换图像颜色空间(如从 BGR 到 RGB)。
  • QImage(): 创建 QImage 对象。
  • QSlider(): 创建滑动条。
  • QPushButton(): 创建按钮。
  • QLabel(): 创建标签用于显示图像。
  • QVBoxLayout() / QHBoxLayout(): 布局管理器。
  • valueChanged 信号: 捕捉滑动条值的变化。
  • clicked 信号: 捕捉按钮点击事件。
  • cv2.imwrite(): 保存图像。

代码实现

import sys
import cv2
from PyQt6.QtWidgets import QApplication, QMainWindow, QSlider, QVBoxLayout, QWidget, QPushButton, QLabel
from PyQt6.QtGui import QImage, QPixmap
from PyQt6.QtCore import Qt
class ImageProcessor(QMainWindow):
    def __init__(self):
        super().__init__()

        # 加载图像
        self.image_path = 'C:\\Users\\lilba\\Desktop\\1228.jpg'
        self.image = cv2.imread(self.image_path)
        if self.image is None:
            print(f"Error: Unable to load image at {self.image_path}")
            sys.exit(1)

        self.brightness = 0
        self.contrast = 1

        self.initUI()
    def initUI(self):
        self.setWindowTitle('Image Processor')
        self.setGeometry(100, 100, 800, 600)
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        self.layout = QVBoxLayout()
        self.central_widget.setLayout(self.layout)

        self.image_label = QLabel()
        self.layout.addWidget(self.image_label)

        self.brightness_slider = QSlider()
        self.brightness_slider.setOrientation(Qt.Orientation.Vertical)
        self.brightness_slider.setMinimum(-100)
        self.brightness_slider.setMaximum(100)
        self.brightness_slider.setValue(0)
        self.brightness_slider.valueChanged.connect(self.updateBrightness)
        self.layout.addWidget(self.brightness_slider)
        self.contrast_slider = QSlider()
        self.contrast_slider.setOrientation(Qt.Orientation.Vertical)
        self.contrast_slider.setMinimum(1)
        self.contrast_slider.setMaximum(10)
        self.contrast_slider.setValue(1)
        self.contrast_slider.valueChanged.connect(self.updateContrast)
        self.layout.addWidget(self.contrast_slider)

        self.save_button = QPushButton('保存图像')
        self.save_button.clicked.connect(self.saveImage)
        self.layout.addWidget(self.save_button)
        self.updateImageLabel()
    def updateImageLabel(self):
        # 调整图像亮度和对比度
        adjusted_image = cv2.convertScaleAbs(self.image, alpha=self.contrast, beta=self.brightness)
        adjusted_image = cv2.cvtColor(adjusted_image, cv2.COLOR_BGR2RGB)

        # 将 OpenCV 图像转换为 QImage
        height, width, channel = adjusted_image.shape
        bytes_per_line = 3 * width
        q_image = QImage(adjusted_image.data, width, height, bytes_per_line, QImage.Format.Format_RGB888)

        # 确保 QImage 不在调整后被释放
        q_image = q_image.copy()

        # 将 QImage 转换为 QPixmap
        pixmap = QPixmap.fromImage(q_image)

        # 在 QLabel 上显示 QPixmap
        self.image_label.setPixmap(pixmap)

    def updateBrightness(self, value):
        self.brightness = value
        self.updateImageLabel()

    def updateContrast(self, value):
        self.contrast = value / 5.0 * 4 + 1
        self.updateImageLabel()

    def saveImage(self):

        adjusted_image = cv2.convertScaleAbs(self.image, alpha=self.contrast, beta=self.brightness)
        cv2.imwrite('adjusted_image.jpg', adjusted_image)
        print("Image saved as adjusted_image.jpg")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = ImageProcessor()
    window.show()
    sys.exit(app.exec())

效果展示

QQ20241228-103924

三、创建一个 PyQt 应用程序,该应用程序能够:

  1. 使用 OpenCV 加载一张图像。
  2. 在 PyQt 的窗口中显示这张图像。
  3. 提供一个下拉列表(QComboBox),对图像做(模糊、锐化、边缘检测)处理:
  • 模糊——使用cv2.GaussianBlur()实现
  • 锐化——使用cv2.Laplacian()、cv2.Sobel()实现
  • 边缘检测——使用cv2.Canny()实现
  1. 当用户点击下拉列表选项时,相应地更新窗口中显示的图像。
  2. 提供一个按钮,当用户点击按钮时,能保存调整后的图像。

思路分析

  1. 初始化 PyQt 应用程序
    • 创建一个基本的 PyQt 应用程序窗口。
    • 设置窗口标题和大小。
  2. 加载图像
    • 使用 OpenCV 加载图像。
    • 将图像从 BGR 格式转换为 RGB 格式(因为 PyQt 使用 RGB 格式)。
  3. 显示图像
    • 使用 QLabel 来显示图像。
    • 将图像转换为 QPixmap 格式以便在 QLabel 中显示。
  4. 创建下拉列表(QComboBox)
    • 添加选项:“模糊”、“锐化”、“边缘检测”。
    • 连接 QComboBox 的信号(currentIndexChanged)到槽函数,以便在用户选择选项时更新图像。
  5. 图像处理
    • 根据用户选择的选项,使用 OpenCV 对图像进行相应处理。
    • 更新 QLabel 中显示的图像。
  6. 保存图像
    • 提供一个 QPushButton,当用户点击时,保存当前显示的图像。
    • 使用 QFileDialog 让用户选择保存路径。

设计到的函数方法

  • cv2.imread():加载图像。
  • cv2.cvtColor():转换图像颜色格式。
  • cv2.GaussianBlur():对图像进行高斯模糊。
  • cv2.Laplacian() 和 cv2.Sobel():对图像进行锐化。
  • cv2.Canny():进行边缘检测。
  • QImage() 和 QPixmap():在 PyQt 中处理和显示图像。
  • QComboBox():创建下拉列表。
  • QPushButton():创建按钮。
  • QFileDialog():打开文件保存对话框。

代码实现

import sys
import cv2
from PyQt6.QtWidgets import QApplication, QMainWindow, QComboBox, QVBoxLayout, QWidget, QPushButton, QLabel, QFileDialog
from PyQt6.QtGui import QImage, QPixmap


class ImageProcessor(QMainWindow):
    def __init__(self):
        super().__init__()

        # 加载图像,确保图像路径正确或添加错误处理
        self.image_path = 'C:\\Users\\lilba\\Desktop\\1228.jpg'
        self.image = cv2.imread(self.image_path)
        if self.image is None:
            print(f"Error: Unable to load image at {self.image_path}")
            sys.exit(1)

        self.initUI()

    def initUI(self):
        self.setWindowTitle('Image Processor')
        self.setGeometry(100, 100, 800, 600)

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.layout = QVBoxLayout()
        self.central_widget.setLayout(self.layout)

        self.image_label = QLabel()
        self.layout.addWidget(self.image_label)

        self.processing_combobox = QComboBox()
        self.processing_combobox.addItems(['模糊', '锐化', '边缘检测'])
        self.processing_combobox.currentIndexChanged.connect(self.updateImage)
        self.layout.addWidget(self.processing_combobox)

        self.save_button = QPushButton('保存图像')
        self.save_button.clicked.connect(self.saveImage)
        self.layout.addWidget(self.save_button)

        self.updateImageLabel()

    def updateImageLabel(self):
        # 根据下拉列表选项处理图像
        processing_option = self.processing_combobox.currentText()
        processed_image = self.image.copy()  # 从原始图像复制,避免修改原始数据

        if processing_option == '模糊':
            processed_image = cv2.GaussianBlur(processed_image, (5, 5), 0)
        elif processing_option == '锐化':
            processed_image = cv2.Laplacian(processed_image, cv2.CV_64F)
            processed_image = cv2.convertScaleAbs(processed_image)
        elif processing_option == '边缘检测':
            processed_image = cv2.Canny(processed_image, 100, 200)

        # 将 OpenCV 图像转换为 QImage
        processed_image = cv2.cvtColor(processed_image, cv2.COLOR_BGR2RGB)
        height, width, channel = processed_image.shape
        bytes_per_line = 3 * width
        q_image = QImage(processed_image.data, width, height, bytes_per_line, QImage.Format.Format_RGB888)

        # 将 QImage 转换为 QPixmap
        pixmap = QPixmap.fromImage(q_image)

        # 在 QLabel 上显示 QPixmap
        self.image_label.setPixmap(pixmap)

    def updateImage(self, index):
        self.updateImageLabel()

    def saveImage(self):
        # 保存调整后的图像
        processing_option = self.processing_combobox.currentText()
        processed_image = self.image.copy()  # 从原始图像复制

        if processing_option == '模糊':
            processed_image = cv2.GaussianBlur(processed_image, (5, 5), 0)
        elif processing_option == '锐化':
            processed_image = cv2.Laplacian(processed_image, cv2.CV_64F)
            processed_image = cv2.convertScaleAbs(processed_image)
        elif processing_option == '边缘检测':
            processed_image = cv2.Canny(processed_image, 100, 200)

        # 使用文件对话框选择保存路径
        options = QFileDialog.Options()
        file_path, _ = QFileDialog.getSaveFileName(self, "保存图像", "", "JPEG Files (*.jpg);;PNG Files (*.png)",
                                                   options=options)
        if file_path:
            cv2.imwrite(file_path, processed_image)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = ImageProcessor()
    window.show()
    sys.exit(app.exec())

效果展示

QQ20241228-112315


http://www.kler.cn/a/461301.html

相关文章:

  • CSS系列(47)-- Animation Timeline详解
  • JS基础 -- 数组 (对象 / 数组 / 类数组 / 对象数组)的遍历
  • MySQL中distinct和group by去重的区别
  • vue2+echarts实现水球+外层动效
  • STM32 + 移远EC800 4G通信模块数传
  • html 音频和视频组件
  • 微服务-配置管理
  • 等保测评和密评的相关性和区别
  • 智能化AI标书撰写工具,让标书制作更高效、更专业
  • 安装Node.js和npm
  • 漏洞分析 | Apache Struts文件上传漏洞(CVE-2024-53677)
  • Maven项目中不修改 pom.xml 状况下直接运行OpenRewrite的配方
  • 数据结构与算法之动态规划: LeetCode 115. 不同的子序列 (Ts版)
  • 小程序样式 —— 20全局样式和局部样式
  • Spring Boot环境配置
  • 鸿蒙项目云捐助第二十九讲云捐助项目云数据库商品的批量增加功能实现
  • 蒙特卡洛方法试验的一般过程和经典例子
  • Qanything 2.0源码解析系列6 PDF解析逻辑
  • 计算机网络•自顶向下方法:IP编址
  • 【每日学点鸿蒙知识】监听输入框删除键、进入页面前网络请求、同层渲染、GridCol左对齐、自定义弹窗禁止手势
  • 语音合成芯片:让净水机更智能、更便捷
  • 练习题:29
  • naive ui 使用地址记录
  • 人工智能知识分享第二天-机器学习之KNN算法
  • 2024终章---愿昭昭如愿,愿岁岁安澜
  • 大模型的实践应用34-大模型LLama3的预训练的全流程介绍,包括:数据收集处理、模型架构与初始化,训练策略等