Сообщество Engee

SVD - разложение для сжатия изображений

Автор
avatar-igarajaigaraja
Notebook

Singular value decomposition (SVD) как способ сжатия изображения

Матрица - как линейный оператор

Создадим набор точек в виде круга

In [ ]:
using LinearAlgebra
using Plots

circ_range = -1:0.025:1

# создаждим вектор векторов, содержащих координаты точек, входящих в круг 
circle = [[i,j] for i = circ_range for j = circ_range if i^2 + j^2 <= 1]

# выбираем точки с координатами [x, 0] и [0,y] для отображения базиса
x_zero_indxs = findall(x-> x[1] == 0 && x[2] >= 0,circle)
y_zero_indxs = findall(x-> x[2]== 0 && x[1] >= 0,circle)

# превращаем вектор векторов в матрицу 
circle = stack(circle)
2×5025 Matrix{Float64}:
 -1.0  -0.975  -0.975  -0.975  -0.975  …  0.975  0.975  0.975  0.975  1.0
  0.0  -0.2    -0.175  -0.15   -0.125     0.125  0.15   0.175  0.2    0.0
In [ ]:
function plot_circle(circle;xlm=[],ylm=[])
    scatter(circle[1,:],circle[2,:],aspect_ratio=:equal)
    scatter!(circle[1,x_zero_indxs],circle[2,x_zero_indxs],aspect_ratio=:equal)
    if (isempty(xlm) || isempty(ylm))
    scatter!(circle[1,y_zero_indxs],circle[2,y_zero_indxs], color=:yellow,aspect_ratio=:equal)
    else
    scatter!(circle[1,y_zero_indxs],circle[2,y_zero_indxs],
    color=:yellow, xlims=xlm, ylims=ylm, aspect_ratio=:equal)
    end
end
plot_circle (generic function with 2 methods)
In [ ]:
plot_circle(circle)

Обратим внимание на наши базисы. Сейчас базис x = a y -

Теперь умножим наш набор точек на матрицу . \text{И} \text{теперь} \text{можем} \text{заметить}, \text{что} \text{координаты} \text{нового} \text{базиса} x \text{в} \text{предыдущих} = . И вся окружность вытянулось по горизонтали

In [ ]:
M = [2 0;
     0 1]
circle_x_2 = M * circle
plot_circle(circle_x_2)
In [ ]:
# То же для y
M = [1 0;
     0 2]
circle_y_2 = M * circle
plot_circle(circle_y_2)
In [ ]:
# Обратите внимание на координаты базисов и матрицу M
M = [2 1;
     1 2]
circle_xy_2 = M * circle
plot_circle(circle_xy_2)
In [ ]:
# Создадим анимации
function step!(M)
    return (M * circle)
end

@gif for i=0:0.05:2
    plot_circle(step!([ i 0;
                        0 i]),
                xlm=[-2, 2],ylm=[-2, 2])
end
┌ Info: Saved animation to /tmp/jl_xkBIzyrer4.gif
└ @ Plots /home/ilya/.julia/packages/Plots/kLeqV/src/animation.jl:156