精华内容
下载资源
问答
  • 多媒体娱乐、信息高速公路等不断对信息数据的存储和传输提出了更高的要求,也给现有的有限带宽以严峻的考验,特别是具有庞大数据量的数字图像通信,更难以传输和存储,极大地制约了图像通信的发展,因此图像压缩技术...
  • 本文实例讲述了Python基于opencv的图像压缩算法。分享给大家供大家参考,具体如下: 插值方法: CV_INTER_NN – 最近邻插值, CV_INTER_LINEAR – 双线性插值 (缺省使用) CV_INTER_AREA – 使用象素关系重采样。当图像...
  • 用C/C++语言实现了JPEG图像压缩算法
  • 图像压缩算法

    千次阅读 2021-06-03 21:26:58
    图像压缩算法是对图像在资源空间上的压缩,每一个色块的颜色可以粗略的由红、绿、蓝的各自三个不同的深度合成得来。 那么,如果我们每一个颜色的程度用8位的二进制码来表示,最终需要24m2大小的空间(这里的m2不是...

    图像压缩

    图像压缩算法是对图像在资源空间上的压缩,每一个色块的颜色可以粗略的由红、绿、蓝的各自三个不同的深度合成得来。
    那么,如果我们每一个颜色的程度用8位的二进制码来表示,最终需要24m2大小的空间(这里的m2不是表示平方米,是一种空间大小的计量单位);而如果我们用5位来表示,需要15m2大小的空间。
    在这里插入图片描述
    选用的位数多,图像色彩更加丰富图像会更清晰,可空间上占用太多资源;而位数少,可以节省空间,可图片就会不够清晰。
    我们目前的磁盘空间一般都比较大了,空间不再是特别昂贵的资源。可我们需要考虑一些其他的情况,比如我们的一些特殊的原件,内存空间十分有限,那么我们就需要在空间上有所拮据;亦或者我们网页应用,如果图片较大,那么在加载时需要的时间就会增长,体验感上难免不舒服;再者我们的用户量多的服务器,空间总是有限的,如果数量级达到一定程度也是十分恐怖的。
    那么总而言之,算法对于程序来说,是十分重要的。也是一个程序品质的真正内核所在!

    那么我们接下来就以8位为例,来体会一下这个图像压缩算法。图像压缩的本质实质上来自于动态规划,大家可以在我们之后的过程中慢慢体会。

    为了减少空间的消耗,我们尝试一种变长的模式来存储,不同像素采用不同的位数。
    在这里插入图片描述

    1.图像线性化

    那么,我们首先要做的是将数据线性化,就是将矩阵式的数字变成线性。
    在这里插入图片描述
    变完之后的效果就是这样:
    在这里插入图片描述

    2.分段

    接下来,我们对上面整理好的线性数据进行分段。
    分段规则如下:
    1.每一段中的像素位数设置相同。
    2.每段是相邻的几个元素的集合。
    3.每段最多含256个元素,若超过就需要增加段来表示。(由于最高位数设置为8
    在这里插入图片描述

    3.分配空间

    我们将数据分好段了,就可以按照之前的这个表查找,这一个段的所有元素,最大需要的存储位数了。那么我们说,只要给这段的每个元素以最大需要的位数空间,那么我们每个元素就都能存的下了。
    在这里插入图片描述
    我们再举一个例子:
    将这一个集合如图分成三段,然后按照表格记录每一段所需要的存储位数。那么除此之外,我们还需要记录每一段包含了几个元素。
    而这两个变量,我们也需要一定的空间存储,每增加一段,就需要一份这样的开销:
    段数3+段数8,化简得:段数*11。

    3表示:我们每个段所需要的存储位数,最大为8位,那么8这个十进制数,我们需要3位的二进制来表示。
    8表示:我们每段包含的元素个数,最大不能超过256(超过就需要两个段了),那么这个十进制的256,需要8位的二进制进行表示。

    所以,我们每多分一个段,就会多一个11的开销,这个十一是固定不能变的,而某种意义上,这部分空间就属于被浪费了,因为他没有起到存储图像内容的作用。因此,我们明白了,合理的分段可以节省空间,可盲目对图像分段细化,只会造成过多的11无用开销。

    所以,图像压缩算法就是找到一个平衡点,找出最优的分段方案!

    在这里插入图片描述

    展开全文
  • C++ 图像压缩算法

    热门讨论 2014-03-17 22:14:28
    基于C++的图像压缩算法,可以压缩多种类型的图片,可调压缩率
  • Luban(鲁班)微信朋友圈的图片压缩算法 mage compression with efficiency very close to WeChat Moments
  • 图像压缩算法-源码

    2021-06-28 18:33:10
    图像压缩算法:seal:一种新的无损图像压缩算法。在最新版本中,该算法的表现相当不错,但仅以 25% 的幅度超过 PNG。这里是原始图像的文件大小 (optipng) 和压缩图像的大小(使用算法)。较大卷的大小可能不同。文件名...
  • 基于DCT图像压缩的方法,并在MATLAB环境下进行仿真实验
  • 本人收集的基于matlab的各种压缩算法程序,包括lzw,huffman,dpcm,diffcoding,jpeg等 (Based on a variety of compression algorithms matlab program I collected, including lzw, huffman, dpcm, diffcoding, ...
  • android经典图片压缩算法 永不失真

    千次下载 热门讨论 2013-12-19 10:21:56
    对各种大图片进行压缩,压缩不失真。大图片压缩后大小在100k以内,可以根据自己的需求进行设置压缩大小。
  • 基于Matlab实现的经典的图像压缩算法,包括哈夫曼编码,算术编码、字典编码、行程编码-Lempel-zev 编码正交变换编码如DCT、子带编码 粒子、子采样、比特分配、矢量量化
  • 近期老师要求将jpeg2000算法移植到安卓平台上,尝试了很长时间,在这里总结一下经验、 OpenJPEG是Universite catholique de Louvain, Belgium大学的通信和遥感试验室于2003年12月开发出来的。OpenJPEG作为完全用C...
  • jbig2二值图像压缩算法实现,C++实现,jbig2是二值图像压缩效果效率平衡最佳的国际标准
  • Python version of Luban(鲁班)—Image compression with efficiency very close to WeChat Moments/可能是最接近微信朋友圈的图片压缩算法
  • 图像压缩算法简介

    万次阅读 2019-01-28 18:41:20
    理论基础 香农的信息论,在不产生任何失真的前提下,通过合理的编码,对于每个信源符号分配不等长的码字,平均码长可以任意接近于信源的熵。在这个理论框架下产生了几...2 图像数据的冗余数据:同一帧临近位置的数...

    理论基础
    香农的信息论,在不产生任何失真的前提下,通过合理的编码,对于每个信源符号分配不等长的码字,平均码长可以任意接近于信源的熵。在这个理论框架下产生了几种不同的无失真的信源编码方法:哈夫曼编码,算术编码、字典编码等。后来出现了更多的编码方式:如KLT编码、分形编码、模型编码、子带编码和基于小波的编码方法。

    压缩的必要性和可能性
    1存储和传输上的消耗。
    2 图像数据的冗余数据:同一帧临近位置的数据相同或相似;连续帧图像数据有大量相同的数据;人眼对图像分辨率的局限性、监视器显示分辨率的限制,容许一定限度的失真。

    方法简介
    基于信息论角度
    冗余度压缩方法:(无损压缩),在数学上可逆:哈夫曼编码-算术编码-行程编码-Lempel-zev 编码
    信息量压缩方法:(有损压缩),解码图像与原始图像有差:预测编码-频率域方法(正交变换编码如DCT、子带编码)-空间域方法(统计分块编码)-模型方法(分形编码、模型编码)-基于重要性(粒子、子采样、比特分配、矢量量化)

    按照压缩技术所依据和使用的数学方法进行分类
    预测编码:基本思想是根据数据统计特性得到预测值,然后传输图像像素与其预测值的差值信号,使传输的码率降低,达到压缩的目的。
    统计编码:主要针对无记忆信源,根据信息码字出现概率的分布特征而进行压缩编码,寻找概率与码字长度间的最优匹配,其编码的实质就是用短码来表示较大的码字,而用长码表示出现概率较小的码字。常用的有:行程编码、哈夫曼编码和算术编码三种。
    变换编码:基本思想是利用图像块内像素之间的相关性,把图像变换到一组新的基(一般是频率域)上,使得能量集中到少数几个变换系数上,通过存储这些系数达到压缩数据的目的。常用的有:DCT-整数DCT-小波变换。

    图像压缩编码的评价标准
    1一个是对图像质量的评价:客观和主观。主观就是用人去观察评分;客观就是对压缩还原后的图像与原始图像误差进行定量计算。一般都是进行某种平均,得到均方误差;另一种是信噪比。
    2 一个是对图像压缩效果的评价:压缩比=原始图像每像素的比特数同压缩后图像每像素的比特数的比值。

    统计编码之哈夫曼编码
    1 基本原理:将使用次数多的代码转换为长度较短的代码,而是用次数少的可以使用较长的编码,并保持编码的唯一可解性。

    2 基本原则:保证权值和最小(字符统计数字x字符编码长度之和)

    3 基本步骤:(1) 从左到右将信源符号频率从小到大的顺序排列 (2)将将两个最小概率进行组合相加,并继续这个步骤,始终将较高的概率分支放到上部,直到概率达到1为止 (3)对每对组合中上边的一个都指定为1,下边的一个指定为0,或者相反。(4)画出由每个信源符号到达概率为1.0处的路径,记下沿路径遇到的各个1和0。(5)对每个信源符号都写出1和0序列,则最后便得到了哈夫曼编码。

    统计编码之算术编码
    基本原理

    算术编码的基本原理是将编码的消息表示成实数0和1之间的一个间隔,消息越长,编码表示它的间隔就越小,表示这一间隔所需的二进制位就越多。 算术编码用到两个基本的参数:符号的概率和它的编码间隔。

    算术编码是一种无失真的编码方法,能有效地压缩信源冗余度,属于熵编码的一种。算术编码的一个重要特点就是可以按分数比特逼近信源熵,突破了Haffman编码每个符号只不过能按整数个比特逼近信源熵的限制。对信源进行算术编码,往往需要两个过程,第一个过程是建立信源概率表,第二个过程是对信源发出的符号序列进行扫描编码。而自适应算术编码在对符号序列进行扫描的过程中,可一次完成上述两个过程,即根据恰当的概率估计模型和当前符号序列中各符号出现的频率,自适应地调整各符号的概率估计值,同时完成编码。尽管从编码效率上看不如已知概率表的情况,但正是由于自适应算术编码具有实时性好、灵活性高、适应性强等特点,在图像压缩、视频图像编码等领域都得到了广泛的应用。
    那为什么还要采用自适应模型呢?因为静态模型无法适应信息的多样性,例如,以上得出的概率分布没法在所有待压缩信息上使用,为了能正确解压缩,必须再消耗一定的空间保存静态模型统计出的概率分布,保存模型所用的空间将使我们重新远离熵值。其次,静态模型需要在压缩前对信息内字符的分布进行统计,这一统计过程将消耗大量的时间,使得本来就比较慢的算术编码压缩更加缓慢。另外还有最重要的一点,对较长的信息,静态模型统计出的符号概率是该符号在整个信息中的出现概率,而自适应模型可以统计出某个符号在某一局部的出现概率或某个符号相对于某一上下文的出现概率,换句话说,自适应模型得到的概率分布将有利于对信息压缩(可以说结合上下文的自适应模型的信息熵建立在更高的概率层次上,其总熵值更小),好的基于上下文的自适应模型得到的压缩结果将远远超过静态模型。
      通常用“阶”(order)这一术语区分不同的自适应模型。刚刚上面的例子采用的是0阶自适应模型,也就是说,该例子中统计的是符号在已输入信息中的出现概率,没有考虑任何上下文信息。如果我们将模型变成统计符号在某个特定符号后的出现概率,那么,模型就成为了 1 阶上下文自适应模型。举例来说,要对一篇英文文本进行编码,已经编码了 10000 个英文字符,刚刚编码的字符是 t,下一个要编码的字符是 h。如果在前面的编码过程中已经统计出前 10000 个字符中出现了 113 次字母 t,其中有 47 个 t 后面跟着字母 h。得出字符 h 在字符 t 后的出现频率是 47/113,我们使用这一频率对字符 h 进行编码,需要 -=1.266位。
    对比 0 阶自适应模型,如果前 10000 个字符中 h 的出现次数为 82 次,则字符 h 的概率是 82/10000,我们用此概率对 h 进行编码,需要 - = 6.930 位。考虑上下文因素的优势显而易见。我们还可以进一步扩大这一优势,例如要编码字符 h 的前两个字符是 gt,而在已经编码的文本中 gt 后面出现 h 的概率是 80%,那么只需要 0.322 位就可以编码输出字符h。此时,这种模型叫做 2 阶上下文自适应模型。
      最理想的情况是采用 3 阶自适应模型。此时,如果结合算术编码,对信息的压缩效果将达到惊人的程度。采用更高阶的模型需要消耗的系统空间和时间至少在目前还无法让人接受,使用算术压缩的应用程序大多数采用 2 阶或 3 阶的自适应模型。
    使用自适应模型的算术编码算法必须考虑如何为从未出现过的上下文编码。例如,在 1 阶上下文模型中,需要统计出现概率的上下文可能有 256 * 256 = 65536 种,因为 0 - 255 的所有字符都有可能出现在 0 - 255 个字符中任何一个之后。当我们面对一个从未出现过的上下文时(比如刚编码过字符 b,要编码字符 d,而在此之前,d 从未出现在 b 的后面),该怎样确定字符的概率呢?
      比较简单的办法是在压缩开始之前,为所有可能的上下文分配计数为 1 的出现次数,如果在压缩中碰到从未出现的 bd 组合,我们认为 d 出现在 b 之后的次数为 1,并可由此得到概率进行正确的编码。使用这种方法的问题是,在压缩开始之前,在某上下文中的字符已经具有了一个比较小的频率。例如对 1 阶上下文模型,压缩前,任意字符的频率都被人为地设定为 1/65536,按照这个频率,压缩开始时每个字符要用 16 位编码,只有随着压缩的进行,出现较频繁的字符在频率分布图上占据了较大的空间后,压缩效果才会逐渐好起来。对于 2 阶或 3 阶上下文模型,情况就更糟糕,我们要为几乎从不出现的大多数上下文浪费大量的空间。
      我们通过引入“转义码”来解决这一问题。“转义码”是混在压缩数据流中的特殊的记号,用于通知解压缩程序下一个上下文在此之前从未出现过,需要使用低阶的上下文进行编码。举例来讲,在 3 阶上下文模型中,我们刚编码过 ght,下一个要编码的字符是 a,而在此之前,ght 后面从未出现过字符 a,这时,压缩程序输出转义码,然后检查 2 阶的上下文表,看在此之前 ht 后面出现 a 的次数;如果 ht 后面曾经出现过 a,那么就使用 2 阶上下文表中的概率为 a 编码,否则再输出转义码,检查 1 阶上下文表;如果仍未能查到,则输出转义码,转入最低的 0 阶上下文表,看以前是否出现过字符 a;如果以前根本没有出现过 a,那么我们转到一个特殊的“转义”上下文表,该表内包含 0 - 255 所有符号,每个符号的计数都为 1,并且永远不会被更新,任何在高阶上下文中没有出现的符号都可以退到这里按照 1/256 的频率进行编码。“转义码”的引入使我们摆脱了从未出现过的上下文的困扰,可以使模型根据输入数据的变化快速调整到最佳位置,并迅速减少对高概率符号编码所需要的位数。

    可以参考
    http://blog.csdn.net/china_video_expert/article/details/5927719

    统计编码之行程编码
    (将一行中颜色值相同的相邻象素用一个计数值和该颜色值来代替。例如aaabccccccddeee可以表示为3a1b6c2d3e。如果一幅图象是由很多块颜色相同的大面积区域组成,那么采用行程编码的压缩效率是惊人的。然而,该算法也导致了一个致命弱点,如果图象中每两个相邻点的颜色都不同,用这种算法不但不能压缩,反而数据量增加一倍。)

    行程编码的可行性讨论:
    行程编码的压缩方法对于自然图片来说是不太可行的,因为自然图片像素点错综复杂,同色像素连续性差,如果硬要用行程编码方法来编码就适得其反,图像体积不但没减少,反而加倍。鉴于计算机桌面图,图像的色块大,同色像素点连续较多,所以行程编码对于计算机桌面图像来说是一种较好的编码方法。行程编码算法特点:有算法简单、无损压缩、运行速度快、消耗资源少等优点。

    大致方法是:遍历所有像素点,一行一行的。从第一个开始,如果下一个相同,则num++,直到下一个不同值开始,等等。

    可以参看http://blog.csdn.net/zuzubo/article/details/1598009

    预测编码之差分脉冲编码调制编码(DPCM)
    可以参看 http://bbs.csdn.net/topics/210083337

    DPCM是differential pulse code modulation的缩写,也就是差分脉冲编码调制的意思。他的主要思想是通过已知的数据预测下一个数据,然后传递预测值与实际值之间的差值。
    在这里插入图片描述(如果直接使用DPCM进行编码的话,是得不到什么压缩的效率的。缘故是,需要传输或保存的是预测值后的值与实际值之间的差值,这与原来的数据占用同样的空间。)

    为了满足我们原始的压缩数据的动机,你可以对这些差值进行各种各样的编码。因为,大部分情况下,差值都是像1,1,1,2,3,5,5,5之类的数。可以对它们进行通常的游程编码或者huffman编码,运气好的话能够得到很大的压缩比。

    (这样做会有一个很大的弊端。因为有些数据可能之间的联系会呈线性或者某种连续函数的性质。但是大部分情况下,数据的分布还是有一定的离散性的。当数据之间出现很大的跳跃的时候,这种方法就显得很苍白无力了。)

    我们可以这么做,每次对得到的差值用一个随着差值大小变化的数来除。这样就可以随着差值的变化,不断调整比例因子。这样出现较大的跳跃时也能把我们要存储的差值限定在一个较小的范围之内。
    如果你现在有些迷惑,没事,我们换种方式来说明一下。
    假设差值是 diff,也就是 diff = X~i - Xi,那么,diff就有可能变动很大,如果引入一个不断变化的因子iDelta,那么,diff’ = diff / iDelta,而对于iDelta,每当diff变大的时候,他就变大比较大,当diff变得比较小的时候,他就相应的减小。这样,我们的diff’就能保持相对的稳定了。通过iDelta的引入,可以使得我们的DPCM编码自动的适应数据间大幅度的跳跃。这就是自适应脉冲编码调制,ADPCM的主要思想。

    你现在可能会想,iDelta到底怎么变化,才能自动的匹配diff的变化?一种可行的方法就是,把它定义为diff的一个函数,这个函数根据不同的diff的值的大小取不同大小的值。通常我们会做一个iDelta值的表,通过diff作为索引,这样,就可以根据不同的diff值,iDelta就可以作相应的变化了。

    预测编码之运动补偿
    主要用于视频图像编码中
    是一种描述相邻帧差别的方法,具体来讲是指描述前面一帧的每个小块怎样移动到当前帧中的某个位置去。常用来被视频压缩/视频编码解码器用来减少视频序列中的空域冗余。
    通常,图像帧是一组一组进行处理的。每组的第一帧在编码时不使用运动估计得方法,这种帧成为帧内编码帧,或I帧。该组中其他帧使用帧间编码帧,通常为P帧,这种编码方式成为IPPPP,表示编码的时候第一帧是I帧,其他帧是P帧。在进行预测的时候,不仅仅可以根据过去帧预测当前帧,还可以使用未来帧预测当前帧。即编码的顺序和播放的顺序是可以不同的。通常,这样的当前帧是使用过去和未来的I帧或者P帧同时进行预测的,成为双向预测帧即B帧。如:IBBPBBPBBPBB

    预测编码之增量调制编码
    模拟信号数字化方法:
    一种把信号上的采样值作为预测值的单纯预测编码方式,是最简单的预测编码方式之一。将信号瞬时值与前一抽样时刻的量化值之差进行量化,而且只对差值的符号进行编码,不对大小编码。因此量化只限于正和负两个电平。接收端每收到一个“1”码,译码器的输出相对于前一个时刻上升一个量阶,当收到连“1”码时,表示信号持续增长。反之亦然。译码器的输出再经过低通滤波器滤除高频量化噪声,从而恢复原始信号。只要抽样频率足够高,量化阶矩大小适当,接收端的信号与原始信号就非常接近。

    变换编码之主成分变换(KLT)
    KLT的基本原理:假设一幅图像在某个通信信道中传输了M次,由于任何物理信道均存在随即干扰因素,接收到的图像系列总混杂有许多随机干扰信号,称之为随机图像集合,集合中各图象之间存在相关性但又不相等。KLT本质上市针对这类广泛的随机图像提出来,当对M个图像施加了KLT以后,变换后的M新图像组成的集合中各图象之间互不相关。由变换结果图像集中取有限个图像K(K<M)而恢复的图像僵尸原图像在统计意义上的最佳逼近。
    参看 http://blog.csdn.net/tiandijun/article/details/20797817

    变换编码之离散余弦变换(DCT)
    JPEG图像格式的压缩算法采用的就是DCT。从原理上讲,可以对整幅图像进行DCT变换。但由于图像各个部分上细节的丰富程度不同,这种整体处理的方式效果不好。为此,发送者首先将输入图像分解为8x8或16x16的块,然后对每个图像块进行二维DCT变换,接着在对DCT系数进行量化,编码和传输,接受者通过对量化的DCT系数进行解码,并对图像块进行二维DCT反变换,最后拼接起来构成一幅完整的图像。对于一般的图像来讲,大多数的系数近似为0。所以,可以忽略之,并不影响效果。

    变换编码之沃尔什-哈达玛变换

    变换编码之小波变换

    JPEG2000静态图像编码标准中的图像变换技术就采用了离散小波变换。最大的特点是在不丢失重要信息的同时,能以比较高的比率压缩图像,并且算法计算量小。

    展开全文
  • 基于深度学习的图像压缩算法研究综述.pdf
  • 想到App巨头“微信”会是怎么处理,Luban(鲁班)就是通过在微信朋友圈发送近100张不同分辨率图片,对比原图与微信压缩后的图片逆向推算出来的压缩算法。 因为有其他语言也想要实现Luban,所以描述了一遍算法步骤。...
  • JPEG图像压缩算法详解

    千次阅读 2019-09-11 08:44:08
    转载自 ... JPEG压缩算法之前已有很多前辈详细讲解过,我就不在这里画蛇添足了(主要是我懒。...JPEG图像压缩算法详解 图片压缩有多重要,可能很多人可能并没有一个直观上的认识,举个例子,一张8...

    转载自

     

    http://www.ibm.com/developerworks/cn/linux/l-cn-jpeg/

    JPEG压缩算法之前已有很多前辈详细讲解过,我就不在这里画蛇添足了(主要是我懒。。),转载两篇JPEG压缩算法介绍,拼为一篇。侵删。

     

     

    JPEG图像压缩算法详解

     

            图片压缩有多重要,可能很多人可能并没有一个直观上的认识,举个例子,一张800X800大小的普通图片,如果未经压缩,大概在1.7MB左右,这个体积如果存放文本文件的话足够保存一部92万字的鸿篇巨著《红楼梦》,现如今互联网上绝大部分图片都使用了JPEG压缩技术,也就是大家使用的jpg文件,通常JPEG文件相对于原始图像,能够得到1/8的压缩比,如此高的压缩率是如何做到的呢?
            JPEG能够获得如此高的压缩比是因为使用了有损压缩技术,所谓有损压缩,就是把原始数据中不重要的部分去掉,以便可以用更小的体积保存,这个原理其实很常见,比如485194.200000000001这个数,如果我们用485194.2来保存,就是一种“有损”的保存方法,因为小数点后面的那个“0.000000000001”属于不重要的部分,所以可以被忽略掉。JPEG整个压缩过程基本上也是遵循这个步骤:
            1. 把数据分为“重要部分”和“不重要部分”
            2. 滤掉不重要的部分
            3. 保存

    步骤一:图像分割


            JPEG算法的第一步,图像被分割成大小为8X8的小块,这些小块在整个压缩过程中都是单独被处理的。后面我们会以一张非常经典的图为例,这张图片名字叫做Lenna,据说是世界上第一张JPG图片,这张图片自从诞生之日开始,就和图像处理结下渊源,陪伴了无数理工宅男度过了的一个个不眠之夜,可谓功勋卓著,感兴趣的朋友可以在这里了解到这张图片的故事。

     

    步骤二:颜色空间转换RGB->YCbCr


            所谓“颜色空间”,是指表达颜色的数学模型,比如我们常见的“RGB”模型,就是把颜色分解成红绿蓝三种分量,这样一张图片就可以分解成三张灰度图,数学表达上,每一个8X8的图案,可以表达成三个8X8的矩阵,其中的数值的范围一般在[0,255]之间。

     

    R>
    G>
    B>

            不同的颜色模型各有不同的应用场景,例如RGB模型适合于像显示器这样的自发光图案,而在印刷行业,使用油墨打印,图案的颜色是通过在反射光线时产生的,通常使用CMYK模型,而在JPEG压缩算法中,需要把图案转换成为YCbCr模型,这里的Y表示亮度(Luminance),Cb和Cr分别表示绿色和红色的“色差值”。
            “色差”这个概念起源于电视行业,最早的电视都是黑白的,那时候传输电视信号只需要传输亮度信号,也就是Y信号即可,彩色电视出现之后,人们在Y信号之外增加了两条色差信号以传输颜色信息,这么做的目的是为了兼容黑白电视机,因为黑白电视只需要处理信号中的Y信号即可。
            根据三基色原理,人们发现红绿蓝三种颜色所贡献的亮度是不同的,绿色的“亮度”最大,蓝色最暗,设红色所贡献的亮度的份额为KR,蓝色贡献的份额为KB,那么亮度为

    (1.1)

            根据经验,KR=0.299,KB=0.114,那么

    (1.2)

            蓝色和红色的色差的定义如下

    (1.3)
    (1.4)

            最终可以得到RGB转换为YCbCr的数学公式为

    (1.5)

            YCbCr模型广泛应用在图片和视频的压缩传输中,比如你可以留意一下电视或者DVD后面的接口,就可以发现色差接口。

            这是有道理的,还记得我们在文章开始时提到的有损压缩的基本原理吗?有损压缩首先要做的事情就是“把重要的信息和不重要的信息分开”,YCbCr恰好能做到这一点。对于人眼来说,图像中明暗的变化更容易被感知到,这是由于人眼的构造引起的。视网膜上有两种感光细胞,能够感知亮度变化的视杆细胞,以及能够感知颜色的视锥细胞,由于视杆细胞在数量上远大于视锥细胞,所以我们更容易感知到明暗细节。比如说下面这张图

    Y

    Y

    Cb

    Cb

    Cr

    Cr

            可以明显看到,亮度图的细节更加丰富。JPEG把图像转换为YCbCr之后,就可以针对数据得重要程度的不同做不同的处理。这就是为什么JPEG使用这种颜色空间的原因。

     

     

    步骤三:离散余弦变换



            这次我们来介绍JPEG算法中的核心内容,离散余弦变换(Discrete cosine transform),简称DCT。
            离散余弦变换属于傅里叶变换的另外一种形式,没错,就是大名鼎鼎的傅里叶变换。傅里叶是法国著名的数学家和物理学家,1807年,39岁的傅里叶在他的一篇论文里提出了一个想法,他认为任何周期性的函数,都可以分解为为一系列的三角函数的组合,这个想法一开始并没有得到当时科学界的承认,比如当时著名的数学家拉格朗日提出质疑,三角函数无论如何组合,都无法表达带有“尖角”的函数,一直到1822年拉格朗日死后,傅里叶的想法才正式在他的著作《热的解析理论》一书中正式发表。
            金子总会闪光,傅里叶变换如今广泛应用于数学、物理、信号处理等等领域,变换除了它在数学上的意义外,还有其哲学上的伟大意义,那就是,世上任何复杂的事物,都可以分解为简单的事物的组合,而这个过程只需要借助数学工具就可以了。但是当年拉格朗日的质疑是正确的,三角函数的确无法表达出尖角形状的函数,不过只要三角函数足够多,可以无限逼近最终结果。比如下面这张动图,就动态描述了一个矩形方波,是如何做傅里叶分析的。

     

     

            当我们要处理的不再是函数,而是一堆离散的数据时,并且这些数据是对称的话,那么傅里叶变化出来的函数只含有余弦项,这种变换称为离散余弦变换。举个例子,有一组一维数据[x0,x1,x2,…,xn-1],那么可以通过DCT变换得到n个变换级数Fi

    (2.1)

            此时原始数据Xi可以通过离散余弦变换变化的逆变换(IDCT)表达出来

    (2.2)

            也就是说,经过DCT变换,可以把一个数组分解成数个数组的和,如果我们数组视为一个一维矩阵,那么可以把结果看做是一系列矩阵的和

    (2.3)


            举个例子,我们有一个长度为8的数字,内容为50,55,67,80,-10,-5,20,30,经过DCT转换,得到8个级数为287.0,106.3,14.2,-110.8,9.2,65.7,-8.2,-43.9,根据公式2.3把这个数组转换为8个新的数组的和,如果我们使用图像来表达的话,就可以发现DCT转换的有趣之处了


    [50,55,67,80,-10,-5,20,30]
      
     数组0
      [35.9,35.9,35.9,35.9,35.9,35.9,35.9,35.9]
     数组1
      [26.0,22.1,14.8,5.2,-5.2,-14.8,-22.1,-26.1]
     数组2
      [3.3,1.4,-1.4,-3.3,-3.3,-1.4,1.4,3.3]
     数组3
      [-23.0,5.4,27.2,15.4,-15.4,-27.2,-5.4,23.0]
     数组4
      [1.6,-1.6,-1.6,1.6,1.6,-1.6,-1.6,1.6]
     数组5
      [9.1,-16.1,3.2,13.6,-13.6,-3.2,16.1,-9.1]
     数组6
      [-0.8,1.9,-1.9,0.8,0.8,-1.9,1.9,-0.8]
     数组7
      [-2.1,6.1,-9.1,10.8,-10.8,9.1,-6.1,2.1]

            奥妙之处在于,经过DCT,数据中隐藏的规律被发掘了出来,杂乱的数据被转换成几个工整变化的数据。DCT转换后的数组中第一个是一个直线数据,因此又被称为“直流数据”,简称DC,后面的数据被称为“交流数据”,简称AC,这个称呼起源于信号分析中的术语。
            在JPEG压缩过程中,经过颜色空间的转换,每一个8X8的图像块,在数据上表现为3个8X8的矩阵,紧接着我们对这三个矩阵做一个二维的DCT转换,二维的DCT转换公式为

    (2.1)

            DCT的威力究竟有多大,我们可以做一个实际的测试,比如一个所有数值都一样的矩阵,经过DCT转换后,将所有级数组合成一个新的矩阵

     

            可以看到,经过DCT转换,矩阵的“能量”被全部集中在左上角上的直流分量F(0,0)上,其他位置都变成了0。
            在实际的JPEG压缩过程中,由于图像本身的连贯性,一个8X8的图像中的数值一般不会出现大的跳跃,经过DCT转换会有类似的效果,左上角的直流分量保存了一个大的数值,其他分量都接近于0,我们以Lenna左上角第一块图像的Y分量为例,经过变换的矩阵为

     

            可以看到,数据经过DCT变化后,被明显分成了直流分量和交流分量两部分,为后面的进一步压缩起到了充分的铺垫作用,可以说是整个JPEG中最重要的一步,后面我们会介绍数据量化。

     

     

    步骤四:数据量化


            经过上一节介绍的离散余弦变换,图像数据虽然已经面目全非,但仍然是处于“可逆”的状态,也就是说我们还没有进入“有损”的那一步。这次我们来玩真的,看一下数据中的细节是如何被滤去的。先来考察一下要对付的问题是什么,经过颜色空间转换和离散余弦变换,每一个8X8的图像块都变成了三个8X8的浮点数矩阵,分别表示Y,Cr,Cb数据,比如以其中某个亮度数据矩阵举例,它的数据如下

            我们的问题是,在可以损失一部分精度的情况下,如何用更少的空间存储这些浮点数?答案是使用量子化(Quantization),简称量化。“量子”这个概念来自于物理学,意思是说连续的能量可以看做是一个个单元体的组合,看起来高端大气,其实很简单,比如游戏中在处理角色面朝方向时,一般并不是使用0到2π这样的浮点数,而是把方向分成16个区间,用0到16这样的整数来表示,这样只用4个bit就足够了。JPEG提供的量子化算法如下:

     

     

    (3.1)

            其中G是我们需要处理的图像矩阵,Q称作量化系数矩阵(Quantization matrices),JPEG算法提供了两张标准的量化系数矩阵,分别用于处理亮度数据Y和色差数据Cr以及Cb。

    标准亮度量化表

    标准亮度量化表

    标准色差量化表

    标准色差量化表


            其中round函数是取整函数,但考虑到了四舍五入,也就是说

    (3.2)

            比如上面数据,以左上角的-415.38为例,对应的量子化系数是16,那么round(-415.38/16)=round(-25.96125)=-26。最终得到的量子化后的结果为

            可以看到,一大部分数据变成了0,这非常有利于后面的压缩存储。这两张神奇的量化表也是有讲究的,还记得我们在第一节中所讲的有损压缩的基本原理吗,有损压缩就是把数据中重要的数据和不重要的数据分开,然后分别处理。DCT系数矩阵中的不同位置的值代表了图像数据中不同频率的分量,这两张表中的数据时人们根据人眼对不不同频率的敏感程度的差别所积累下的经验制定的,一般来说人眼对于低频的分量必高频分量更加敏感,所以两张量化系数矩阵左上角的数值明显小于右下角区域。在实际的压缩过程中,还可以根据需要在这些系数的基础上再乘以一个系数,以使更多或更少的数据变成0,我们平时使用的图像处理软件在省城jpg文件时,在控制压缩质量的时候,就是控制的这个系数。
            在进入下一节之前,矩阵的量化还有最后一步要做,就是把量化后的二维矩阵转变成一个一维数组,以方便后面的霍夫曼压缩,但在做这个顺序转换时,需要按照一个特定的取值顺序。

            这么做的目的只有一个,就是尽可能把0放在一起,由于0大部分集中在右下角,所以才去这种由左上角到右下角的顺序,经过这种顺序变换,最终矩阵变成一个整数数组

    -26,-3,0,-3,-2,-6,2,-4,1,-3,0,1,5,,1,2,-1,1,-1,2,0,0,0,0,0,-1,-1,0,0,0,0,…,0,0


            后面的工作就是对这个数组进行再一次的哈夫曼压缩,已得到最终的压缩数据。

     

     

    步骤五:哈弗曼编码


            JPEG压缩的最后一步是对数据进行哈弗曼编码(Huffman coding),哈弗曼几乎是所有压缩算法的基础,它的基本原理是根据数据中元素的使用频率,调整元素的编码长度,以得到更高的压缩比。
            举个例子,比如下面这段数据

     

     

    “AABCBABBCDBBDDBAABDBBDABBBBDDEDBD”

            这段数据里面包含了33个字符,每种字符出现的次数统计如下

    字符ABCDE
    次数615291

            如果我们用我们常见的定长编码,每个字符都是3个bit。

    字符ABCDE
    编码001010011100101

            那么这段文字共需要3*33 = 99个bit来保存,但如果我们根据字符出现的概率,使用如下的编码

    字符ABCDE
    编码11001110101111

            那么这段文字共需要3*6 + 1*15 + 4*2 + 2*9 + 4*1 = 63个bit来保存,压缩比为63%,哈弗曼编码一般都是使用二叉树来生成的,这样得到的编码符合前缀规则,也就是较短的编码不能够是较长编码的前缀,比如上面这个编码,就是由下面的这颗二叉树生成的。

            我们回到JPEG压缩上,回顾上一节的内容,经过数据量化,我们现在要处理的数据是一串一维数组,举例如下:

    ①原始数据

    35,7,0,0,0,-6,-2,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,…,0

            在实际的压缩过程中,数据中的0出现的概率非常高,所以首先要做的事情,是对其中的0进行处理,把数据中的非零的数据,以及数据前面0的个数作为一个处理单元。

    ①原始数据

    35,7,0,0,0,-6,-2,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,…,0

    ②RLE编码3570,0,0,-6-20,0,-90,0,…,0,80,0,…,0

            如果其中某个单元的0的个数超过16,则需要分成每16个一组,如果最后一个单元全都是0,则使用特殊字符“EOB”表示,EOB意思就是“后面的数据全都是0”,

    ①原始数据

    35,7,0,0,0,-6,-2,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,…,0

    ②RLE编码3570,0,0,-6-20,0,-90,0,…,0,80,0,…,0
    3570,0,0,-6-20,0,-90,0,…,00,0,80,0,…,0
    (0,35)(0,7)(3,-6)(0,-2)(2,-9)(15,0)(2,8)EOB

           * RLE - Run-Length Encoding,即行程编码,对于连续重复出现的字符有很好的压缩率。编码后为(字符出现次数,字符)。

           * JPEG 中实际使用的是(字符出现次数 - 1,字符)

     

            其中(15,0)表示16个0,接下来我们要处理的是括号里右面的数字,这个数字的取值范围在-2047~2047之间,JPEG提供了一张标准的码表用于对这些数字编码:

    ValueSizeBits
    00
    -11101
    -3,-22,3200,0110,11
    -7,-6,-5,-44,5,6,73000,001,010,011100,101,110,111
    -15,…,-88,…,1540000,…,01111000,…,1111
    -31,…,-1616,…,3150 0000,…,0 11111 0000,…,1 1111
    -63,…,-3232,…,63600 0000,……,11 1111
    -127,…,-6464,…,1277000 0000,……,111 1111
    -255,…,-128128,…,25580000 0000,……,1111 1111
    -511,…,-256256,…,51190 0000 0000,……,1 1111 1111
    -1023,…,-512512,…,10231000 0000 0000,……,11 1111 1111
    -2047,…,-10241024,…,204711000 0000 0000,……,111 1111 1111

            举例来说,第一个单元中的“35”这个数字,在表中的位置是长度为6的那组,所对应的bit码是“100011”,而“-6”的编码是”001″,由于这种编码附带长度信息,所以我们的数据变成了如下的格式。

    ①原始数据

    35,7,0,0,0,-6,-2,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,…,0

    ②RLE编码3570,0,0,-6-20,0,-90,0,…,0,80,0,…,0
    3570,0,0,-6-20,0,-90,0,…,00,0,80,0,…,0
    (0,35)(0,7)(3,-6)(0,-2)(2,-9)(15,0)(2,8)EOB
    ③BIT编码(0,6, 100011)(0,3, 111)(3,3, 001)(0,2, 01)(2,4, 0110)(15,-)(2,4, 1000)EOB

            括号中前两个数字分都在0~15之间,所以这两个数可以合并成一个byte,高四位是前面0的个数,后四位是后面数字的位数。

    ①原始数据

    35,7,0,0,0,-6,-2,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,…,0

    ②RLE编码3570,0,0,-6-20,0,-90,0,…,0,80,0,…,0
    3570,0,0,-6-20,0,-90,0,…,00,0,80,0,…,0
    (0,35)(0,7)(3,-6)(0,-2)(2,-9)(15,0)(2,8)EOB
    ③BIT编码(0,6, 100011)(0,3, 111)(3,3, 001)(0,2, 01)(2,4, 0110)(15,-)(2,4, 1000)EOB
    (0x6,100011)(0x3,111)(0x33,001)(0x2,01)(0x24,0110)(0xF0,-)(0x24,1000)EOB

            对于括号前面的数字的编码,就要使用到我们提到的哈弗曼编码了,比如下面这张表,就是一张针对数据中的第一个单元,也就是直流(DC)部分的哈弗曼表,由于直流部分没有前置的0,所以取值范围在0~15之间。

    LengthValueBits
    3 bits04
    05
    03
    02
    06
    01
    00 (EOB)
    000
    001
    010
    011
    100
    101
    110
    4 bits071110
    5 bits081111 0
    6 bits091111 10
    7 bits0A1111 110
    8 bits0B1111 1110

            举例来说,示例中的DC部分的数据是0x06,对应的二进制编码是“100”,而对于后面的交流部分,取值范围在0~255之间,所以对应的哈弗曼表会更大一些

    LengthValueBits
    2 bits01
    02
    00
    01
    3 bits03100
    4 bits00 (EOB)
    04
    11
    1010
    1011
    1100
    5 bits05
    12
    21
    1101 0
    1101 1
    1110 0
    6 bits31
    41
    1110 10
    1110 11
    12 bits24
    33
    62
    72
    1111 1111 0100
    1111 1111 0101
    1111 1111 0110
    1111 1111 0111
    15 bits821111 1111 1000 000
    16 bits09

    FA
    1111 1111 1000 0010

    1111 1111 1111 1110

            这样经过哈弗曼编码,并且序列化后,最终数据成为如下形式

    ①原始数据

    35,7,0,0,0,-6,-2,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,…,0

    ②RLE编码3570,0,0,-6-20,0,-90,0,…,0,80,0,…,0
    3570,0,0,-6-20,0,-90,0,…,00,0,80,0,…,0
    (0,35)(0,7)(3,-6)(0,-2)(2,-9)(15,0)(2,8)EOB
    ③BIT编码(0,6, 100011)(0,3, 111)(3,3, 001)(0,2, 01)(2,4, 0110)(15,-)(2,4, 1000)EOB
    (0x6,100011)(0x3,111)(0x33,001)(0x2,01)(0x24,0110)0xF0(0x24,1000)EOB
    ④哈弗曼编码1001000111001111111 1111 010100101011111 1111 010001101111 1111 0011111 1111 010010001010
    ⑤序列化

    100100011100111111111110101001010111111111010001101111111100111111111010010001010

    91 CF FE A5 7F D1 BF CF FA 45

            最终我们使用了10个字节的空间保存了原本长度为64的数组,至此JPEG的主要压缩算法结束,这些数据就是保存在jpg文件中的最终数据。

     

    一个JPEG图片实例分析

     

     

    我们可以打开 JPEG 文件查看里面的内容,即可看到上面的各个标记段:

     

    在头部有 FFD8 ,表示图像的开始;结束部分有 FFD9 ,表示图像的结束。

    在中间有两个量化表 DQT 对应的标记 FFDB ;

    还有图像大小信息对应的 FFC0

    再后面有四个 Haffman 表对应的 FFC4 ;

     

    一般一个 JPEG 文件里会有 2 类 Haffman 表:一个用于 DC 一个用于 AC ,也即实际有 4个表,亮度的 DC,AC 两个,色度的 DC,AC 两个。

    然后是图像数据段标记 FFDA;

     

    我们再来看看各个标记的细部,具体分析一下各个部分的含义。

    1、图片的识别信息

    上面的内容,在标记 FFE0 后,即为长度16。

    然后是5字节的 JFIF 标识符号,说明这是一个 JPEG 压缩的文件。

    然后是主/次版本号码。下一个为 XY 像素的单位,这里为1,表示单位为点数/英寸。

    然后是 XY 方向的像素密度,这里是 96DPI,最后是缩略图有关信息,这里为0。

     

    2、量化表的实例

    上面这个内容,FFDB 标记后的长度值为67,接下来的是 QT 信息,占一个字节;

    这里是0,表示这个 QT 表编号为0,并且精度是8bit。然后后面就是64个8x8的 QT 表的各个 item 了。

    也即第一个 DQT 量化表的内容表示为十进制是:

    这个表即为 JPEG 亮度量化表。

     

    第二个量化表的内容为:

    这个表的内容即为 JPEG 色度量化表。

    当你打开不同的 JPEG 文件,你会看到这两个表可能也是会有区别的。这个主要是使用了不同的量化方式的结果。

     

    3、图像信息段

    上面这个内容,FFC0 标记后即是长度,为17;

    然后是一个字节的数据精度,通常是为8,代表样本位数。

    接下来是图片的高度,占两字节,这里即为8,然后是图片的宽度,也为8,这也就是我们定义的8x8的内容。

    然后是 component 的个数,这里是3,表示 YUV。接下来是三组数据,每组数据里,第一个是 component ID,第二个是采样系数,这里 Y 的采样系数为22,说明垂直是2,水平是2。

    再后面就是量化表的编号了。

     

    4、Haffman 表的实例

    上面这个内容,FFC4 标记后的内容为数据长度,再接着的1字节为 Huffman Table 的信息,低4位是 HT ID 号,第5位是 HT 表类型标记,再高三位是为0。

    第一个 DHT 表,00,类型为 DC table,HT ID 号为 0;

    第二个 DHT 表,10,类型为 AC table,HT ID 号也为 0;

    第三个 DHT 表,01,类型为 DC table,HT ID 号为 1;

    第四个 DHT 表,11,类型为 AC table,HT ID 号为 1;

    即前两个表为Y亮度分量的 DC/AC 表,后两个为 UV 色度分量的 DC/AC 表。

     

    以第一个表为例,因为长度只有 31,那么 00 后面的 16 字节,即绿色部分:

    组号为 1 的组中,代码有 0 个;

    组号为 2 的,代码有 1 个;

    组号为 3 的代码有 5 个;

    组号为 4/5/6/7/8/9 的代码各 1 个。

    总共 12 个。

    再看后续的数据:

    00 01 02 03 04 05 06 07 08 09 0A 0B

    即对应:

    其他未出现的组号,对应的数据未使用到。也就是说前面提到过的范式 Huffman 编码里,目前只使用部分数据即可,原因是这个 8x8 的图像数据很小。

    第二个 DHT 表就更复杂些了,长度有 181。

     

    5、图像数据段

    这里 SOS 段,长度为 12,后面所含有的 component 数量为 3 个,也即 Y UV。然后后面是各 component 的编号,及对应所使用的 Huffman 表的 ID 是多少。

    在这个段的后面就是所有压缩后的数据。直到结束的问题,即 FFD9,EOI(End Of Image)。

     

     

     

    转载自:

    http://thecodeway.com/blog/

    http://www.ibm.com/developerworks/cn/linux/l-cn-jpeg/

    展开全文
  • 基于改进的SPIHT图像压缩算法,胡晖,卢珏,针对SPIHT算法中的零树结构以及分集判断规则所产生的冗余对编码效果的影响,本文提出了一种改进算法。通过改变原算法的初始化步骤�
  • JPEG-LS算法是公认的灰度图像有效的压缩算法。然而,对于计算机绘制的灰度图像(如CAD、SOLIDWORK等),其压缩效率低,限制了JPEG-LS的广泛应用。提出一种基于两步编码法的图像有效压缩算法,即建模和编码,算法与...
  • 实验结果表明,优化后的编码器降低了运算复杂度,提高了CCSDS图像压缩算法的实时性。  空间数据咨询会(CCSDS)于2005年11月提出的针对空间应用的CCSDS图像压缩算法,具有良好的图像压缩性能和抗误码能力,同时算法...
  • matlab上利用主成分分析(PCA)对图像进行压缩的程序,有详细注释,给想学习PCA的人提供参考。
  • 是运动图像压缩算法的国际标准 目录 1?简介 2?标准 3?历史 4?常见谬误 5?全新压缩理念 MPG MPG?又称?MPEGMoving?Pictures?Experts?Group即动态 图像专家组由国际标准化组织?ISO(International Standards?...
  • 图像压缩算法:seal:一种新的图像压缩算法。 在最新版本中,该算法在大多数情况下的性能要优于PNG。 实际上,唯一变大的图像是img_4。 原始的img_2.png例如为12.8 MB; 压缩的二进制文件只有10.1 MB的大小。 但是,这...
  • 本文实例讲述了Python基于opencv的图像压缩算法。分享给大家供大家参考,具体如下: 插值方法: CV_INTER_NN - 最近邻插值, CV_INTER_LINEAR - 双线性插值 (缺省使用) CV_INTER_AREA - 使用象素关系重采样。当图像...

    本文实例讲述了Python基于opencv的图像压缩算法。分享给大家供大家参考,具体如下:

    插值方法:

    CV_INTER_NN - 最近邻插值,
    CV_INTER_LINEAR - 双线性插值 (缺省使用)
    CV_INTER_AREA - 使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 CV_INTER_NN 方法..
    CV_INTER_CUBIC - 立方插值.

    函数 cvResize 将图像 src 改变尺寸得到与 dst 同样大小。若设定 ROI,函数将按常规支持 ROI.

    程序1:图像压缩(第一版)

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    # coding=utf-8

    import time

    time1 = time.time()

    import cv2

    image=cv2.imread("c:/1.jpg")

    res = cv2.resize(image, (1280,960), interpolation=cv2.INTER_AREA)

    # cv2.imshow('image', image)

    # cv2.imshow('resize', res)

    # cv2.waitKey(0)

    # cv2.destroyAllWindows()

    cv2.imwrite("C:/5.jpg",res)

    time2=time.time()

    print u'总共耗时:' + str(time2 - time1) + 's'

    4.19M—377k 压缩了11倍

    程序2:图像压缩(第二版)

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    #-*-coding:utf-8-*-

    #############设置编码################

    import sys

    reload(sys)

    sys.setdefaultencoding('utf-8')

    ###################导入计算机视觉库opencv和图像处理库PIL####################

    from PIL import Image

    from PIL import ImageEnhance

    from PIL import ImageFilter

    import cv2

    import time

    time1 = time.time()

    ####################读入图像###############################

    image=cv2.imread("c:/pic//0.jpg")

    ####################双三次插值#############################

    res = cv2.resize(image, (1280,960), interpolation=cv2.INTER_AREA)

    ####################写入图像########################

    cv2.imwrite("C:/pic/101.jpg",res)

    ###########################图像对比度增强##################

    imgE = Image.open("c:/pic/101.jpg")

    imgEH = ImageEnhance.Contrast(imgE)

    img1=imgEH.enhance(2.8)

    ########################图像转换为灰度图###############

    gray = img1.convert("L")

    gray.save("C:/pic/3.jpg")

    ##########################图像增强###########################

    # 创建滤波器,使用不同的卷积核

    gary2=gray.filter(ImageFilter.DETAIL)

    gary2.save("C:/pic/2.jpg")

    #############################图像点运算#################

    gary3=gary2.point(lambda i:i*0.9)

    gary3.save("C:/pic/4.jpg")

    # img1.show("new_picture")

    time2=time.time()

    print u'总共耗时:' + str(time2 - time1) + 's'

    4.17M–>290kb

    程序3:函数版本

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    #-*-coding:utf-8-*-

    #############设置编码################

    import sys

    reload(sys)

    sys.setdefaultencoding('utf-8')

    ############导入计算机视觉库opencv和图像处理库PIL####################

    from PIL import Image

    from PIL import ImageEnhance

    from PIL import ImageFilter

    import cv2

    import time

    time1 = time.time()

    ########################自定义图像压缩函数############################

    def img_zip(path,filename1,filename2):

      image = cv2.imread(path+filename1)

      res = cv2.resize(image, (1280, 960), interpolation=cv2.INTER_AREA)

      cv2.imwrite(path+filename2, res)

      imgE = Image.open(path+filename2)

      imgEH = ImageEnhance.Contrast(imgE)

      img1 = imgEH.enhance(2.8)

      gray1 = img1.convert("L")

      gary2 = gray1.filter(ImageFilter.DETAIL)

      gary3 = gary2.point(lambda i: i * 0.9)

      gary3.save(path+filename2)

    ################################主函数##################################

    if __name__ == '__main__':

      path=u"c:/pic/"

      filename1="0.jpg"

      filename2="1.jpg"

      img_zip(path,filename1,filename2)

      time2 = time.time()

      print u'总共耗时:' + str(time2 - time1) + 's'

    转自:https://www.jb51.net/article/139334.htm 

    展开全文
  • 文中的即时通讯应用系统基于中小型APP中即时聊天功能的实现,为了提高轻量级聊天功能的性能,特别需要解决聊天中图片压缩的问题,在保证客户端图片压缩质量的同时可以在一定程度上降低服务器端负载,让图片数据可以...
  • 图像压缩算法的设计与实现”演讲用PPT 介绍了“图像压缩”所采取的JPEG算法,并对算法实现的原理进行了图解
  • 多媒体数据压缩技术是实现实时有效地处理、传输和存储庞大...本文主要是把所学的图像压缩算法涉及的知识应用于实践,对目前普遍采用的多媒体数据及其压缩算法加以研究,同时介绍了图像压缩所采用的分类、方法及其标准。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 137,828
精华内容 55,131
关键字:

图像压缩算法

友情链接: IPM2.zip