Python利用PCA压缩图片
参考
1、python代码实现PCA
这里先将1280的1D向量转变成2D图片之后,再进行PCA降维处理(但是这么做不是很科学,因为转2D后,同一列的数据实际含义是不同的)
from sklearn.decomposition import PCA
'''PCA对图像进行压缩'''
#参考 https://blog.csdn.net/u010687164/article/details/109253038
def PCA_decomposition(vector_1D, PCA_RATIO=0.7):
'''
:param vector_1D: 1D向量(要求输出的1D向量长度都是2的整数倍) type = list
:return:
'''
#1D向量转2D
vector_1D = np.array(vector_1D)
vector_2D = dimension_convert(vector_1D)
height,width = vector_2D.shape
#PCA降维
n_components = round(width * PCA_RATIO) #保存前70%的变量
pca = PCA(n_components=n_components) #降维至多少个变量, 注意降维时样本数不变(height数目不变)
res_array = pca.fit_transform(vector_2D)
#2D转1D
vector_1D = res_array.flatten()
return vector_1D
#简单实现1D转2D
def dimension_convert(vector_1D):
'''
:param vector_1D: 要求输出的1D向量长度都是2的整数倍,type = np.array
:return: 返回2D向量,尽量保证2D向量的width,height基本一致
'''
length = len(vector_1D)
temp = length
factor = 1
for i in range(length):
if(temp % 2 == 0):
factor = factor * 2 #height
temp = temp / 2 #width
if(factor * 2 > temp): #尽量保证2D向量的width,height基本一致,且height < width
break
else:
break
height,width = int(factor),int(temp)
vector_2D = np.resize(vector_1D,(height,width))
return vector_2D
class MyTest(unittest.TestCase):
def test_PCA_decomposition(self):
image = cv2.imread("../data/id_dataset/Ben.jpg")
model_path = "mobileNetV3.pth"
model = get_mobileNet(model_path)
output = face_feature_extract_withMobileNet(image, model) #得到长度为1280的1D向量
pca_output = PCA_decomposition(output,PCA_RATIO=0.7) #PCA降维
print(pca_output)
2、常见错误:
import numpy as np
from model.feature_similar import *
from sklearn.decomposition import PCA
import time
#a = np.array([[1,2,3],[4,5,6],[7,8,9]])
#b = np.array([[10,11,12],[13,14,15],[16,17,18]])
c = np.array([[1,2,3,4,5,6]]) #1D向量,每个像素为一个样本,无需进行降维
res = cosine(a,b)
print(res)
pca = PCA(n_components=2)
newArray = pca.fit_transform(c) #ValueError: n_components=2 must be between 0 and min(n_samples, n_features)=1 with svd_solver='full'
img = np.around(newArray)
print(img)
---
ValueError: n_components=2 must be between 0 and min(n_samples, n_features)=1 with svd_solver='full'
解决方法:
将1D向量转变为2D向量即可使用PCA,但是在进行PCA时,只是修改了样本的维数,而不改变样本数量