svd.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. # https://www.frankcleary.com/svdimage/
  2. # https://bigdataschool.ru/blog/recommender-systems-advanced-algorithms.html#:~:text=%D0%A1%D0%B8%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D0%BE%D0%B5%20%D1%80%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%20(SVD%2D%D1%80%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5)%20%E2%80%93,%D0%BC%D0%BE%D0%B3%D0%BB%D0%B8%20%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C%20%D0%BF%D1%80%D0%BE%D0%B3%D0%BD%D0%BE%D0%B7%20%D0%BE%D1%86%D0%B5%D0%BD%D0%BA%D0%B8%20%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F
  3. '''
  4. https://www.geeksforgeeks.org/image-reconstruction-using-singular-value-decomposition-svd-in-python/
  5. Хотя 1-й собственный вектор содержит 99,77% информации, реконструкция изображения только по нему не дает четкой картины.
  6. Использование 15 лучших векторов для реконструкции изображения дает достаточно хорошее приближение. Также из 3648 векторов,
  7. что значительно сокращает вычисления и сжимает изображение.
  8. '''
  9. import matplotlib.pyplot as plt
  10. import numpy as np
  11. import time
  12. from PIL import Image
  13. img = Image.open('img/amelieOrigin.png')
  14. #.convert('L')
  15. # plt.figure(figsize=(8, 8))
  16. # plt.imshow(img)
  17. # plt.show()
  18. imgmat = np.array(list(img.getdata(band=0)), float)
  19. imgmat.shape = (img.size[1], img.size[0])
  20. imgmat = np.matrix(imgmat)
  21. # plt.figure(figsize=(8, 8))
  22. # plt.imshow(img)
  23. # plt.show()
  24. U, sigma, V = np.linalg.svd(imgmat)
  25. print('input wm')
  26. wm = 11100
  27. print('WM = ', str(wm)*11)
  28. # WM = 11101110111011101110111011101110111011101110
  29. # WM = 1110011100111001110011100111001110011100111001110011100
  30. for i in range(11):
  31. print(sigma[i]) # U и V все меньше 1
  32. sigma[i] = int(sigma[i]) + wm # если 11100, то уже видны изменения
  33. print(sigma[i])
  34. for i in range(1, 602, 40):
  35. reconstimg = np.matrix(U[:, :i]) * np.diag(sigma[:i]) * np.matrix(V[:i, :])
  36. plt.imshow(reconstimg, cmap='gray')
  37. title = "n = %s" % i
  38. plt.title(title)
  39. plt.savefig(f'img/step-for-vectors-with-WM/{i}-vectors_of_the_singular_value_decomposition-{wm}.png')
  40. #plt.show()
  41. print('\ncheck')
  42. for i in range(11):
  43. print(sigma[i]) # U и V все меньше 1
  44. """
  45. восстановленное изображение по первым n
  46. векторов разложения по сингулярным значениям (n
  47. указано в заголовке графика). Первые 50 векторов дают изображение, очень близкое к исходному, занимая при этом всего 50∗3900+50+50∗26003900∗2600≈3,2% от объема исходных данных.
  48. по сравнению с исходными данными.
  49. """
  50. # for i in range(5, 51, 5):
  51. # reconstimg = np.matrix(U[:, :i]) * np.diag(sigma[:i]) * np.matrix(V[:i, :])
  52. # plt.imshow(reconstimg, cmap='gray')
  53. # title = "n = %s" % i
  54. # plt.title(title)
  55. # plt.savefig(f'img/{i}-vectors_of_the_singular_value_decomposition.png')
  56. # #plt.show()
  57. # for i in range(100, 151, 2):
  58. # reconstimg = np.matrix(U[:, :i]) * np.diag(sigma[:i]) * np.matrix(V[:i, :])
  59. # plt.imshow(reconstimg, cmap='gray')
  60. # title = "n = %s" % i
  61. # plt.title(title)
  62. # plt.savefig(f'img/step-for-vectors/{i}-vectors_of_the_singular_value_decomposition.png')
  63. # #plt.show()