(图像处理)课上小作业04

本文介绍了如何使用Qt Creator创建用户界面(UI),并展示了如何通过信号和槽函数实现文件操作、图像处理功能,包括添加噪声、腐蚀、膨胀、开运算和闭运算。重点展示了open_buttonclicked、add_noise_btn_clicked等槽函数的实现。
摘要由CSDN通过智能技术生成

1、Qt Creator创建UI

在这里插入图片描述
将UI转换为py脚本的方法如上文所示

2、添加信号和槽函数

# 绑定槽函数
self.open_btn.clicked.connect(self.open_buttonclicked)
self.add_noise_btn.clicked.connect(self.add_noise_btn_clicked)
self.erode_btn.clicked.connect(self.erode_btn_clicked)
self.dilate_btn.clicked.connect(self.dilate_btn_clicked)
self.openning_btn.clicked.connect(self.openning_btn_clicked)
self.closing_btn.clicked.connect(self.closing_btn_clicked)

定义槽函数


    # 打开文件按钮的槽函数
    def open_buttonclicked(self):
        fileName, fileType = QFileDialog.getOpenFileName(self, "选取文件", os.getcwd(),"All Files(*);;Text Files(*.txt)")
        # print("fileName: ",fileName)
        # print("fileType: ",fileType)
        save_fpath=self.scaleImg(fileName)
        if save_fpath is not None:
            print("文件已存在:{}".format(save_fpath))
        self.ori_path=save_fpath
        pix = QPixmap(save_fpath)
        self.ori_lb.setPixmap(pix)

    # 添加噪声按钮的槽函数
    def add_noise_btn_clicked(self):
        try:
            img=cv2.imread(self.ori_path)
            print("img", len(img))
            noise_img=self.salt_and_pepper_noise(img)
            print("noise_img", len(img))
            dir = os.path.dirname(self.ori_path)
            fname = self.ori_path.split('/')[-1]
            noise_fname='/noise_'+fname
            noise_fpath=dir+noise_fname
            self.noise_fpath=noise_fpath

            if os.path.exists(noise_fpath):
                # 读入噪声图
                pix = QPixmap(self.noise_fpath)
                self.noise_lb.setPixmap(pix)
            else:
                cv2.imwrite(noise_fpath, noise_img)
        except Exception as e:
            print(e)

    # 腐蚀按钮的槽函数
    def erode_btn_clicked(self):
        img = cv2.imread(self.noise_fpath, 0)
        # 转为二值图
        ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

        # 中值滤波
        lbimg = cv2.medianBlur(th1, 3)

        # 开始腐蚀操作
        kernel = np.ones((3, 3), np.uint8)
        erosion = cv2.erode(lbimg, kernel, iterations=1)

        dir = os.path.dirname(self.noise_fpath)
        fname = self.noise_fpath.split('/')[-1]
        self.erode_fpath=dir+'/erode_'+fname
        if os.path.exists(self.erode_fpath):
            pix = QPixmap(self.erode_fpath)
            self.erode_lb.setPixmap(pix)
        else:
            cv2.imwrite(self.erode_fpath, erosion)

    # 膨胀按钮的槽函数
    def dilate_btn_clicked(self):
        img = cv2.imread(self.noise_fpath, 0)
        # 转为二值图
        ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

        # 中值滤波
        lbimg = cv2.medianBlur(th1, 3)

        # 开始膨胀操作
        kernel = np.ones((3, 3), np.uint8)
        erosion = cv2.dilate(lbimg, kernel, iterations=1)

        dir = os.path.dirname(self.noise_fpath)
        fname = self.noise_fpath.split('/')[-1]
        self.dilate_path=dir+'/dilate_'+fname
        if os.path.exists(self.dilate_path):
            pix = QPixmap(self.dilate_path)
            self.dilate_lb.setPixmap(pix)
        else:
            cv2.imwrite(self.dilate_path, erosion)

    # 开运算按钮的槽函数
    def openning_btn_clicked(self):
        img = cv2.imread(self.noise_fpath, 0)
        # 转为二值图
        ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

        # 中值滤波
        lbimg = cv2.medianBlur(th1, 3)

        # 开始开运算操作
        kernel = np.ones((3, 3), np.uint8)
        opening = cv2.morphologyEx(lbimg, cv2.MORPH_OPEN, kernel, 3)

        dir = os.path.dirname(self.noise_fpath)
        fname = self.noise_fpath.split('/')[-1]
        self.openning_path=dir+'/openning_'+fname
        if os.path.exists(self.openning_path):
            pix = QPixmap(self.openning_path)
            self.openning_lb.setPixmap(pix)
        else:
            cv2.imwrite(self.openning_path, opening)

    # 闭运算按钮的槽函数
    def closing_btn_clicked(self):
        img = cv2.imread(self.noise_fpath, 0)
        # 转为二值图
        ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

        # 中值滤波
        lbimg = cv2.medianBlur(th1, 3)

        # 开始闭运算操作
        kernel = np.ones((3, 3), np.uint8)
        closing = cv2.morphologyEx(lbimg, cv2.MORPH_CLOSE, kernel)

        dir = os.path.dirname(self.noise_fpath)
        fname = self.noise_fpath.split('/')[-1]
        self.closing_path = dir + '/closing_' + fname
        if os.path.exists(self.closing_path):
            pix = QPixmap(self.closing_path)
            self.closing_lb.setPixmap(pix)
        else:
            cv2.imwrite(self.closing_path, closing)

完整代码

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

# Form implementation generated from reading ui file 'dialog2.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
from PyQt5.QtWidgets import (QWidget, QApplication,QLabel,QFileDialog,QPushButton,QHBoxLayout,QLineEdit)
from PyQt5.QtGui import QPixmap,QImage
import os
import cv2
import sys
import random
import numpy as np


class Ui_Dialog(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.ori_path=''
        self.noise_fpath=''
        self.erode_fpath=''
        self.dilate_path=''
        self.openning_path=''
        self.closing_path=''

    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(932, 545)
        self.horizontalLayoutWidget = QtWidgets.QWidget(Dialog)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 90, 281, 181))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.ori_lb = QtWidgets.QLabel(self.horizontalLayoutWidget)
        self.ori_lb.setObjectName("ori_lb")
        self.horizontalLayout.addWidget(self.ori_lb)
        self.open_btn = QtWidgets.QPushButton(Dialog)
        self.open_btn.setGeometry(QtCore.QRect(200, 60, 93, 28))
        self.open_btn.setObjectName("open_btn")
        self.horizontalLayoutWidget_2 = QtWidgets.QWidget(Dialog)
        self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(330, 90, 281, 181))
        self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.erode_lb = QtWidgets.QLabel(self.horizontalLayoutWidget_2)
        self.erode_lb.setObjectName("erode_lb")
        self.horizontalLayout_2.addWidget(self.erode_lb)
        self.horizontalLayoutWidget_3 = QtWidgets.QWidget(Dialog)
        self.horizontalLayoutWidget_3.setGeometry(QtCore.QRect(330, 310, 281, 181))
        self.horizontalLayoutWidget_3.setObjectName("horizontalLayoutWidget_3")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_3)
        self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.openning_lb = QtWidgets.QLabel(self.horizontalLayoutWidget_3)
        self.openning_lb.setObjectName("openning_lb")
        self.horizontalLayout_3.addWidget(self.openning_lb)
        self.horizontalLayoutWidget_4 = QtWidgets.QWidget(Dialog)
        self.horizontalLayoutWidget_4.setGeometry(QtCore.QRect(640, 310, 281, 181))
        self.horizontalLayoutWidget_4.setObjectName("horizontalLayoutWidget_4")
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_4)
        self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.closing_lb = QtWidgets.QLabel(self.horizontalLayoutWidget_4)
        self.closing_lb.setObjectName("closing_lb")
        self.horizontalLayout_4.addWidget(self.closing_lb)
        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(20, 70, 72, 15))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(Dialog)
        self.label_2.setGeometry(QtCore.QRect(330, 70, 72, 15))
        self.label_2.setObjectName("label_2")
        self.horizontalLayoutWidget_5 = QtWidgets.QWidget(Dialog)
        self.horizontalLayoutWidget_5.setGeometry(QtCore.QRect(640, 90, 281, 181))
        self.horizontalLayoutWidget_5.setObjectName("horizontalLayoutWidget_5")
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_5)
        self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.dilate_lb = QtWidgets.QLabel(self.horizontalLayoutWidget_5)
        self.dilate_lb.setObjectName("dilate_lb")
        self.horizontalLayout_5.addWidget(self.dilate_lb)
        self.label_3 = QtWidgets.QLabel(Dialog)
        self.label_3.setGeometry(QtCore.QRect(640, 70, 72, 15))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(Dialog)
        self.label_4.setGeometry(QtCore.QRect(330, 290, 72, 15))
        self.label_4.setObjectName("label_4")
        self.label_5 = QtWidgets.QLabel(Dialog)
        self.label_5.setGeometry(QtCore.QRect(640, 290, 72, 15))
        self.label_5.setObjectName("label_5")
        self.label_6 = QtWidgets.QLabel(Dialog)
        self.label_6.setGeometry(QtCore.QRect(20, 290, 72, 15))
        self.label_6.setObjectName("label_6")
        self.horizontalLayoutWidget_6 = QtWidgets.QWidget(Dialog)
        self.horizontalLayoutWidget_6.setGeometry(QtCore.QRect(20, 310, 281, 181))
        self.horizontalLayoutWidget_6.setObjectName("horizontalLayoutWidget_6")
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_6)
        self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.noise_lb = QtWidgets.QLabel(self.horizontalLayoutWidget_6)
        self.noise_lb.setObjectName("noise_lb")
        self.horizontalLayout_6.addWidget(self.noise_lb)
        self.add_noise_btn = QtWidgets.QPushButton(Dialog)
        self.add_noise_btn.setGeometry(QtCore.QRect(200, 280, 93, 28))
        self.add_noise_btn.setObjectName("add_noise_btn")
        self.erode_btn = QtWidgets.QPushButton(Dialog)
        self.erode_btn.setGeometry(QtCore.QRect(510, 60, 93, 28))
        self.erode_btn.setObjectName("erode_btn")
        self.dilate_btn = QtWidgets.QPushButton(Dialog)
        self.dilate_btn.setGeometry(QtCore.QRect(820, 60, 93, 28))
        self.dilate_btn.setObjectName("dilate_btn")
        self.openning_btn = QtWidgets.QPushButton(Dialog)
        self.openning_btn.setGeometry(QtCore.QRect(510, 280, 93, 28))
        self.openning_btn.setObjectName("openning_btn")
        self.closing_btn = QtWidgets.QPushButton(Dialog)
        self.closing_btn.setGeometry(QtCore.QRect(820, 280, 93, 28))
        self.closing_btn.setObjectName("closing_btn")

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

        # 绑定槽函数
        self.open_btn.clicked.connect(self.open_buttonclicked)
        self.add_noise_btn.clicked.connect(self.add_noise_btn_clicked)
        self.erode_btn.clicked.connect(self.erode_btn_clicked)
        self.dilate_btn.clicked.connect(self.dilate_btn_clicked)
        self.openning_btn.clicked.connect(self.openning_btn_clicked)
        self.closing_btn.clicked.connect(self.closing_btn_clicked)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.ori_lb.setText(_translate("Dialog", "原图"))
        self.open_btn.setText(_translate("Dialog", "打开文件"))
        self.erode_lb.setText(_translate("Dialog", "腐蚀图"))
        self.openning_lb.setText(_translate("Dialog", "开运算结果"))
        self.closing_lb.setText(_translate("Dialog", "闭运算结果"))
        self.label.setText(_translate("Dialog", "原图:"))
        self.label_2.setText(_translate("Dialog", "腐蚀:"))
        self.dilate_lb.setText(_translate("Dialog", "膨胀图"))
        self.label_3.setText(_translate("Dialog", "膨胀:"))
        self.label_4.setText(_translate("Dialog", "开运算:"))
        self.label_5.setText(_translate("Dialog", "闭运算:"))
        self.label_6.setText(_translate("Dialog", "加椒盐噪声:"))
        self.noise_lb.setText(_translate("Dialog", "噪声图"))
        self.add_noise_btn.setText(_translate("Dialog", "加噪声"))
        self.erode_btn.setText(_translate("Dialog", "腐蚀"))
        self.dilate_btn.setText(_translate("Dialog", "膨胀"))
        self.openning_btn.setText(_translate("Dialog", "开运算"))
        self.closing_btn.setText(_translate("Dialog", "闭运算"))

    # 打开文件按钮的槽函数
    def open_buttonclicked(self):
        fileName, fileType = QFileDialog.getOpenFileName(self, "选取文件", os.getcwd(),"All Files(*);;Text Files(*.txt)")
        # print("fileName: ",fileName)
        # print("fileType: ",fileType)
        save_fpath=self.scaleImg(fileName)
        if save_fpath is not None:
            print("文件已存在:{}".format(save_fpath))
        self.ori_path=save_fpath
        pix = QPixmap(save_fpath)
        self.ori_lb.setPixmap(pix)

    # 把图像放缩到合适大小
    def scaleImg(self,fpath):
        dir = os.path.dirname(fpath)
        fname = fpath.split('/')[-1]
        save_fpath=dir+'/cvt_'+fname
        if os.path.exists(save_fpath):
            return save_fpath
        img=cv2.imread(fpath)
        img_test2 = cv2.resize(img, (300, 200),interpolation=cv2.INTER_NEAREST)
        cv2.imwrite(save_fpath,img_test2)
        return save_fpath

    # 添加噪声按钮的槽函数
    def add_noise_btn_clicked(self):
        try:
            img=cv2.imread(self.ori_path)
            print("img", len(img))
            noise_img=self.salt_and_pepper_noise(img)
            print("noise_img", len(img))
            dir = os.path.dirname(self.ori_path)
            fname = self.ori_path.split('/')[-1]
            noise_fname='/noise_'+fname
            noise_fpath=dir+noise_fname
            self.noise_fpath=noise_fpath

            if os.path.exists(noise_fpath):
                # 读入噪声图
                pix = QPixmap(self.noise_fpath)
                self.noise_lb.setPixmap(pix)
            else:
                cv2.imwrite(noise_fpath, noise_img)
        except Exception as e:
            print(e)

    # 加入椒盐噪声
    def salt_and_pepper_noise(self,img, proportion=0.01):
        # 在加上self之前,传入的实参是numpy.ndarray类型,但进来后形参就变成Ui_Dialog类型了,然后就报错
        noise_img = img

        height, width = noise_img.shape[0], noise_img.shape[1]
        num = int(height * width * proportion)  # 多少个像素点添加椒盐噪声
        for i in range(num):
            w = random.randint(0, width - 1)
            h = random.randint(0, height - 1)
            if random.randint(0, 1) == 0:
                noise_img[h, w] = 0
            else:
                noise_img[h, w] = 255
        return noise_img

    # 腐蚀按钮的槽函数
    def erode_btn_clicked(self):
        img = cv2.imread(self.noise_fpath, 0)
        # 转为二值图
        ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

        # 中值滤波
        lbimg = cv2.medianBlur(th1, 3)

        # 开始腐蚀操作
        kernel = np.ones((3, 3), np.uint8)
        erosion = cv2.erode(lbimg, kernel, iterations=1)

        dir = os.path.dirname(self.noise_fpath)
        fname = self.noise_fpath.split('/')[-1]
        self.erode_fpath=dir+'/erode_'+fname
        if os.path.exists(self.erode_fpath):
            pix = QPixmap(self.erode_fpath)
            self.erode_lb.setPixmap(pix)
        else:
            cv2.imwrite(self.erode_fpath, erosion)

    # 膨胀按钮的槽函数
    def dilate_btn_clicked(self):
        img = cv2.imread(self.noise_fpath, 0)
        # 转为二值图
        ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

        # 中值滤波
        lbimg = cv2.medianBlur(th1, 3)

        # 开始膨胀操作
        kernel = np.ones((3, 3), np.uint8)
        erosion = cv2.dilate(lbimg, kernel, iterations=1)

        dir = os.path.dirname(self.noise_fpath)
        fname = self.noise_fpath.split('/')[-1]
        self.dilate_path=dir+'/dilate_'+fname
        if os.path.exists(self.dilate_path):
            pix = QPixmap(self.dilate_path)
            self.dilate_lb.setPixmap(pix)
        else:
            cv2.imwrite(self.dilate_path, erosion)

    # 开运算按钮的槽函数
    def openning_btn_clicked(self):
        img = cv2.imread(self.noise_fpath, 0)
        # 转为二值图
        ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

        # 中值滤波
        lbimg = cv2.medianBlur(th1, 3)

        # 开始开运算操作
        kernel = np.ones((3, 3), np.uint8)
        opening = cv2.morphologyEx(lbimg, cv2.MORPH_OPEN, kernel, 3)

        dir = os.path.dirname(self.noise_fpath)
        fname = self.noise_fpath.split('/')[-1]
        self.openning_path=dir+'/openning_'+fname
        if os.path.exists(self.openning_path):
            pix = QPixmap(self.openning_path)
            self.openning_lb.setPixmap(pix)
        else:
            cv2.imwrite(self.openning_path, opening)

    # 闭运算按钮的槽函数
    def closing_btn_clicked(self):
        img = cv2.imread(self.noise_fpath, 0)
        # 转为二值图
        ret1, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

        # 中值滤波
        lbimg = cv2.medianBlur(th1, 3)

        # 开始闭运算操作
        kernel = np.ones((3, 3), np.uint8)
        closing = cv2.morphologyEx(lbimg, cv2.MORPH_CLOSE, kernel)

        dir = os.path.dirname(self.noise_fpath)
        fname = self.noise_fpath.split('/')[-1]
        self.closing_path = dir + '/closing_' + fname
        if os.path.exists(self.closing_path):
            pix = QPixmap(self.closing_path)
            self.closing_lb.setPixmap(pix)
        else:
            cv2.imwrite(self.closing_path, closing)
def main():
    """
    主函数,用于运行程序
    :return: None
    """
    app = QtWidgets.QApplication(sys.argv)
    dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(dialog)
    dialog.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

最终效果

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值