Skip to content

yzxoi/matrix-and-image-processing

Repository files navigation

矩阵与图像处理项目

项目简介

本项目旨在实现一系列基于矩阵运算和图像处理(卷积操作)的功能,同时包含扩展任务(例如 OTSU 算法和目标提取),OTSU 算法直接采用 OpenCV 库中 threshold,目标提取则是简单采取 contours 中面积最大的一块作为目标,其余涂黑。

项目采用模块化设计,将基础功能与扩展功能分别封装到独立的源文件和目录中,便于后续扩展。

此外,本项目同时提供了基于二维数组的矩阵运算(在 Matrix 目录下)和利用一维数组实现的矩阵运算(在 ExtendedMatrix 目录下)。图像处理部分分为基本卷积处理(ImageProcessing 模块)和扩展模块(ExtendedImageProcessing 模块)。

目录结构

├── Matrix.sln // Visual Studio 解决方案文件 
|
├── brain.jpg // 测试图像
├── demolena.jpg
├── polyhedrosis.jpg
├── ship.jpg
├── snowball.jpg
|
├── README.md
|
├── Main.cpp // 主程序入口(二维矩阵和基本与扩展图像处理) 
├── ExtendedMain.cpp // 扩展主程序入口(矩阵运算基于一维数组实现) 
|
├── ImageProcessing.h // 基本图像卷积处理模块接口 
├── ImageProcessing.cpp // 基本图像卷积处理实现
├── ExtendedImageProcessing.h // 扩展图像处理模块接口
├── ExtendedImageProcessing.cpp // 扩展图像处理实现
├── Matrix.h // 二维矩阵运算接口
├── Matrix.cpp // 二维矩阵运算实现
├── ExtendedMatrix.h // 一维数组实现的矩阵运算接口 
└── ExtendedMatrix.cpp // 一维数组实现的矩阵运算

编译与运行

环境要求

  • 开发环境:Visual Studio(推荐使用 VS2022),或其他支持 C++ 和 OpenCV 的 IDE。
  • 依赖库:OpenCV。
  • 操作系统:Windows,使用 _getch() 实现无回车输入。

编译步骤

  1. 将所有源代码和图像文件放置在同一工作目录下,按照上面的目录结构组织文件。
  2. 在 Visual Studio 中打开 Matrix.sln
  3. 配置 OpenCV 的包含目录和库目录。
  4. 编译并运行项目(分别编译 Matrix 项目和 ExtendedMatrix 项目)。
  5. 根据提示在主菜单选择相应功能进行测试。

运行说明

图片处理时,文件目录不应包含空格或中文字符!

  • 主菜单中包含矩阵运算(加法、数乘、转置、乘法、Hadamard 乘积、卷积)、卷积应用(图像处理)、OTSU 算法和目标提取功能。
  • 根据需要切换使用二维矩阵运算(通过 Main.cpp 入口)或一维矩阵运算(通过 ExtendedMain.cpp 入口)。

贡献指南

欢迎提交 Issue 和 Pull Request。

许可证

MIT License

题目描述:矩阵运算

相信你已经在线性代数或者高等代数中接触过矩阵的概念。矩阵是一个按照长方阵列排列的复数或实数集合,支持加法、减法、数乘、乘法等运算。矩阵还具有行列式、秩、特征值和特征向量等重要概念和性质,在数学中广泛应用于线性方程组求解、向量空间变换等方面,同时在物理学、计算机科学、工程学等众多领域也发挥着关键作用,是进行数据处理和分析、解决实际问题的重要数学工具。本次作业要求你实现一个矩阵操作的程序,支持矩阵的一系列运算,并简单探索矩阵在计算机图形学中的应用。详细内容如下:

一、基础项要求

在阅读下面的题目要求前,建议你先下载附件,对照其中的参考代码框架阅读。

附件下载链接: 矩阵运算大作业附件.zip

1. 主菜单

设计一个主菜单,让用户选择具体运算,界面大致如下。退出系统前用户可进行任意次操作。

注意: 用户选择菜单项后不需要输入回车直接跳转到相应选项中。

1

如果输入非法字符(除 $0\sim 7$ 的其他字符),提示输入错误,按回车后刷新界面回到菜单界面。

2. 运算说明

下面是你需要实现功能的具体说明。

(1)矩阵加法

矩阵加法结果为对应元素相加。

$$ \begin{bmatrix} 1 & 2 \ 3 & 4 \end{bmatrix} + \begin{bmatrix} 5 & 6 \ 7 & 8 \end{bmatrix}

\begin{bmatrix} 6 & 8 \ 10 & 12 \end{bmatrix} $$

注意:两个列数、行数都相等的矩阵(同型矩阵),加法运算才有意义。

(2)矩阵数乘

将整数与矩阵中的每一个元素分别相乘所得的矩阵。

$$ \begin{bmatrix} 1 & 2 \ 3 & 4 \end{bmatrix} \times 4

\begin{bmatrix} 4 & 8 \ 12 & 16 \end{bmatrix} $$

(3)矩阵转置

$M\times N$ 的矩阵 $A$ 的行换成同序数的列得到 $N\times M$ 的矩阵 $A^T$:例如

$$ A = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix}, \quad A^T = \begin{bmatrix} 1 & 4 \\ 2 & 5 \\ 3 & 6 \end{bmatrix} $$

(4)矩阵乘法

设矩阵 $$ A = (a_{ij}){m \times s}, \quad B = (b{ij}){s \times n}, $$ 则 $A$ 与 $B$ 的乘积为 $$ C = (c{ij}){m \times n}, \quad \text{其中 } c{ij} = \sum_{k=1}^{s} a_{ik} b_{kj}, \quad (i=1,2,\ldots,m; ; j=1,2,\ldots,n). $$ 比如: $$ \begin{bmatrix} 1 & 2 & 3 \ 4 & 5 & 6 \end{bmatrix} \times \begin{bmatrix} 3 & -4 \ -2 & 5 \ 1 & -6 \end{bmatrix}

\begin{bmatrix} 2 & -12 \ 8 & -27 \end{bmatrix} $$

注意:矩阵 $A$ 的列数和矩阵 $B$ 的行数相等时,矩阵乘法运算才有意义。

(5)Hadamard 乘积

合法性约束与矩阵加法相同,只是对应元素运算变为乘法:

$$ \begin{bmatrix} 1 & 2 \ 3 & 4 \end{bmatrix} \circ \begin{bmatrix} 1 & 2 \ 3 & 4 \end{bmatrix}

\begin{bmatrix} 1 & 4 \ 9 & 16 \end{bmatrix} $$

(6)矩阵卷积

卷积的计算方式如下

10

设矩阵 $A$ 是一个 $5\times5$ 的矩阵;矩阵 $B$ (kernel) 是一个 $3\times3$ 的矩阵。下面是具体步骤与要求:

  1. 先把 $B$ 放到矩阵 $A$ 上,并且 $A$[0,0] 元素与 $B$[0,0] 元素对齐,则重叠出 $3\times3$ 的矩阵。

  2. 再把重叠位置对应的元素相乘,得到 1 个 $3\times3$ 的矩阵([0,0] 位置对齐的结果如下)。

  3. 把上面结果的所有元素相加,得到卷积结果矩阵 [0,0] 位置的值。 $$ 0\times(-1) + 25\times0 + 75\times1 + 0\times(-1) + 75\times0 + 80\times1 + 0\times(-1) + 75\times0 + 80\times1 = 235 $$

  4. 这里采用的步长 (stride) 是 $1$,填补 (padding) 为 $0$。则接下来把 $B$[0,0]$A$[0,1] 对齐,再进行上面步骤的计算,得到结果矩阵 [0,1] 位置的值。当一行计算完成,则把 $B$[0,0]$A$[1,0] 对齐,进行计算,以此类推。

  5. 如果增加填充 (padding),以 padding=1 为例,则在矩阵 $A$ 的外围填补一圈 $0$,使得矩阵 $A$ 变成 $7\times7$ 的矩阵。

  6. 不考虑 dilation.

注意: 本次作业要求 kernel size = 3, padding = 1, stride = 1, dilation = 1;可参考示例网站:https://ezyang.github.io/convolution-visualizer/index.html.

(7)卷积应用

实现一个利用卷积操作应用与图像处理的简单示例:
假设矩阵 $A$ 为原灰度图 demolena.jpg(大小为 $256\times256$),灰度值为矩阵值(int),分别采用如下卷积核(矩阵 $B$)进行卷积运算,并将得到的矩阵除以卷积核的总和(如 $B_1$ 的卷积核总和为 $9$,总和为 $0$ 时不做处理),保存为灰度图观察结果: $$ \begin{align} B_1)&; \begin{bmatrix} 1 & 1 & 1 \ 1 & 1 & 1 \ 1 & 1 & 1 \ \end{bmatrix}, \quad B_2)&; \begin{bmatrix} -1 & -2 & -1 \ 0 & 0 & 0 \ 1 & 2 & 1 \ \end{bmatrix}, \quad B_3)&; \begin{bmatrix} -1 & 0 & 1 \ -2 & 0 & 2 \ -1 & 0 & 1 \ \end{bmatrix} \ B_4)&; \begin{bmatrix} -1 & -1 & -1 \ -1 & 9 & -1 \ -1 & -1 & -1 \ \end{bmatrix}, \quad B_5)&; \begin{bmatrix} -1 & -1 & 0 \ -1 & 0 & 1 \ 0 & 1 & 1 \ \end{bmatrix}, \quad B_6)&; \begin{bmatrix} 1 & 2 & 1 \ 2 & 4 & 2 \ 1 & 2 & 1 \ \end{bmatrix} \end{align} $$

提示:这都是数字图像处理中非常经典的滤波器,所得到的图片效果也不尽相同,注意观察并分析原因。

对于这一部分内容,请认真阅读 “vs+opencv 配置说明”,操作完成后,取消框架程序开始的两段注释:

#include <opencv2/opencv.hpp>
using namespace cv;

然后完成 demo 函数功能,将原图和不同卷积操作后的图像显示在屏幕上,并观察结果。具体包括:

  1. 读取原图并显示;
  2. 计算原图矩阵与卷积核 $B_1$ 的卷积结果并图像显示;
  3. 计算原图矩阵与卷积核 $B_2$ 的卷积结果并图像显示;
  4. 计算原图矩阵与卷积核 $B_3$ 的卷积结果并图像显示;
  5. 计算原图矩阵与卷积核 $B_4$ 的卷积结果并图像显示;
  6. 计算原图矩阵与卷积核 $B_5$ 的卷积结果并图像显示;
  7. 计算原图矩阵与卷积核 $B_6$ 的卷积结果并图像显示。

二、加分项要求

学有余力的同学可以选取下面一个或多个任务完成。加分项开放使用 opencv 库函数。

1. 一维数组

使用一维数组实现上述功能。

2. OTSU算法实现

在菜单中加入功能 “8 OTSU 算法”,并完成下述功能:使用 OTSU 算法对 lena 图像进行二值化,结果如下所示:

12

请自行学习该算法原理与实现方法。

3. 目标提取

你已经掌握了上述图像处理的简单方法—二值化,请在此基础上配合其它方法,对下述测试样例进行处理,保留目标区域并设置背景为黑色,结果如下所示,处理结果类似即可,没有标准答案:

① 实验室前任团宠“雪球” - snowball.jpg (200×150)
13

② 多角星形 - polyhedrosis.jpg (98×90)
14

③ 船舰 - ship.jpg (128×96)
15

④ 脑部影像截取 - brain.jpg (119×78)
16

提交要求

请按照文件打包要求上传你的项目代码。务必记得清除不必要的文件(包括一些隐藏文件)!

About

Lab work #1 of Advanced Programming (Basic), Tongji Univ, Sem 2, 2024-2025.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages