不懂原理的同学请参考:
def svd(img, topk_percent=0.7): """ 使用svd对图片降维,可作为一种数据增强手段 每列作为一个向量,先构建方阵,再求特征值 特征向量,取前N个主成分,再重构图像 :param img: 输入图像 :param topk_percent: 图像恢复率, :return: img after svd """ img_src = img[...] if len(img.shape) == 3: img_src = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY) h, w = img_src.shape data = np.asarray(img_src, np.double) # 以下两种方式都可以 # method 1 U, s, V = np.linalg.svd(data) K = round(len(s) * topk_percent) K = min(h, w) if K > min(h, w) else K S = np.diag(s) major_data = np.dot(U[:, :K], np.dot(S[:K, :K], V[:K, :])) # # method 2 # feat_values, feat_vectors = np.linalg.eig(np.dot(data.T, data)) # feat_index = np.argsort(np.sqrt(feat_values), axis=0)[::-1] # S = np.diag(feat_values) # V = feat_vectors[:, feat_index] # S_inv = np.asmatrix(S).I # V_inv = np.asmatrix(V).I # U = np.dot(np.dot(data, V), S_inv) # K = round(S.shape[0] * topk_percent) # K = min(h, w) if K > min(h, w) else K # major_data = np.dot(np.dot(U[:, :K], S[:K, :K]), V_inv[:K, :]) rebuild_img = np.asarray(major_data, np.uint8) cv2.imshow('1', rebuild_img) cv2.waitKey(0) return rebuild_img def pca(img, topk_percent=0.7): """ 使用pca对图片降维,可作为一种数据增强手段 每列作为一个向量,先0均值化,再求协方差矩阵的特征值和特征向量,取前N个主成分,再重构图像 :param img: 输入图像 :param topk_percent: 图像恢复率, :return: img after pca """ img_src = img[...] if len(img.shape) == 3: img_src = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY) print(img_src.shape) h, w = img_src.shape data = np.asarray(img_src, np.double) # 计算每列的mean _mean = np.mean(data, axis=0) data -= _mean # 以 列为变量计算方式,计算协方差矩阵 data_cov = np.cov(data, rowvar=False) feat_values, feat_vectors = np.linalg.eig(data_cov) feat_index = np.argsort(np.sqrt(feat_values), axis=0)[::-1] V = feat_vectors[:, feat_index] K = round(len(feat_values) * topk_percent) K = min(h, w) if K > min(h, w) else K # 重建图像 major_data = np.dot(np.dot(data, V[:, :K]), V[:, :K].T) + _mean rebuild_img = np.asarray(major_data, np.uint8) cv2.imshow('1', rebuild_img) cv2.waitKey(0) return rebuild_img