点乘
就是常见的向量相乘,如果是点的坐标的话,结果就是一个标量,是一个值,用模和夹角的计算公式:
叉乘
叉乘的结果是向量, 模的值是:
方向是:
垂直于
平面的直线,也就是平面的法线!垂直的线之间的点乘的值为0(毕竟
°
)
计算方法如下:
现在是在三维的角度来解决问题了,其中
代表三个方向,是标准基,可以求出
的表达式,这是标准基中的写法。
获取特征值和特征向量的Python实现:
eigvals, eigvecs = np.linalg.eig(M)
奇异值分解
概念
奇异值就是
的非负平方根,表示为
如果
是形如
的矩阵,那么就会有两个正交矩阵
和
,组成下列公式:
但是这个东西什么时候用呢,我也就在用很多三维点拟合平面的时候才用到过这个,还有之前处理“花”的图像的时候,采用过,好像根据选取的特征的数量来改变花的特征
每个矩阵说明
- 是矩阵本身, 和 是旋转矩阵, 是缩放矩阵
- 和 是“单位”矩阵,每一列都是单位向量, 的元素数量等于A的秩数,其中的元素由高到低排列
- 的列是数据的主要成分,能用来生成原始矩阵的列,它的用处之一是生成一个矩阵,矩阵的每一列都是一个独立的数据样本
组成关系
只用1/30的主要成分就能生成一个可识别的图案,PCA允许用主要元素的权重代替初始数据,这些更小的数据让计算运行更快
算法
- 找到A.dot(A.T)的特征向量,这些特征向量就是U的列,平方根特征向量就是 Σ
- 找到A.T.dot(A)的特征向量,这些特征向量是V的列(也就是V.T的行)
使用
如果想要A的前100个特征,那么
注意U是全部的行列,取多少个特征是通过改变S和V实现的
这是matlab代码
U,S,V_T = np.linalg.svd(M)
但是什么时候用这个也不清楚,在图像处理方面,现在好像都是用的卷积来提取特征了
效果
不同特征个数的效果对比:
用自己的图再python尝试:
官方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()