糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 图片的谱表征

图片的谱表征

时间:2022-05-12 06:33:53

相关推荐

图片的谱表征

用谱方法来表征图像 Spectral Representations of Natural Images

1.导入库2.定义相关子函数3.主函数3.1 读入lenna图片、resize以及保存3.2 计算该图像的拉普拉斯矩阵及谱特征3.3 图像重建及保存 参考文献

本文是对Understanding Convolutions on Graphs以及对应的google colab:SpectralRepresentations.ipynb的学习总结。

通过学习此文,也可以深入理解下图神经网络中谱空间模型。

注意:该colab存在一两处bug,可参考本文fix过的代码。完整代码见/download/WANGWUSHAN/86781716。

1.导入库

import functoolsimport itertoolsimport osimport matplotlib.pyplot as pltimport numpy as npimport scipy.sparseimport scipy.sparse.linalg

2.定义相关子函数

主要包括了计算图的拉普拉斯矩阵 L = D − A L=D-A L=D−A以及图的重建子函数。

def get_index(x, y, img_width, img_height):return y * img_width + xdef get_neighbours(x, y, img_width, img_height):neighbours_x_pos = [max(0, x - 1), x, min(x + 1, img_width - 1)]neighbours_y_pos = [max(0, y - 1), y, min(y + 1, img_height - 1)]neighbours = itertools.product(neighbours_x_pos, neighbours_y_pos)neighbours = set(neighbours)neighbours.discard((x, y))return neighboursdef compute_sparse_laplacian(img_width, img_height):#计算图的拉普拉斯矩阵neighbours_fn = functools.partial(get_neighbours, img_width=img_width, img_height=img_height)index_fn = functools.partial(get_index, img_width=img_width, img_height=img_height)senders = []recievers = []values = []for x in range(img_width):for y in range(img_height):pos = (x, y)pos_index = index_fn(*pos)degree = 0.for neighbour in neighbours_fn(*pos):neigh_index = index_fn(*neighbour)senders.append(pos_index)recievers.append(neigh_index)values.append(-1.)degree += 1.senders.append(pos_index)recievers.append(pos_index)values.append(degree)return scipy.sparse.coo_matrix((values, (senders, recievers)))def keep_first_components(img_data, num_components):#图的重建子函数orig_shape = img_data.shapeimg_reshaped = np.reshape(img_data, (-1, 3))chosen_eigenvecs = eigenvecs[:, :num_components]spectral_coeffs = chosen_eigenvecs.T @ img_reshapedupd_img_data_reshaped = chosen_eigenvecs @ spectral_coeffsreturn np.reshape(upd_img_data_reshaped, orig_shape).astype(int)

3.主函数

3.1 读入lenna图片、resize以及保存

from PIL import Imageimg_name = 'E:/lenna.png'img_width = 32img_height = 32img_data = np.asarray(Image.open(img_name).resize((img_width, img_height)))save_dir = 'E:/spectral_representation'if not os.path.exists(save_dir):os.makedirs(save_dir)plt.axis('off')_ = plt.imshow(img_data)plt.show()Image.fromarray(img_data).save(os.path.join(save_dir, '1ena.png'))

原图resize之后,显示如下:

3.2 计算该图像的拉普拉斯矩阵及谱特征

计算拉普拉斯矩阵,以及该矩阵的特征值、特征向量。

num_eigenvecs = 800assert num_eigenvecs < img_width*img_heightv0 = np.ones(img_width * img_height)laplacian = compute_sparse_laplacian(img_width, img_height)eigenvals, eigenvecs = scipy.sparse.linalg.eigsh(laplacian, k=num_eigenvecs, which='SM', v0=v0)assert np.all(eigenvals >= 0)plt.hist(eigenvals, bins=100)plt.title('Histogram of Laplacian Eigenvalues')plt.show()

3.3 图像重建及保存

base_name = os.path.basename(img_name).split('.')[0]for num_components in [1, 10, 100, 200, 500, num_eigenvecs]:upd_img_data = keep_first_components(img_data, num_components).astype(np.uint8)upd_img_name = f'{base_name}-{num_components}.png'# plt.axis('off')# plt.imshow(upd_img_data)Image.fromarray(upd_img_data).save(os.path.join(save_dir, upd_img_name))

base_name = os.path.basename(img_name).split('.')[0]for num_components in [1, 10, 100, 200, 500, img_width*img_height]:upd_img_data = keep_first_components(img_data, num_components).astype(np.uint8)upd_img_name = f'{base_name}-{num_components}.png'plt.axis('off')plt.imshow(upd_img_data)Image.fromarray(upd_img_data).save(os.path.join(save_dir, upd_img_name))

下图从左到右使用的特征向量个数分别为1, 10, 100, 200, 500, 800。可以看出随着特征向量增多,重建效果越来越好。

参考文献

[1] Understanding Convolutions on Graphs

[2] google colab:SpectralRepresentations.ipynb

如果觉得《图片的谱表征》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。
相关阅读
何谓大谱表?

何谓大谱表?

2021-04-24

联合谱表怎么画

联合谱表怎么画

2024-05-27

5个月宝宝食谱表

5个月宝宝食谱表

2021-02-11

10个月宝宝食谱表

10个月宝宝食谱表

2020-03-30