CS231A:python和线代

点乘

在这里插入图片描述
就是常见的向量相乘,如果是点的坐标的话,结果就是一个标量,是一个值,用模和夹角的计算公式:
v w = ( x 1 , x 2 ) ( y 1 , y 2 ) = v w c o s α v \cdot w = (x_1,x_2) \cdot (y_1,y_2) = ||v|| \cdot ||w|| cos \alpha

叉乘

在这里插入图片描述
叉乘的结果是向量, 模的值是:
u = v × w = v w s i n α ||u|| = ||v \times w|| = ||v|| ||w|| sin \alpha
方向是:
垂直于 w , v w,v 平面的直线,也就是平面的法线!垂直的线之间的点乘的值为0(毕竟 c o s 90 cos90 ° = 0 =0 )

在这里插入图片描述
计算方法如下:
在这里插入图片描述
现在是在三维的角度来解决问题了,其中 i , j , k i,j,k 代表三个方向,是标准基,可以求出 u u 的表达式,这是标准基中的写法。

获取特征值和特征向量的Python实现:

eigvals, eigvecs = np.linalg.eig(M)

奇异值分解

概念

奇异值就是 A t A A^tA 的非负平方根,表示为 σ i , i = 1 , . . . , n \sigma_i,i=1,...,n
如果 A A 是形如 m × n m\times n 的矩阵,那么就会有两个正交矩阵 U R m × m U\in R^{m\times m} U R m × m U\in R^{m\times m} ,组成下列公式:
在这里插入图片描述

但是这个东西什么时候用呢,我也就在用很多三维点拟合平面的时候才用到过这个,还有之前处理“花”的图像的时候,采用过,好像根据选取的特征的数量来改变花的特征

每个矩阵说明

  1. A ( m n ) A(m*n) 是矩阵本身, U ( m m ) U(m*m) V ( n n ) V(n*n) 旋转矩阵, Σ ( m n ) Σ(m*n) 缩放矩阵
  2. U U V V 是“单位”矩阵,每一列都是单位向量, Σ Σ 的元素数量等于A的秩数,其中的元素由高到低排列
  3. U U 的列是数据的主要成分,能用来生成原始矩阵的列,它的用处之一是生成一个矩阵,矩阵的每一列都是一个独立的数据样本

组成关系

在这里插入图片描述
只用1/30的主要成分就能生成一个可识别的图案,PCA允许用主要元素的权重代替初始数据,这些更小的数据让计算运行更快

算法

  1. 找到A.dot(A.T)的特征向量,这些特征向量就是U的列,平方根特征向量就是 Σ
  2. 找到A.T.dot(A)的特征向量,这些特征向量是V的列(也就是V.T的行)

使用

如果想要A的前100个特征,那么 A 100 = U [ : , : ] S [ : , : 100 ] V [ : , : 100 ] A_{100} = U[:,:] * S[:,:100] * V[:,:100]
注意U是全部的行列,取多少个特征是通过改变S和V实现的

这是matlab代码

U,S,V_T = np.linalg.svd(M)

但是什么时候用这个也不清楚,在图像处理方面,现在好像都是用的卷积来提取特征了

效果

不同特征个数的效果对比:
在这里插入图片描述
10 10个
在这里插入图片描述
100 100个
在这里插入图片描述
200 200个

用自己的图再python尝试:
在这里插入图片描述
原图

在这里插入图片描述
k = 50 k = 50 的效果图
官方API
这个API已经讲的很详细了
但我好像哪里出了什么问题… 代码如下:

import numpy as np
import cv2

img = cv2.imread('C:\\Users\\saber\\Desktop\\CS231A\\python\\test_svd.jpeg')

img_1 = img[:,:,0]
img_2 = img[:,:,1]
img_3 = img[:,:,2]

U_1 , S_1, V_T_1 = np.linalg.svd(img_1)
U_2 , S_2, V_T_2 = np.linalg.svd(img_2)
U_3 , S_3, V_T_3 = np.linalg.svd(img_3)

S_reshape_1 = S_1.reshape((-1,1))
S_reshape_2 = S_2.reshape((-1,1))
S_reshape_3 = S_3.reshape((-1,1))

US_1 = U_1 * S_reshape_1
US_2 = U_2 * S_reshape_2
US_3 = U_3 * S_reshape_3

k = 50
mg_svd_1 = US_1[:,:k].dot(V_T_1[:k,:])
mg_svd_2 = US_2[:,:k].dot(V_T_2[:k,:])
mg_svd_3 = US_3[:,:k].dot(V_T_3[:k,:])

mg_svd = np.stack((mg_svd_1,mg_svd_2,mg_svd_3),axis=2)
cv2.imshow('aa',mg_svd)
cv2.waitKey()

np.linalg.svd 也可以直接设置k,我这里不知道三个通道如何同时处理,就用了笨方法。

下面的都是行不通的代码

# 这个用官方的计算s方法,怎么显示不出图片呢?

import numpy as np
import cv2

img = cv2.imread('C:\\Users\\saber\\Desktop\\CS231A\\python\\test_svd.jpeg')

img_1 = img[:,:,0]
img_2 = img[:,:,1]
img_3 = img[:,:,2]

U_1 , S_1, V_T_1 = np.linalg.svd(img_1)
U_2 , S_2, V_T_2 = np.linalg.svd(img_2)
U_3 , S_3, V_T_3 = np.linalg.svd(img_3)

S_reshape_1 = np.zeros((U_1.shape[0],V_T_1.shape[0]))
S_reshape_1[:len(S_1),:len(S_1)] = np.diag(S_1)

S_reshape_2 = np.zeros((U_1.shape[0],V_T_1.shape[0]))
S_reshape_2[:len(S_1),:len(S_1)] = np.diag(S_2)

S_reshape_3 = np.zeros((U_1.shape[0],V_T_1.shape[0]))
S_reshape_3[:len(S_1),:len(S_1)] = np.diag(S_3)

k = 50

mg_svd_1 = U_1[:,:].dot(S_reshape_1[:,:k]).dot(V_T_1[:k,:])
mg_svd_2 = U_2[:,:].dot(S_reshape_2[:,:k]).dot(V_T_2[:k,:])
mg_svd_3 = U_3[:,:].dot(S_reshape_3[:,:k]).dot(V_T_3[:k,:])

mg_svd = np.stack((mg_svd_1,mg_svd_2,mg_svd_3),axis=2)
cv2.imshow('aa',mg_svd)
cv2.waitKey()

直接三通道代码:

import numpy as np
import cv2
import scipy
#import scipy.sparse.linalg.svds

img = cv2.imread('C:\\Users\\saber\\Desktop\\CS231A\\python\\test_svd.jpeg')
img = np.rollaxis(img,2)
U , S, V_T = np.linalg.svd(img)

S_mat = np.zeros((3,U.shape[1],V_T.shape[1]))
S_mat[:,len(S),:len(S)] = np.diag(S)
A_100_1 = U[0,:,:].dot(S_mat[0,:,:100]).dot(V_T[0,:100,:])
A_100_2 = U[1,:,:].dot(S_mat[1,:,:100]).dot(V_T[1,:100,:])
A_100_3 = U[2,:,:].dot(S_mat[2,:,:100]).dot(V_T[2,:100,:])
A_100 = np.stack((A_100_1,A_100_2,A_100_3),axis=2)

cv2.imshow('a100',A_100)
cv2.waitKey()
print('a')
import numpy as np
import cv2

img = cv2.imread('C:\\Users\\saber\\Desktop\\CS231A\\python\\test_svd.jpeg')
image = np.rollaxis(img,axis=2)
# u 3 371 371
# s 3 371
# vh 3 406 406
u, s, vh = np.linalg.svd(image, full_matrices=True)

aaa = np.matmul(u * s[:, None, :], vh[:,:371,:371])
aaa = np.rollaxis(aaa,axis=2)
aaa = np.rollaxis(aaa,axis=2)
cv2.imshow('aaa',aaa)
cv2.waitKey()
发布了32 篇原创文章 · 获赞 1 · 访问量 2779

猜你喜欢

转载自blog.csdn.net/McEason/article/details/104081316