Search code examples
pythonpython-3.ximagenumpysvd

SVD image reconstruction in Python


I am trying to do a Singular Value Decomposition of this image:

enter image description here

taking the first 10 values. I have this code:

from PIL import Image
import numpy as np

img = Image.open('bee.jpg')
img = np.mean(img, 2)
U,s,V = np.linalg.svd(img)
recon_img = U @ s[1:10] @ V

but when I run it it throws me this error:

ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 9 is different from 819)

So I think I do something wrong when I do the reconstruction. I am not sure of the dimensions of the matrix np.linalg.svd(img) creates. How can I solve?

Sorry for the english


Solution

  • The issue is the dimension of s, if you print the U, s and V dimensions, I get:

    print(np.shape(U))
    print(np.shape(s))
    print(np.shape(V))
    
    (819, 819)
    (819,)
    (1024, 1024)
    

    So U and V are square matrix, s is an array. You have to create a matrix with the same dimensions of you image (819 x 1024) with s on the main diagonal with this:

    n = 10
    S = np.zeros(np.shape(img))
    for i in range(0, n):
        S[i,i] = s[i]
    print(np.shape(S))
    

    output:

    (819, 1024)
    

    Then you can proceed with your elaboration. For a comparison, check this code:

    from PIL import Image
    import numpy as np
    import matplotlib.pyplot as plt
    
    img = Image.open('bee.jpg')
    img = np.mean(img, 2)
    
    U,s,V = np.linalg.svd(img)
    
    n = 10
    S = np.zeros(np.shape(img))
    for i in range(0, n):
        S[i,i] = s[i]
    
    recon_img = U @ S @ V
    
    fig, ax = plt.subplots(1, 2)
    
    ax[0].imshow(img)
    ax[0].axis('off')
    ax[0].set_title('Original')
    
    ax[1].imshow(recon_img)
    ax[1].axis('off')
    ax[1].set_title(f'Reconstructed n = {n}')
    
    plt.show()
    

    which give me this:

    enter image description here