利用SVD进行图像压缩(附Python代码)

SVD图像压缩步骤

对于RGB图像来说,对应三色层,对每一个色层进行SVD分解,得到U,S,VU, S, V矩阵,设利用前K大奇异值进行图像压缩,即有:

result=i=13Ui[:,1:K]S[1:K,1:K]VT[1:K,:]result = \sum_{i = 1}^{3}U_i[:, 1:K] * S[1:K, 1:K] * V^T[1:K, :]

而对于灰度图像来说,只需要完成一层的运算即可。

原图及不同保留度下压缩结果

原图像:
在这里插入图片描述
不同保留度下的压缩结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Show me the code

导包

import numpy as np
import matplotlib.pyplot as plt

SVD图像压缩模块

def zip_image_by_svd(origin_image, rate = 0.8):
    # 显示原图像
    plt.figure(figsize= (12, 12))
    plt.title("Origin Image")
    plt.imshow(origin_image)
    plt.show()
    
    print("\n\n======开始压缩======")
    # 提前开辟结果存放空间
    result = np.zeros(origin_image.shape)

    # 对原图像进行SVD分解
    u_shape = 0
    s_shape = 0
    vT_shape = 0

    for chan in range(3):
        # 对该层进行SVD分解
        U, sigma, V = np.linalg.svd(origin_image[:, :, chan])
        n_sigmas = 0
        temp = 0

        # 计算达到保留率需要的奇异值数量
        while (temp / np.sum(sigma)) < rate:
            temp += sigma[n_sigmas]
            n_sigmas += 1

        # 构建奇异值矩阵
        S = np.zeros((n_sigmas, n_sigmas))

        for i in range(n_sigmas):
            S[i, i] = sigma[i]

        # 构建结果
        result[:, :, chan] = (U[:, 0:n_sigmas].dot(S)).dot(V[0:n_sigmas, :])
        u_shape = U[:, 0:n_sigmas].shape
        s_shape = S.shape
        vT_shape = V[0:n_sigmas, :].shape

    # 归一化到[0, 1]
    for i in range(3):
        MAX = np.max(result[:, :, i])
        MIN = np.min(result[:, :, i])
        result[:, :, i] = (result[:, :, i] - MIN) / (MAX - MIN)

    # 调整到[0, 255]
    result  = np.round(result * 255).astype('int')
    
    
    # 显示压缩结果
    plt.figure(figsize= (12, 12))
    plt.imshow(result)
    plt.title("Result Image")
    plt.show()

    # 计算压缩率
    zip_rate =(origin_image.size -3 * (u_shape[0] * u_shape[1] + s_shape[0] * s_shape[1] + vT_shape[0] * vT_shape[1])) / (origin_image.size)
    
    print("保留率:        ", rate)
    print("所用奇异值数量为:", n_sigmas)
    print("原图大小:       ", origin_image.shape)
    print("压缩后用到的矩阵大小:3 x ({} + {} + {})". format(u_shape, s_shape, vT_shape))
    print("压缩率为:       ", zip_rate)

主函数及其调用

# 定义主函数
def main():
    # 读入图像
    image_path = '/Users/tantaiyunfei/Desktop/图片/背景图/e32e0ab9393fb231aa3af9a71ac06a07.jpg'
    origin_image = plt.imread(image_path)
    
    # 利用自定义SVD图像压缩模块对图像进行压缩
    zip_image_by_svd(origin_image, rate = 0.8)
    
# 主函数调用
if __name__ == "__main__":
    main()
发布了84 篇原创文章 · 获赞 23 · 访问量 3万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览