Документация Engee

Сжатие изображений с использованием SVD

В этой демонстрации показано, как работать с цветовыми каналами для изучения сжатия изображений с использованием сингулярного разложения (SVD).

using Images, TestImages
using LinearAlgebra

img = float.(testimage("mandrill"))
channels = channelview(img)

function rank_approx(F::SVD, k)
    U, S, V = F
    M = U[:, 1:k] * Diagonal(S[1:k]) * V[:, 1:k]'
    clamp01!(M)
end

Для каждого канала выполняется разложение SVD, а затем канал реконструируется с использованием только K наибольших сингулярных значений.

Изображение сжимается по той причине, что для каждого канала требуется сохранить лишь две небольшие матрицы и один вектор — усеченную часть (U, S, V). Например, если исходное изображение в оттенках серого размером (512, 512) воссоздается с использованием сингулярных значений, то для его воссоздания необходимо сохранить лишь чисел, в то время как исходное изображение содержит чисел. Следовательно, получается коэффициент сжатия , если не принимать во внимание тип для хранения.

# до версии julia 1.1:
# svdfactors = (svd(channels[1,:,:]), svd(channels[2,:,:]), svd(channels[3,:,:]))
svdfactors = svd.(eachslice(channels; dims=1))
imgs = map((10, 50, 100)) do k
    colorview(RGB, rank_approx.(svdfactors, k)...)
end

mosaicview(img, imgs...; nrow=1, npad=10)
stlwxyw

Слева направо: исходное изображение, реконструированные изображения с использованием 10, 50 и 100 наибольших сингулярных значений. Мы видим, что наибольших сингулярных значений позволяют достаточно хорошо воссоздать изображение.


Эта страница была создана с помощью DemoCards.jl и Literate.jl.