来吧展示期末大作业

本作业由中国农业大学内蒙古校区计算机研究生院下F4团队郭某某所写,朱某某进行翻译解读。今天心情很好发钱了,还发两次欧耶耶!

首先进行描述一下大作业的基本内容吧,本次作业是计算机视觉期末作业,主要完成一下几个功能点:

  1. 对于打开的图像lena.bmp显示其灰度直方图,实现直方图均衡化和绘制直方图。
  2. 实现图像lena.bmp平滑处理,实现均值滤波、方框滤波、高斯滤波和中值滤波。
  3. 实现图像lena.bmp边缘检测,实现Soble算子、Laplacian算子、Robert算子和Canny算子。
  4. 实现图像lena.bmp傅里叶变换,逆傅里叶变换、高通滤波和低筒滤波。
  5. 实现图像lena.bmp几何变换,实现缩放、翻转(绕x轴、绕y轴、绕x轴和y轴)。
  6. 使用OpenCV完成手写数字的识别。

再介绍一下实现功能的基本大框架吧。

1、Tkinter进行GUI设计,OpenCV进行图像处理,PyTorch用于手写数字识别。没毛病

2、图像操作:灰度直方图、平滑处理、均值滤波、方框滤波、高斯滤波、中值滤波、边缘检测、傅里叶变换、图像变换等

最后是代码讲解吧,环境不用说吧,反正我是一下子把代码运行出来了,根本不用第二下。

代码:

import cv2
import numpy as np
from tkinter import filedialog
from matplotlib import pyplot as plt
from PIL import Image, ImageTk
from tkinter import simpledialog
from tkinter import font
from tkinter import simpledialog
import tkinter as tk
import torch
from torchvision import transforms
from handss import Net
#类继承自simpledialog.Dialog,用于创建带有下拉菜单选项的对话框
class OptionDialog(simpledialog.Dialog):
    def __init__(self, parent, title, options):
        self.options = options
        super().__init__(parent, title)
#设置Tkinter窗口的标题、图像标签等界面元素,加载预训练的PyTorch模型,并定义了图像转换
    def body(self, master):
        self.var = tk.StringVar(master)
        self.var.set(self.options[0])
        self.option_menu = tk.OptionMenu(master, self.var, *self.options)
        self.option_menu.pack()
        return self.option_menu

    def apply(self):
        self.result = self.var.get()

#该类包含了图像处理应用程序的各种功能
#该函数进行初始化GUI应用程序
class ImageProcessingApp:
    def __init__(self, root):
        self.root = root
        self.root.title("图像处理应用")

        self.image_label = tk.Label(root)
        self.image_label.pack()

        menu_bar = tk.Menu(root)
        root.config(menu=menu_bar)

        file_menu = tk.Menu(menu_bar, tearoff=0)
        menu_bar.add_cascade(label="文件", menu=file_menu)
        file_menu.add_command(label="打开图像", command=self.open_image)

        process_menu = tk.Menu(menu_bar, tearoff=0)
        menu_bar.add_cascade(label="图像操作", menu=process_menu)
        process_menu.add_command(label="灰度直方图", command=self.show_histogram)
        process_menu.add_command(label="平滑处理", command=self.smooth_image)
        process_menu.add_command(label="均值滤波", command=self.mean_filter)
        process_menu.add_command(label="方框滤波", command=self.box_filter)
        process_menu.add_command(label="高斯滤波", command=self.gaussian_filter)
        process_menu.add_command(label="中值滤波", command=self.median_filter)
        process_menu.add_command(label="边缘检测", command=self.edge_detection)
        process_menu.add_command(label="傅里叶变换", command=self.fourier_transform)
        process_menu.add_command(label="图像变换", command=self.geometric_transform)
        process_menu.add_command(label="手写数字识别", command=self.handwritten_digit_recognition)  # 添加手写数字识别菜单项
        # 加载预训练的 PyTorch 模型
        
        self.model = torch.load('my_model.pth', map_location=torch.device('cpu'))
        self.model.eval()

        # 定义模型输入所需的图像转换
        self.transform = transforms.Compose([
            transforms.ToPILImage(),
            transforms.Grayscale(num_output_channels=1),
            transforms.Resize((8, 8)),
            transforms.ToTensor(),
        ])

        plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文显示
        plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
        # 设置中文显示
        font.nametofont("TkDefaultFont").configure(family="SimHei")


#打开图像
    def open_image(self):
        file_path = filedialog.askopenfilename()
        if file_path:
            self.image = cv2.imread(file_path)
            self.display_image()
#显示图像
    def display_image(self):
        image_rgb = cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)
        image_pil = Image.fromarray(image_rgb)
        image_tk = ImageTk.PhotoImage(image=image_pil)
        self.image_label.config(image=image_tk)
        self.image_label.image = image_tk
        self.root.update()  # 更新 Tkinter 窗口

    def show_histogram(self):
        gray_image = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)#将彩色图像转换为灰度图像
        hist, bins = np.histogram(gray_image.flatten(), 256, [0, 256])#计算灰度直方图
#绘制灰度直方图
        plt.plot(hist, color='gray')
        plt.title("灰度直方图")
        plt.xlabel("灰度值")
        plt.ylabel("像素数量")
        plt.show()

    def smooth_image(self):
        smooth_image = cv2.GaussianBlur(self.image, (5, 5), 0)#使用高斯模糊对图像进行平滑处理
        self.image = smooth_image#将处理后的图像赋值给self.image
        self.display_image()#更新显示图像

    def mean_filter(self):
        #cv的blur函数对图像进行均值滤波处理
        smoothed_image = cv2.blur(self.image, (5, 5))#您可以调整内核大小(例如,(3, 3),(7, 7)等)
        self.image = smoothed_image#将均值滤波处理后的图像赋值给self.image
        self.display_image()

    def box_filter(self):
        # 应用方框滤波(类似于均值滤波)
        smoothed_image = cv2.boxFilter(self.image, -1, (5, 5))#对图像进行方框滤波处理
        self.image = smoothed_image#处理后的图像赋值给self.image
        self.display_image()

    def gaussian_filter(self):
        # 应用高斯滤波
        smoothed_image = cv2.GaussianBlur(self.image, (5, 5), 0)#对图像进行高斯滤波处理
        self.image = smoothed_image#将处理后的图像赋值
        self.display_image()
#调用display_image方法,更新Tkinter窗口中显示的图像,使用户能够看到高斯滤波处理后的效果
    def median_filter(self):
        # 应用中值滤波
        smoothed_image = cv2.medianBlur(self.image, 5)#对图像进行中值滤波处理
        #5表示卷积核的大小,即用于计算每个像素的中值的窗口大小
        self.image = smoothed_image
        self.display_image()

    def edge_detection(self):
        gray_image = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)#将彩图转为灰度图
        sobel_x = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, ksize=5)
        #用sobel算子对x轴和y轴进行边缘检测
        sobel_y = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, ksize=5)
        magnitude = np.sqrt(sobel_x ** 2 + sobel_y ** 2)
#使用sobel算子计算水平和垂直方向的梯度
        plt.imshow(magnitude, cmap='gray')#使用matplotlib库显示边缘强度图像
        plt.title("Sobel算子边缘检测")
        plt.show()

    def fourier_transform(self):
        gray_image = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)#转为灰度图像

        f_transform = np.fft.fft2(gray_image)# 对灰度图像进行二维傅里叶变换
        f_shift = np.fft.fftshift(f_transform)#将零频率分量移到频谱的中心
        magnitude_spectrum = 20 * np.log(np.abs(f_shift))
#计算频谱的幅度谱并对其取对数进行缩放
        plt.imshow(magnitude_spectrum, cmap='gray')#显示傅里叶变换后的频谱图像
        plt.title("傅里叶变换")
        plt.show()

    def geometric_transform(self):
        # 提供缩放、翻转等几何变换的选项
        transform_options = ["缩放", "绕X轴翻转", "绕Y轴翻转", "绕X和Y轴翻转"]

        #OptionDialog类创建一个对话框,以选择几何变换类型
        dialog = OptionDialog(self.root, "几何变换", transform_options)
        selected_option = dialog.result#获取用户选择的几何变换类型
        if selected_option:
            if selected_option == "缩放":
                scale_factor = tk.simpledialog.askfloat("缩放", "请输入缩放因子:", initialvalue=1.0, parent=self.root)
                if scale_factor:
                    scaled_image = cv2.resize(self.image, None, fx=scale_factor, fy=scale_factor)
                    self.image = scaled_image
                    self.display_image()#在应用几何变换后立即展示变换后的图像
            elif selected_option == "绕X轴翻转":
                flipped_image = cv2.flip(self.image, 0)
#flip 函数对图像进行水平翻转(绕X轴翻转),然后更新显示变换后的图像。                
                self.image = flipped_image
                self.display_image()
            elif selected_option == "绕Y轴翻转":
                flipped_image = cv2.flip(self.image, 1)
                self.image = flipped_image
                self.display_image()
            elif selected_option == "绕X和Y轴翻转":
                flipped_image = cv2.flip(self.image, -1)
                self.image = flipped_image
                self.display_image()
#新窗口中显示图像
    def display_image_in_new_window(self, image):
        new_window = tk.Toplevel(self.root)
        new_image_label = tk.Label(new_window)
        new_image_label.pack()

        image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        #将格式(BGR)转换为 RGB 格式
        image_pil = Image.fromarray(image_rgb)
        #使用 PIL 库将其转换为 Image 对象
        image_tk = ImageTk.PhotoImage(image=image_pil)
        #ImageTk 将其转换为 Tkinter 支持的图像对象
        new_image_label.config(image=image_tk)
        #将新创建的ImageTk.PhotoImage 对象设置为新标签的图像属性,
        #并将该对象保存在 new_image_label.image中
        new_image_label.image = image_tk

    # 在ImageProcessingApp类中的handwritten_digit_recognition方法中
    def handwritten_digit_recognition(self):
        if not hasattr(self, 'model'):
            self.__init__()  # 调用 __init__ 方法初始化属性
        # 将 OpenCV 图像转换为 PyTorch 张量
        input_tensor = self.transform(self.image)
        input_tensor = input_tensor.unsqueeze(0)  # 添加批次维度

        # 在这里添加调整图像大小的代码,以匹配模型期望的输入大小
        input_tensor = input_tensor.view(-1, 64)  # 将图像形状调整为 (1, 64)

        # 使用预训练模型进行预测
        with torch.no_grad():
            output = self.model(input_tensor)

        # 获取预测的数字
        predicted_digit = torch.argmax(output).item()

        # 在原图像上显示预测的数字
        cv2.putText(self.image, str(predicted_digit), (10, 30),
                    cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)

        self.display_image()


if __name__ == "__main__":

    root = tk.Tk()
    app = ImageProcessingApp(root)
    root.mainloop()

不知道下学期会不会用到这些CV知识,还是先记录一下吧:

1.2.1直方图均衡化

是一种增强图像对比度的方法,通过重新分布图像的灰度级别,使得各个灰度级别的像素在图像中均匀分布。均衡化的具体步骤如下。

1、计算原始图像的灰度直方图。

2、计算累积分布函数,将直方图中每个灰度级别的像素数量累加,得到一个累积分布。

3、根据累积分布函数的值,将原始图像的每个像素灰度级别映射到新的灰度级别,使得新的灰度级别均匀分布。

1.2.2绘制直方图

目的是将图像的灰度分布可视化。具体步骤如下

1、初始化直方图数组,长度为灰度级别的范围(通常是 0 到 255)。

2、对图像中的每个像素,将其灰度值对应的直方图数组元素加一。

3、将直方图数组中的值归一化,使其范围在 0 到 1 之间,以便在图上显示。

1. 均值滤波:

均值滤波是一种简单的平滑处理方法,通过将每个像素的值替换为周围邻域像素的平均值来实现。具体步骤如下

对图像中的每个像素,取其周围邻域(卷积核)内像素的平均值。

新的像素值替代原始像素值。适用于对噪声进行平滑处理,但可能导致图像边缘信息的丢失。

2. 方框滤波:

方框滤波是一种基本的线性滤波方法,与均值滤波类似,但有一些差别。

对图像中的每个像素,取其周围邻域内像素的平均值。新的像素值替代原始像素值。

这种滤波方法同样可以用于噪声平滑,但较均值滤波在计算上更为高效。

3. 高斯滤波:

高斯滤波是一种基于高斯函数的平滑方法,它通过对图像进行卷积操作来实现。具体步骤

构建高斯核,即一个二维的高斯函数。对图像进行卷积操作,将每个像素值替换为周围邻域内像素的加权平均值。高斯滤波在平滑图像的同时,更加注重保留图像的细节,因为它对周围像素进行加权平均,而权重是由高斯函数决定的。

4. 中值滤波:

中值滤波是一种非线性的滤波方法,使用邻域内像素值的中值来替代当前像素值。具体步骤

对图像中的每个像素,取其周围邻域内像素值的中值。新的像素值替代原始像素值。

中值滤波对于去除椒盐噪声和脉冲噪声等突发性噪声效果较好,因为它不受极端值的干扰,但可能导致图像细节的损失。

1、Sobel算子是基于卷积的边缘检测算子,它分别对图像进行水平和垂直方向的卷积运算。

2、Laplacian算子是一种用于检测图像中的二阶导数的算子。

3、Roberts算子是一种简单的边缘检测算子,它通过以下两个卷积核进行卷积运算:

4、Canny算子是一种多阶段的边缘检测算法,包括高斯滤波、梯度计算、非极大值抑制、双阈值处理和边缘跟踪等步骤。Canny算子的应用能够较好地提取图像中的细节边缘。

下面是各个算子的卷积核

1、傅里叶变换:将一个信号(在这里是图像)从时域转换到频域。对于二维离散傅里叶变换(DFT),可以使用快速傅里叶变换(FFT)算法加速计算。

2、逆傅里叶变换:用于将频域中的信息重新转换回时域,从而得到原始图像。逆傅里叶变换可以使用与傅里叶变换相同的FFT算法来实现。

3、高通滤波:通过去除图像中的低频分量来增强图像中的高频细节。在频域中,可以通过去除低频部分实现高通滤波,常用的方法包括将图像中心的低频区域置零,只保留高频成分。

4、低通滤波通过去除图像中的高频分量来保留图像中的低频信息。在频域中,可以通过去除高频成分实现低通滤波,常用的方法包括截断高频区域或对高频区域进行平滑

图像缩放:

通过调整图像的像素位置和像素值来改变图像的尺寸。对于缩小操作,通常使用插值算法来估算新像素值。对于放大操作,可以通过插值或者直接重复像素值来实现。

图像翻转:是通过交换图像的行或列来实现的。对于绕x轴翻转,交换图像的行;对于绕y轴翻转,交换图像的列;对于绕x轴和y轴翻转,同时交换行和列。

over先到这再见

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
spring root是指Spring框架中的一种配置方式,用于管理系统中的Java类依赖关系并实现控制反转(Inversion of Control)和依赖注入(Dependency Injection)。 在Spring Root期末大作业中,我们需要设计和实现一个基于Spring Root的系统。这个系统可以是一个Web应用、后台管理系统、电子商务平台等等,具体根据各个学生的兴趣和专业方向而定。 这个期末大作业要求我们充分掌握Spring Root的使用,理解控制反转和依赖注入的原理和实现方式。我们需要使用Spring Root来管理和协调系统中各个Java类的依赖关系,提供灵活可扩展的架构。 在实现这个系统的过程中,我们需要编写配置文件,在配置文件中定义和配置各个组件和依赖关系。同时,我们还需要编写Java类,使用注解和注入来实现控制反转和依赖注入。 在这个期末大作业中,我们需要考虑系统的整体架构、模块划分、数据库设计、业务逻辑等等。我们可以使用Spring提供的各种功能和特性,如AOP(面向切面编程)、事务管理、安全性等,来实现系统的高效运行和良好的性能。 通过完成这个期末大作业,我们能够加深对Spring框架的理解和掌握,掌握使用Spring Root来构建复杂系统的能力,提升自己的软件开发能力和团队协作能力。同时,还能够展示我们的设计和编码能力,为将来的工作和学习奠定坚实的基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值