iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >NumPy实现多维数组中的线性代数
  • 826
分享到

NumPy实现多维数组中的线性代数

2024-04-02 19:04:59 826人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录简介图形加载和说明图形的灰度灰度图像的压缩原始图像的压缩总结简介 本文将会以图表的形式为大家讲解怎么在NumPy中进行多维数据的线性代数运算。 多维数据的线性代数通常被用在图像

简介

本文将会以图表的形式为大家讲解怎么在NumPy中进行多维数据的线性代数运算。
多维数据的线性代数通常被用在图像处理的图形变换中,本文将会使用一个图像的例子进行说明。

图形加载和说明

熟悉颜色的朋友应该都知道,一个颜色可以用R,G,B来表示,如果更高级一点,那么还有一个A表示透明度。通常我们用一个四个属性的数组来表示。

对于一个二维的图像来说,其分辨率可以看做是一个X*Y的矩阵,矩阵中的每个点的颜色都可以用(R,G,B)来表示。

有了上面的知识,我们就可以对图像的颜色进行分解了。

首先需要加载一个图像,我们使用imageio.imread方法来加载一个本地图像,如下所示:


import imageio
img=imageio.imread('img.png')
print(type(img))

上面的代码从本地读取图片到img对象中,使用type可以查看img的类型,从运行结果,我们可以看到img的类型是一个数组。


class 'imageio.core.util.Array'

通过img.shape可以得到img是一个(80, 170, 4)的三维数组,也就是说这个图像的分辨率是80*170,每个像素是一个(R,B,G,A)的数组。

最后将图像画出来如下所示:


import matplotlib.pyplot as plt
plt.imshow(img)

图形的灰度

对于三维数组来说,我们可以分别得到三种颜色的数组如下所示:


red_array = img_array[:, :, 0]
green_array = img_array[:, :, 1]
blue_array = img_array[:, :, 2]

有了三个颜色之后我们可以使用下面的公式对其进行灰度变换:


Y=0.2126R + 0.7152G + 0.0722B

上图中Y表示的是灰度。
怎么使用矩阵的乘法呢?使用 @ 就可以了:


 img_gray = img_array @ [0.2126, 0.7152, 0.0722]

现在img是一个80 * 170的矩阵。
现在使用cmap="gray"作图:


plt.imshow(img_gray, cmap="gray")

可以得到下面的灰度图像:

灰度图像的压缩

灰度图像是对图像的颜色进行变换,如果要对图像进行压缩该怎么处理呢?

矩阵运算中有一个概念叫做奇异值和特征值。

设A为n阶矩阵,若存在常数λ及n维非零向量x,使得Ax=λx,则称λ是矩阵A的特征值,x是A属于特征值λ的特征向量。

一个矩阵的一组特征向量是一组正交向量。

即特征向量被施以线性变换 A 只会使向量伸长或缩短而其方向不被改变。

特征分解(Eigendecomposition),又称谱分解(Spectral decomposition)是将矩阵分解为由其特征值和特征向量表示的矩阵之积的方法。

假如A是m * n阶矩阵,q=min(m,n),A*A的q个非负特征值的算术平方根叫作A的奇异值。

特征值分解可以方便的提取矩阵的特征,但是前提是这个矩阵是一个方阵。如果是非方阵的情况下,就需要用到奇异值分解了。先看下奇异值分解的定义:

A=UΣVT

其中A是目标要分解的m * n的矩阵,U是一个 m * m的方阵,Σ 是一个m * n 的矩阵,其非对角线上的元素都是0。VTV^TVT是V的转置,也是一个n * n的矩阵。

奇异值跟特征值类似,在矩阵Σ中也是从大到小排列,而且奇异值的减少特别的快,在很多情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上了。也就是说,我们也可以用前r大的奇异值来近似描述矩阵。r是一个远小于m、n的数,这样就可以进行压缩矩阵。

通过奇异值分解,我们可以通过更加少量的数据来近似替代原矩阵。

要想使用奇异值分解svd可以直接调用linalg.svd 如下所示:


U, s, Vt = linalg.svd(img_gray)

其中U是一个m * m矩阵,Vt是一个n * n矩阵。

在上述的图像中,U是一个(80, 80)的矩阵,而Vt是一个(170, 170) 的矩阵。而s是一个80的数组,s包含了img中的奇异值。

如果将s用图像来表示,我们可以看到大部分的奇异值都集中在前的部分:

这也就意味着,我们可以取s中前面的部分值来进行图像的重构。
使用s对图像进行重构,需要将s还原成80 * 170 的矩阵:


# 重建
import numpy as np
Sigma = np.zeros((80, 170))
for i in range(80):
    Sigma[i, i] = s[i]

使用 U @ Sigma @ Vt 即可重建原来的矩阵,可以通过计算linalg.nORM来比较一下原矩阵和重建的矩阵之间的差异。


linalg.norm(img_gray - U @ Sigma @ Vt)

或者使用np.allclose来比较两个矩阵的不同:


np.allclose(img_gray, U @ Sigma @ Vt)

或者只取s数组的前10个元素,进行重新绘图,比较一下和原图的区别:


k = 10
approx = U @ Sigma[:, :k] @ Vt[:k, :]
plt.imshow(approx, cmap="gray")

可以看到,差异并不是很大:

原始图像的压缩

上一节我们讲到了如何进行灰度图像的压缩,那么如何对原始图像进行压缩呢?

同样可以使用linalg.svd对矩阵进行分解。

但是在使用前需要进行一些处理,因为原始图像的img_array 是一个(80, 170, 3)的矩阵--这里我们将透明度去掉了,只保留了R,B,G三个属性。

在进行转换之前,我们需要把不需要变换的轴放到最前面,也就是说将index=2,换到index=0的位置,然后进行svd操作:


img_array_transposed = np.transpose(img_array, (2, 0, 1))
print(img_array_transposed.shape)

U, s, Vt = linalg.svd(img_array_transposed)
print(U.shape, s.shape, Vt.shape)

同样的,现在s是一个(3, 80)的矩阵,还是少了一维,如果重建图像,需要将其进行填充和处理,最后将重建的图像输出:


Sigma = np.zeros((3, 80, 170))

for j in range(3):
    np.fill_diaGonal(Sigma[j, :, :], s[j, :])

reconstructed = U @ Sigma @ Vt
print(reconstructed.shape)

plt.imshow(np.transpose(reconstructed, (1, 2, 0)))

当然,也可以选择前面的K个特征值对图像进行压缩:


approx_img = U @ Sigma[..., :k] @ Vt[..., :k, :]
print(approx_img.shape)
plt.imshow(np.transpose(approx_img, (1, 2, 0)))

重新构建的图像如下:

对比可以发现,虽然损失了部分精度,但是图像还是可以分辨的。

总结

图像的变化会涉及到很多线性运算,大家可以以此文为例,仔细研究。

到此这篇关于NumPy实现多维数组中的线性代数的文章就介绍到这了,更多相关NumPy 多维数组线性代数内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: NumPy实现多维数组中的线性代数

本文链接: https://www.lsjlt.com/news/131486.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • NumPy实现多维数组中的线性代数
    目录简介图形加载和说明图形的灰度灰度图像的压缩原始图像的压缩总结简介 本文将会以图表的形式为大家讲解怎么在NumPy中进行多维数据的线性代数运算。 多维数据的线性代数通常被用在图像...
    99+
    2022-11-12
  • NumPy怎么实现多维数组中的线性代数
    本篇内容介绍了“NumPy怎么实现多维数组中的线性代数”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录简介图形加载和说明图形的灰度灰度图像...
    99+
    2023-06-20
  • NumPy实现ndarray多维数组操作
    目录简介 创建ndarray ndarray的属性 ndarray中元素的类型转换 ndarray的数学运算 index和切片 基本使用 index with slice boole...
    99+
    2022-11-12
  • NumPy迭代数组的实现
    目录迭代数组一、单数组迭代1. 使用 nditer 访问数组的每个元素2. 控制数组元素的迭代顺序3. 修改数组值4. 使用外部循环,跟踪索引或多索引5. 以特定数据类型迭代二、广播...
    99+
    2023-02-19
    NumPy迭代数组 NumPy数组迭代
  • C#中的矩形数组(多维数组)和锯齿数组的实现
    目录(一)矩形数组(二)锯齿数组总结(一)矩形数组 在C#中,矩形数组(rectangular array),又称多维数组,是使用多个索引访问其元素的数组。 1. 二维数组的声明: ...
    99+
    2023-05-15
    C# 矩形数组 C# 锯齿数组 C# 多维数组
  • numpy之多维数组的创建全过程
    目录numpy多维数组的创建1.1 随机抽样创建1.2 序列创建1.3 数组重新排列1.4 数据类型的转换1.5 数组转列表numpy 多维数组相关问题创建(多维)数组数组赋值np数...
    99+
    2023-05-12
    numpy多维数组 numpy多维数组创建 numpy创建多维数组
  • NumPy迭代数组如何实现
    本文小编为大家详细介绍“NumPy迭代数组如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“NumPy迭代数组如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。迭代数组NumPy中引入了 nditer ...
    99+
    2023-07-05
  • 怎么实现NumPy迭代数组
    这篇文章主要介绍“怎么实现NumPy迭代数组”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么实现NumPy迭代数组”文章能帮助大家解决问题。迭代数组NumPy中引入了 nditer 对象来提供一种...
    99+
    2023-07-05
  • Numpy实现矩阵运算及线性代数应用
    目录一、创建矩阵的方法二、矩阵运算 2.1随机函数表2.2部分实例三、通用函数3.1 一元通用函数3.2二元通用函数四、矩阵运算-add运算4.1矩阵元素求和—reduce...
    99+
    2022-11-11
  • php多维数组的底层实现
    随着互联网时代的发展,PHP语言在Web方面占据了举足轻重的地位。而多维数组作为PHP语言中最常用的数据结构之一,其在程序开发中具有重要的应用价值。本文将针对PHP多维数组的底层实现进行深入分析,以期为读者提供更加深入的了解。一、多维数组的...
    99+
    2023-05-19
  • PHP中怎么实现多维数组排序
    这篇文章将为大家详细讲解有关PHP中怎么实现多维数组排序,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。根据数组的键进行比较大小,排序,就不用说了,php有很多,很方便的内置函数,krsort...
    99+
    2023-06-17
  • Numpy如何实现矩阵运算及线性代数应用
    这篇文章主要介绍了Numpy如何实现矩阵运算及线性代数应用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、创建矩阵的方法import numpy as&...
    99+
    2023-06-14
  • nditer—numpy.ndarray 多维数组的迭代操作
    1. Single array iteration >>> a = np.arange(6).reshape(2,3) >>> for x i...
    99+
    2022-11-12
  • Numpy中的多维数组索引,你知道如何使用吗?
    Numpy是Python中用于科学计算的重要库,它提供了许多强大的工具来处理多维数组,这些数组是科学计算中最常用的数据结构之一。在本文中,我们将介绍Numpy中的多维数组索引,以及如何使用它们来访问和操作数组中的数据。 一维数组索引 让我们...
    99+
    2023-06-14
    http numpy 索引
  • Numpy三维数组索引与切片如何实现
    今天小编给大家分享一下Numpy三维数组索引与切片如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。这是一个三维数组,关...
    99+
    2023-07-05
  • 打包多个NumPy数组,Python中该如何实现?
    在Python中使用NumPy进行科学计算时,我们通常会处理多个数组。当需要将多个NumPy数组打包成一个数组时,我们可以使用NumPy库中的np.stack()函数。本文将详细介绍如何使用np.stack()函数打包多个NumPy数组。 ...
    99+
    2023-08-04
    numy 索引 打包
  • PHP如何实现多维数组降级
    这篇文章将为大家详细讲解有关PHP如何实现多维数组降级,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。多维数组降级function array_flatten($arr) { ...
    99+
    2023-06-03
  • Numpy 数组索引的实现
    目录一、整数索引二、切片索引2.1、一维数组切片2.2、多维数组切片三、整数数组索引3.1、 一维数组的整数数组索引3.2、多维数组的整数数组索引四、布尔索引五、花式索引数组索引是指...
    99+
    2023-01-28
    Numpy 数组索引
  • C#中多维数组[,]和交错数组[][]的区别
    多维数组的声明 在声明时,必须指定数组的长度,格式为 type [lenght ,lenght ,lengh, ... ] int [,] test1 = new int [3,3]...
    99+
    2022-11-12
  • C语言多维数组数据结构的实现详解
    目录数据结构之多维数组各基本操作函数原型说明 各基本操作的具体实现测试分析思考与小结1、 对数组的再认识2、调试过程中遇到的问题及解决方案3、算法的时间复杂度分析总结数据结构之多维数...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作