百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

基于奇异值分解(SVD)的图片压缩实践

toyiye 2024-07-08 22:59 11 浏览 0 评论

1. 前言

数字图片在计算机中是以矩阵形式存储的。所以可以通过矩阵理论和矩阵算法对数字图像进行分析和处理。本文通过对图片进行SVD压缩,对不同的参数下的压缩效果进行对比。

SVD概念可以参考:《统计学习方法》–奇异值分解(Singular Value Decomposition,SVD)

2. 原理简介

彩色图片有3个图层,RGB(红、绿、蓝)也就是矩阵的一个位置上存储了3个基色的数值,由3个基色混合成不同的色彩。

通过对3个图层矩阵,分别进行SVD近似,SVD奇异值是唯一的,可以取前 k 个最大的奇异值进行近似表达,最后再将3个图层的矩阵数据合并,用较少的数据去表达图片。

2.1 SVD定义



3. 实践代码

# -*- coding:utf-8 -*-
# @Python Version: 3.7
# @Time: 2020/4/21 23:38
# @Author: Michael Ming
# @Website: https://michael.blog.csdn.net/
# @File: 15.svd_pic_compress.py
# @Reference: https://blog.csdn.net/weixin_44344462/article/details/89401727
import numpy as np
import matplotlib.pyplot as plt
def zip_img_by_svd(img, plotId, rate=0.8):
    zip_img = np.zeros(img.shape)
    u_shape = 0
    sigma_shape = 0
    vT_shape = 0
    for chanel in range(3):  # 3个图层
        u, sigma, v = np.linalg.svd(img[:, :, chanel])  # numpy svd函数
        sigma_i = 0
        temp = 0
        while (temp / np.sum(sigma)) < rate:  # 选取的奇异值和需要达到设定的权重
            temp += sigma[sigma_i]
            sigma_i += 1
        SigmaMat = np.zeros((sigma_i, sigma_i))  # 选取了sigma_i 最大的奇异值
        for i in range(sigma_i):
            SigmaMat[i, i] = sigma[i]  # 将奇异值填充到Sigma对角矩阵
        zip_img[:, :, chanel] = u[:, 0:sigma_i].dot(SigmaMat).dot(v[0:sigma_i, :])
        # 将分解得到的3个矩阵相乘,得到压缩后的近似矩阵
        u_shape = u[:, 0:sigma_i].shape
        sigma_shape = SigmaMat.shape
        vT_shape = v[0:sigma_i, :].shape
    for i in range(3):  # 对三个通道的矩阵数值进行归一化处理
        MAX = np.max(zip_img[:, :, i])
        MIN = np.min(zip_img[:, :, i])
        zip_img[:, :, i] = (zip_img[:, :, i] - MIN) / (MAX - MIN)
    zip_img = np.round(zip_img * 255).astype("uint8")
    # 不乘255图片是黑的(接近0,0,0),数据类型uint8
    plt.imsave("zip_svd_img.jpg", zip_img)  # 保存压缩后的图片
    zip_rate = (img.size - 3 * (
            u_shape[0] * u_shape[1] + sigma_shape[0] * sigma_shape[1] + vT_shape[0] * vT_shape[1])) / (zip_img.size)
    f = plt.subplot(3, 3, plotId)
    f.imshow(zip_img)
    f.set_title("SVD压缩率 %.4f,奇异值数量:%d" % (zip_rate, sigma_i))
    print("设置的压缩率:", rate)
    print("使用的奇异值数量:", sigma_i)
    print("原始图片大小:", img.shape)
    print("压缩后用到的矩阵大小:3x({}+{}+{})".format(u_shape, sigma_shape, vT_shape))
    print("压缩率为:", zip_rate)
if __name__ == '__main__':
    imgfile = "svd_img.jpg"
    plt.figure(figsize=(12, 12))
    plt.rcParams['font.sans-serif'] = 'SimHei'  # 消除中文乱码
    img = plt.imread(imgfile)
    f1 = plt.subplot(331)  # 绘制子图,3行3列,3*3个子图,现在画第1幅
    f1.imshow(img)
    f1.set_title("原始图片")
    for i in range(8):  # 再画8个子图
        rate = (i + 1) / 10.0  # 压缩率 10% - 80%
        zip_img_by_svd(img, i + 2, rate)
    plt.suptitle('图片SVD效果对比', fontsize=17, y=0.02)  # y偏移距离
    plt.show()
  • 可以看出在使用128个奇异值的SVD压缩情况下,就可以得到跟原图差不多效果的图片
  • 原图是703x800的尺寸,SVD使用的矩阵 ((703, 128)+(128, 128)+(128, 800))=208768
  • 可以少使用的矩阵数据比例为(703*800*3-208768*3)/(703*800*3)= 62.88%
  • 可以只用37.12%的数据量去近似表达原始图片,是不是很酷!!!
  • 在网络传输图片的过程中,终端用户可能点击,也可能不点击,那我都给他们发送SVD后的图片矩阵数据(减少了当次传输数据量),然后在终端进行矩阵运算得到压缩后的图片,当用户点击图片后,再进行传输原图片(1、用户点击是分散的,可以降低统一发送原图的网络拥挤现象;2、有的用户也不会点击,就避免了传输原图,达到了压缩的目的,节省流量)

总结难免有不足,大家可以评论区提出来一起讨论。另外小编精心准备了2020最新python学习资料,大家可以关注公众号:芝麻代理。回复:资料分享。免费领取。




相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码