首页 > 其他分享 >PyQt5与OpenCV结合的三个小练习

PyQt5与OpenCV结合的三个小练习

时间:2024-12-20 20:55:35浏览次数:5  
标签:__ self 练习 cv2 PyQt5 current OpenCV 图像 image

题目1、简单图像处理

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

1、使用 OpenCV 加载一张图像。

2、在 PyQt 的窗口中显示这张图像。

3、提供四个按钮(QPushButton):

  • 一个用于将图像转换为灰度图
  • 一个用于将图像恢复为原始彩色图
  • 一个用于将图像进行翻转
  • 一个用于将图像进行旋转

4、当用户点击按钮时,相应地更新窗口中显示的图像。

用于测试的图片如下:

QT窗口界面搭建

首先,我在QT Designer里搭建了如下窗口:

并且对内部的组件进行了命名,方便后续搭建对应的槽函数 

代码实现 

import sys
import cv2
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import QWidget, QPushButton, QLabel, QApplication
from qtpy import uic

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        ui = uic.loadUi('./image.ui', self)

        #设置窗口固定大小
        self.setFixedSize(1000,800)

        self.GrayBtn: QPushButton = ui.graybtn  # 灰度化按钮
        self.ImgBtn: QPushButton = ui.imgbtn  # 显示原图按钮
        self.FlipBtn: QPushButton = ui.filipbtn  # 翻转按钮
        self.RotateBtn: QPushButton = ui.rotatebtn  # 旋转按钮
        self.imagelab: QLabel = ui.imagelab  # 显示图片

        # 读取图片
        self.original_image = cv2.imread('./lena.png')
        self.current_image = self.original_image.copy() #复制原图用于后续处理

        # 信号和槽的连接
        self.GrayBtn.clicked.connect(self.to_grayscale)
        self.ImgBtn.clicked.connect(self.restore_color)
        self.FlipBtn.clicked.connect(self.flip_image)
        self.RotateBtn.clicked.connect(self.rotate_image)

        # 初始化显示原图
        self.update_image()

    def convert_cv_qt(self, img):
        """将 OpenCV 图像转换为 QImage"""
        if len(img.shape) == 2:  # 灰度图
            height, width = img.shape
            bytes_per_line = width
            qimg = QImage(img.data, width, height, bytes_per_line, QImage.Format_Grayscale8)
        else:  # 彩色图
            height, width, channel = img.shape
            bytes_per_line = 3 * width
            qimg = QImage(img.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped()
        return qimg

    def update_image(self):
        """更新 QLabel 上显示的图像"""
        qimg = self.convert_cv_qt(self.current_image)
        pixmap = QPixmap.fromImage(qimg)
        self.imagelab.setPixmap(pixmap)
        self.imagelab.setAlignment(Qt.AlignCenter)

    def to_grayscale(self):
        """转换为灰度图"""
        self.current_image = cv2.cvtColor(self.original_image, cv2.COLOR_BGR2GRAY)
        self.current_image = cv2.cvtColor(self.current_image, cv2.COLOR_GRAY2BGR)  # 转换为伪彩色以便显示
        self.update_image()

    def restore_color(self):
        """恢复为原图"""
        self.current_image = self.original_image.copy()
        self.update_image()

    def flip_image(self):
        """翻转图像"""
        self.current_image = cv2.flip(self.original_image, 1)  # 水平翻转
        self.update_image()

    def rotate_image(self):
        """旋转图像"""
        (h, w) = self.original_image.shape[:2]
        center = (w // 2, h // 2)
        M = cv2.getRotationMatrix2D(center, 90, 1.0)  # 顺时针旋转90度
        self.current_image = cv2.warpAffine(self.original_image, M, (w, h))  # 注意:这里可能会裁剪图像
        # 如果需要保留全部图像,可以调整输出图像大小或使用填充
        self.update_image()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWidget = MyWidget()
    myWidget.show()
    sys.exit(app.exec_())

结果展示

题目2、图像亮度对比度调整

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

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

 QT窗口界面搭建

首先,我在QT Designer里搭建了如下窗口:

并且对内部的组件进行了命名,方便后续搭建对应的槽函数 

代码实现

import sys
import cv2
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import QWidget, QPushButton, QLabel, QApplication, QSlider, QFileDialog
from qtpy import uic


class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        ui = uic.loadUi('./form2.ui', self)

        #设置窗口固定大小
        self.setFixedSize(1100,1000)
        self.imagelab.setAlignment(Qt.AlignCenter)   #设置居中显示图片

        self.SaveBtn: QPushButton = ui.savebtn  # 保存按钮
        self.imagelab: QLabel = ui.imagelab  # 显示图片
        self.contrastSlider: QSlider = ui.contrastSlider        #对比度滑块
        self.lightSlider:QSlider = ui.lightSlider        #亮度滑块

        # 读取图片
        self.original_image = cv2.imread('./lena.png')
        self.current_image = self.original_image.copy()


        # 信号和槽的连接
        self.SaveBtn.clicked.connect(self.SaveBtn_slot)
        self.contrastSlider.valueChanged.connect(self.change_contrast)  # 改变对比度
        self.lightSlider.valueChanged.connect(self.change_light)  # 改变亮度

        # 初始化显示原图
        self.update_image()

    def convert_cv_qt(self, img):
        """将 OpenCV 图像转换为 QImage"""
        if len(img.shape) == 2:  # 灰度图
            height, width = img.shape
            bytes_per_line = width
            qimg = QImage(img.data, width, height, bytes_per_line, QImage.Format_Grayscale8)
        else:  # 彩色图
            height, width, channel = img.shape
            bytes_per_line = 3 * width
            qimg = QImage(img.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped()
        return qimg

    def update_image(self):
        """更新 QLabel 上显示的图像"""
        qimg = self.convert_cv_qt(self.current_image)
        pixmap = QPixmap.fromImage(qimg)
        self.imagelab.setPixmap(pixmap)


    def change_contrast(self,value):
        alpha = value / 50.0  # 将滑动条的值映射到0到2
        self.current_image = cv2.convertScaleAbs(self.original_image.copy(), alpha=alpha, beta=0)
        self.update_image()

    def change_light(self,value):
        beta = value - 50  # 将滑动条的值映射到-50到50
        self.current_image = cv2.convertScaleAbs(self.original_image.copy(), alpha=1, beta=beta)
        self.update_image()

    def SaveBtn_slot(self):
        options = QFileDialog.Options()
        filePath, _ = QFileDialog.getSaveFileName(self, "Save Image", "", "Images (*.png *.xpm *.jpg);;All Files (*)",
                                                  options=options)
        if filePath:
            cv2.imwrite(filePath, self.current_image)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWidget = MyWidget()
    myWidget.show()
    sys.exit(app.exec_())

这个代码并不完善,滑块位于中间时才是原图的样式,且亮度和对比度不能同时调整,希望后续我能将代码有所改进。

结果展示

题目3、图像锐化模糊等操作

创建一个 PyQt 应用程序,该应用程序能够:
1.使用 OpenCV 加载一张图像。
2.在 PyQt 的窗口中显示这张图像。
3.提供一个下拉列表(QComboBox),对图像做(模糊、锐化、边缘检测)处理:

  • - 模糊——使用cv2.GaussianBlur()实现
  • - 锐化——使用cv2.Laplacian()、cv2.Sobel()实现
  • - 边缘检测——使用cv2.Canny()实现

4.当用户点击下拉列表选项时,相应地更新窗口中显示的图像。
5.提供一个按钮,当用户点击按钮时,能保存调整后的图像。

  QT窗口界面搭建

首先,我在QT Designer里搭建了如下窗口:

并且对内部的组件进行了命名,方便后续搭建对应的槽函数 

 

代码实现


import sys
import cv2
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import QWidget, QPushButton, QLabel, QApplication, QComboBox, QFileDialog
from qtpy import uic

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        ui = uic.loadUi('./form3.ui', self)

        #设置窗口固定大小
        self.setFixedSize(1000,800)
        self.imagelab.setAlignment(Qt.AlignCenter)   #设置居中显示图片

        self.imagelab: QLabel = ui.imagelab  # 显示图片
        self.SaveBtn: QPushButton = ui.savebtn  # 保存按钮
        self.comboBox: QComboBox  = ui.comboBox #下拉列表

        # 读取图片
        self.original_image = cv2.imread('./lena.png')
        self.current_image = self.original_image.copy()

        # 信号和槽的连接
        self.SaveBtn.clicked.connect(self.SaveBtn_slot)
        self.comboBox.currentIndexChanged.connect(self.processImage)


        # 初始化显示原图
        self.update_image()

    def SaveBtn_slot(self):
        options = QFileDialog.Options()
        filePath, _ = QFileDialog.getSaveFileName(self, "Save Image", "", "Images (*.png *.xpm *.jpg);;All Files (*)",
                                                  options=options)
        if filePath:
            cv2.imwrite(filePath, self.current_image)

    def processImage(self, index):
        """根据下拉列表的选项处理图像"""
        if index == 0:
            self.current_image = self.original_image.copy()
        elif index == 1:
            # 模糊
            self.current_image = cv2.GaussianBlur(self.original_image, (15, 15), 0)
        elif index == 2:
            # 锐化
            laplacian = cv2.Laplacian(self.original_image, cv2.CV_64F)
            sobelx = cv2.Sobel(self.original_image, cv2.CV_64F, 1, 0, ksize=3)
            sobely = cv2.Sobel(self.original_image, cv2.CV_64F, 0, 1, ksize=3)
            sharpened = cv2.convertScaleAbs(self.original_image - laplacian + sobelx + sobely)
            self.current_image = sharpened
        elif index == 3:
            # 边缘检测
            edges = cv2.Canny(self.original_image, 100, 200)
            # Canny 边缘检测返回的是灰度图,但我们可以将其转换为彩色图以更好地在 QLabel 上显示
            edges_color = cv2.cvtColor(edges, cv2.COLOR_GRAY2RGB)
            self.current_image = edges_color
        self.update_image()

    def convert_cv_qt(self, img):
        """将 OpenCV 图像转换为 QImage"""
        if len(img.shape) == 2:  # 灰度图
            height, width = img.shape
            bytes_per_line = width
            qimg = QImage(img.data, width, height, bytes_per_line, QImage.Format_Grayscale8)
        else:  # 彩色图
            height, width, channel = img.shape
            bytes_per_line = 3 * width
            qimg = QImage(img.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped()
        return qimg

    def update_image(self):
        """更新 QLabel 上显示的图像"""
        qimg = self.convert_cv_qt(self.current_image)
        pixmap = QPixmap.fromImage(qimg)
        self.imagelab.setPixmap(pixmap)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWidget = MyWidget()
    myWidget.show()
    sys.exit(app.exec_())

结果展示

标签:__,self,练习,cv2,PyQt5,current,OpenCV,图像,image
From: https://blog.csdn.net/mi_shu_zi/article/details/144617408

相关文章

  • 【Unity 计算机视觉插件】OpenCV for Unity 轻松实现图像处理、目标检测、物体识别、A
    OpenCVforUnity是一款功能强大的Unity插件,将著名的计算机视觉库OpenCV无缝集成到Unity中,为开发者提供丰富的计算机视觉功能支持。通过该插件,开发者可以轻松实现图像处理、目标检测、物体识别、AR增强现实等复杂功能,适用于多种平台,包括Windows、macOS、Android、iOS等。功......
  • 基于vgg16和efficientnet卷积神经网络的天气识别系统(pytorch框架) 图像识别与分类 前
    基于vgg16和efficientnet卷积神经网络的天气识别系统(pytorch框架)前端界面:flask+python,UI界面:pyqt5+python这是一个完整项目,包括代码,数据集,模型训练记录,前端界面,ui界面,各种指标图:包括准确率,精确率,召回率,F1值,损失曲线,准确率曲线等卷积模型采用vgg16模型或efficien......
  • 基于OpenCV和Python的人脸识别系统
    一、系统概述基于OpenCV和Python的人脸识别系统利用先进的算法和工具,提供高效、准确的人脸识别服务。该系统可以应用于安全监控、门禁系统、移动支付、智能设备解锁等多个场景,具有广泛的应用价值和商业价值。二、核心组件OpenCV:OpenCV是一个开源的计算机视觉和机器学习......
  • 【C语言练习(13)—打印100以内素数】
    C语言练习(13)文章目录C语言练习(13)问题问题分析结果问题找出100以内的素数,并打印出来问题分析质数(英文名:Primenumber)又称素数,是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。比如5如何判断是不是素数,为了找5的因数,我们可以从2~4逐个找是不是因子,......
  • 【C语言练习(12)—反向输出字符串】
    C语言练习(12)文章目录C语言练习(12)前言题目题目解析结果总结前言对于一个给定的字符串,反方向输出该字符串,本次给了循环和利用指针反向输出两种方法题目给定一个字符串,计算该字符串的个数并反向输出例如给定字符串ILoveStudy则反向输出后为ydutSevoLI题目解析......
  • 17盒子模型练习-设置背景-附加背景图片
    一、元素的水平居中方案这个是在开发中比较常见的功能,就是元素的水平居中,需要元素在父元素中水平居中显示,父元素一般都是块级元素,inline-block如果想要居中目前我们学习了两种方案:行内级元素(包括inline-block元素)水平居中:在父元素中设置text-align:center块级元素水平居中:ma......
  • 第四天案例练习-banner效果
    Banner设计:是一种用于展示品牌、产品或服务信息的网络广告设计。通常以横幅的形式出现在网页或移动端屏幕的顶部,也可以在社交媒体平台上使用<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-wi......
  • 全国高等学校(安徽考区)计算机水平考试,考试模拟app双击登录打开报出“数据库连接错误请
    运行环境为:Win11系统;压缩包:去官网CCT-全国高校计算机水平考试(office,c,python,vb,vfp,access等)模拟系统-更新至2024上半年!-计算机科学与工程学院欢迎您!https://jsj.aust.edu.cn/info/1334/6137.htm一、出现情况为:下载安装后的模拟应用软件双击打开报出:“数据库连接错误请联......
  • OpenCV:C++——边框(copyMakeBorder )和轮廓(findContours ,
    一、添加边框1、函数声明        在OpenCV中,可以使用函数copyMakeBorder为图像设置边界。该函数可以为图像定义额外的填充(边框),原始边缘的行或列被复制到额外的边框。该函数声明如下:CV_EXPORTS_WvoidcopyMakeBorder(InputArraysrc,OutputArraydst,......
  • 类与对象练习——点类
    问题描述多段线(polyline)通常有多个点对象构成,2D空间中的多段线由2D空间中的点构成,这些点依次链接,在二维平面上构成一条多段线,请编写的点类、利用动态内存申请的形式,编写polyline类。要求:1.二维点类;2.多段线中存储的点个数用户可以指定;3.能够计算多段线的长度;4.能够计算这......