【Opencv-PyQt 实战】图像平滑处理小程序

1 篇文章 0 订阅

在尽量保留原有信息的情况下,过滤掉图像内部的噪声,这过程成为图像平滑处理,所得图像为平滑图像

图像平滑的基本原理是:将噪声所在像素点的像素值处理为其周围临近像素点的值的近似值。

本次所写小程序可对图像 .jpg .png .gif 图像进行处理,支持的平滑操作有:

  • 均值滤波
  • 方框滤波
  • 高斯滤波
  • 中值滤波
  • 双边滤波

代码的主要业务实现部分如下:

import sys
import cv2
import numpy as np
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import QApplication, QWidget, QFileDialog
from PyQt5.QtCore import QDir, pyqtSlot

from ui_OpencvFilter import Ui_OpencvFilter


class Qopencv_filter_Qwidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_OpencvFilter()
        self.ui.setupUi(self)
        self.filename = ""
        self.cv_img = np.ndarray(())

    @pyqtSlot()
    def on_pushButtonOpen_clicked(self):
        curPath = QDir.currentPath()
        title = "选择图片"
        filt = "所有文件(*.*);;图片文件(*.jpg *.png *.gif)"
        self.filename, filtUsed = QFileDialog.getOpenFileName(self, title, curPath, filt)
        if self.filename == "":
            return
        pixmap = QPixmap(self.filename)
        if pixmap.width() > 400:
            pixRatio = pixmap.width() / 400
            pixmap.setDevicePixelRatio(pixRatio)
        self.ui.labelImg.setPixmap(pixmap)
        self.ui.labelImg.setScaledContents(True)

    @pyqtSlot()
    def on_pushButtonSave_clicked(self):
        curPath = QDir.currentPath()
        title = "保存图片"
        filt = "所有文件(*.*);;图片文件(*.jpg *.png *.gif)"
        savename, filtUsed = QFileDialog.getSaveFileName(self, title, curPath, filt)
        if savename == "":
            return
        cv2.imwrite(savename, self.cv_img)

    @pyqtSlot()
    def on_pushButtonOrg_clicked(self):
        if self.filename == "":
            return
        pixmap = QPixmap(self.filename)
        if pixmap.width() > 400:
            pixRatio = pixmap.width() / 400
            pixmap.setDevicePixelRatio(pixRatio)
        self.ui.labelImg.setPixmap(pixmap)
        self.ui.labelImg.setScaledContents(True)

    # 高斯滤波
    @pyqtSlot()
    def on_pushButtonGaussian_clicked(self):
        if self.filename == "":
            return
        self.cv_img = cv2.imdecode(np.fromfile(self.filename, dtype=np.uint8), 1)
        self.cv_img = cv2.GaussianBlur(self.cv_img, ksize=(5, 5), sigmaX=0, sigmaY=0)
        self.refreshShow(self.cv_img)

    # 方框滤波
    @pyqtSlot()
    def on_pushButtonBox_clicked(self):
        if self.filename == "":
            return
        self.cv_img = cv2.imdecode(np.fromfile(self.filename, dtype=np.uint8), 1)
        self.cv_img = cv2.boxFilter(self.cv_img, ksize=(5, 5), ddepth=-1)
        self.refreshShow(self.cv_img)

    # 均值滤波
    @pyqtSlot()
    def on_pushButtonBlur_clicked(self):
        if self.filename == "":
            return
        self.cv_img = cv2.imdecode(np.fromfile(self.filename, dtype=np.uint8), 1)
        self.cv_img = cv2.blur(self.cv_img, ksize=(5, 5))
        self.refreshShow(self.cv_img)

    # 中值滤波
    @pyqtSlot()
    def on_pushButtonMedian_clicked(self):
        if self.filename == "":
            return
        self.cv_img = cv2.imdecode(np.fromfile(self.filename, dtype=np.uint8), 1)
        self.cv_img = cv2.medianBlur(self.cv_img, ksize=5)
        self.refreshShow(self.cv_img)

    # 双边滤波
    @pyqtSlot()
    def on_pushButtonBilateral_clicked(self):
        if self.filename == "":
            return
        self.cv_img = cv2.imdecode(np.fromfile(self.filename, dtype=np.uint8), 1)
        self.cv_img = cv2.bilateralFilter(self.cv_img, d=5, sigmaColor=100, sigmaSpace=100)
        self.refreshShow(self.cv_img)

    def refreshShow(self, img):
        # 提取图像的通道和尺寸,用于将OpenCV下的image转换成Qimage
        height, width, channel = img.shape
        bytesPerline = 3 * width
        qimg = QImage(img.data, width, height, bytesPerline, QImage.Format_BGR888)
        pixmap = QPixmap.fromImage(qimg)
        # 将QImage显示出来
        if pixmap.width() > 400:
            pixRatio = pixmap.width() / 400
            pixmap.setDevicePixelRatio(pixRatio)
        self.ui.labelImg.setPixmap(pixmap)
        self.ui.labelImg.setScaledContents(True)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_widget = Qopencv_filter_Qwidget()
    main_widget.show()
    sys.exit(app.exec_())

小程序UI代码部分(由可视化UI界面设计生成)如下:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'OpencvFilter.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_OpencvFilter(object):
    def setupUi(self, OpencvFilter):
        OpencvFilter.setObjectName("OpencvFilter")
        OpencvFilter.setWindowModality(QtCore.Qt.NonModal)
        OpencvFilter.resize(417, 367)
        self.verticalLayout = QtWidgets.QVBoxLayout(OpencvFilter)
        self.verticalLayout.setObjectName("verticalLayout")
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        spacerItem = QtWidgets.QSpacerItem(29, 25, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem, 0, 1, 1, 1)
        spacerItem1 = QtWidgets.QSpacerItem(29, 25, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem1, 1, 1, 1, 1)
        self.pushButtonBox = QtWidgets.QPushButton(OpencvFilter)
        self.pushButtonBox.setObjectName("pushButtonBox")
        self.gridLayout.addWidget(self.pushButtonBox, 0, 2, 1, 1)
        self.pushButtonGaussian = QtWidgets.QPushButton(OpencvFilter)
        self.pushButtonGaussian.setObjectName("pushButtonGaussian")
        self.gridLayout.addWidget(self.pushButtonGaussian, 1, 0, 1, 1)
        spacerItem2 = QtWidgets.QSpacerItem(30, 25, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem2, 0, 3, 1, 1)
        self.pushButtonOrg = QtWidgets.QPushButton(OpencvFilter)
        self.pushButtonOrg.setObjectName("pushButtonOrg")
        self.gridLayout.addWidget(self.pushButtonOrg, 0, 0, 1, 1)
        spacerItem3 = QtWidgets.QSpacerItem(30, 25, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem3, 1, 3, 1, 1)
        self.pushButtonBlur = QtWidgets.QPushButton(OpencvFilter)
        self.pushButtonBlur.setObjectName("pushButtonBlur")
        self.gridLayout.addWidget(self.pushButtonBlur, 0, 4, 1, 1)
        self.pushButtonMedian = QtWidgets.QPushButton(OpencvFilter)
        self.pushButtonMedian.setObjectName("pushButtonMedian")
        self.gridLayout.addWidget(self.pushButtonMedian, 1, 2, 1, 1)
        self.pushButtonBilateral = QtWidgets.QPushButton(OpencvFilter)
        self.pushButtonBilateral.setObjectName("pushButtonBilateral")
        self.gridLayout.addWidget(self.pushButtonBilateral, 1, 4, 1, 1)
        self.verticalLayout.addLayout(self.gridLayout)
        self.labelImg = QtWidgets.QLabel(OpencvFilter)
        self.labelImg.setText("")
        self.labelImg.setObjectName("labelImg")
        self.verticalLayout.addWidget(self.labelImg)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.pushButtonOpen = QtWidgets.QPushButton(OpencvFilter)
        self.pushButtonOpen.setObjectName("pushButtonOpen")
        self.horizontalLayout.addWidget(self.pushButtonOpen)
        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem4)
        self.pushButtonSave = QtWidgets.QPushButton(OpencvFilter)
        self.pushButtonSave.setObjectName("pushButtonSave")
        self.horizontalLayout.addWidget(self.pushButtonSave)
        self.verticalLayout.addLayout(self.horizontalLayout)

        self.retranslateUi(OpencvFilter)
        QtCore.QMetaObject.connectSlotsByName(OpencvFilter)

    def retranslateUi(self, OpencvFilter):
        _translate = QtCore.QCoreApplication.translate
        OpencvFilter.setWindowTitle(_translate("OpencvFilter", "图像平滑处理小程序"))
        self.pushButtonBox.setText(_translate("OpencvFilter", "方框滤波"))
        self.pushButtonGaussian.setText(_translate("OpencvFilter", "高斯滤波"))
        self.pushButtonOrg.setText(_translate("OpencvFilter", "原图"))
        self.pushButtonBlur.setText(_translate("OpencvFilter", "均值滤波"))
        self.pushButtonMedian.setText(_translate("OpencvFilter", "中值滤波"))
        self.pushButtonBilateral.setText(_translate("OpencvFilter", "双边滤波"))
        self.pushButtonOpen.setText(_translate("OpencvFilter", "打开文件"))
        self.pushButtonSave.setText(_translate("OpencvFilter", "保存文件"))

小程序UI展示:

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在这个项目案例中,我们将学习如何使用OpenCVPyQt来实现一个鼠标框选功能。鼠标框选功能允许用户通过拖动鼠标来创建一个矩形框,然后可以在这个框内进行处理。 首先,我们需要创建一个PyQt窗口,并在窗口中显示图像。我们使用OpenCV的`cv2.imshow()`函数来显示图像,并通过PyQt的`QLabel`来将图像显示在窗口中。 接下来,我们需要实现鼠标事件的处理函数。我们可以使用PyQt的信号槽机制来捕获鼠标事件。当用户按下鼠标左键时,我们将记录下鼠标的坐标作为框选的起始点。当用户释放鼠标左键时,我们将记录下鼠标的坐标作为框选的结束点,并根据这两个点创建一个矩形框。 在绘制矩形框时,我们可以使用OpenCV的`cv2.rectangle()`函数来绘制矩形,然后将绘制好的图像显示在窗口中。 最后,我们可以在矩形框内部进行一些处理操作,比如截取矩形框内的图像区域,并对该区域进行一些处理,如图像增强、目标检测等等。 这个鼠标框选的功能在很多场景中非常有用,比如在图像处理、目标检测、图像分割等领域中,我们可以利用这个功能选择目标区域并进行针对性的处理,从而提高处理效率和准确性。 综上所述,通过这个项目案例,我们学习了如何使用OpenCVPyQt来实现鼠标框选功能,并了解了它在图像处理领域中的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卖报的大地主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值