首页 > 代码库 > ComicEnhancerPro 系列教程二十:用“文件比较”看有损、无损

ComicEnhancerPro 系列教程二十:用“文件比较”看有损、无损

作者:马健
邮箱:stronghorse_mj@hotmail.com
主页:http://www.comicer.com/stronghorse/
发布:2017.07.23

教程二十:用“文件比较”看有损、无损

在前两篇教程中,扯了一大堆JPG文件的有损压缩,平时在网上也经常看到一些人整天把有损、无损挂在嘴边,但具体是否真的无损?有损又损了多少、损在哪里?讲得清的人就真心不多了。CEP从v4.13开始提供“文件比较”功能,可用于定量比较有损、无损。

按照CEP的使用说明,“文件比较”功能提供两种定量比较结果:

  1. 图像差值绝对值的统计量:源文件1的像素值减去源文件2的像素值,并对结果取绝对值后进行统计。计算方法:逐像素相减、取绝对值后,得到一个结果数组,然后统计这个数组的统计特征量,包括最大值、平均值、标准差。对于单通道图像(灰度图像),结果数组是个一维数组,所以统计特征量也只有一个。对于24位真彩图像,结果数组是个三维数组(R、G、B三个通道分别计算),所以统计特征量也显示3个,即各通道分别计算 ,按照R、G、B顺序排列。
    均值、标准差有两组,对应不同的分母:粉色的那组是针对整个图像计算的,即两个图像中相同的像素(结果数组中值为0)也参与计数;蓝色的那组只针对不同的像素,即结果数组中的零值不参与统计。
  2. 相似度:这个其实是论文《A Universal Image Quality Index》(Z.Wang, A.C.Bovik. IEEE Signal Processing Letters, vol.9, No.3, March 2002, pp.81-84.)中提出的算法,比较两个图像的相似度。各通道分别计算、显示。结果值的范围是-1~1,越接近1说明两个图像越相像,值为1则说明两个图像完全相同。

针对图像差值绝对值的统计量,还进一步提供直方图、差异图像等工具。

下面结合实例,说一下如何用这个功能进行比较。注意所有步骤均是可重复的,所有数据也是可重现的,因此这里更重要的是在说明比较的方法。

首先来验证一下我在教程十八中提出的观点:DCT量化之后的熵编码过程对图像质量无影响,但优化编码、渐进(progressive)编码在一定程度上可以减小文件长度。

验证步骤:

  1. 启动CEP,点击“恢复”按钮以清空参数,打开教程十八中的示例PNG文件。
  2. 把JPG拉到100,强制使用全1的量化矩阵,避免量化过程对质量的影响。
  3. 设置JPG质量细则,先用缺省的“渐进式”,把示例PNG文件另存为1.jpg。注意“颜色采样”方式为“自动”,CEP在质量系数100时不会对颜色进行缩水,因此可以避免颜色缩水对质量的影响。
  4. 设置JPG质量细则,把“渐进式”去掉,保留“优化编码”,示例PNG文件另存为2.jpg。
    技术分享
  5. 把“渐进式”、“优化编码”都去掉,示例PNG文件另存为3.jpg。

结果如表1所示。其中压缩比=文件长度/1382400,其中1382400=图像像素高度×图像像素宽度×每像素字节数=800×576×3。 表中文件长度是用DOS重定向功能复制过来。

表1

文件名 文件长度(字节) 压缩比 参数
1.jpg 131,686 0.095 渐进+优化
2.jpg 138,048 0.100 优化
3.jpg 146,245 0.106

我对表1的解读:

  1. 从文件长度栏看,渐进、优化对减小JPG文件长度确实有效果。
  2. 即使质量系数高达100%,JPG文件仍然能取得接近10:1的压缩比。

下面就该实际看一下这3个文件在质量上有没有差异了。操作步骤:

  1. 启动CEP,点击工具条上的按钮进入“图像比较”界面。
  2. “源文件1”选上面生成的1.jpg,“源文件2”选上面生成的2.jpg,点击“比较”,可以看到“最大值”显示的全是0,即两个图像差值的最大值是0,实际是没有差异,也就是说这两个图像完全相同。专门给小白看的证明过程:如A - B = 0,则A = B。
  3. “源文件1”不变,“源文件2”改选上面生成的3.jpg,点击“比较”,最大值仍然是0,说明两个图像完全相同。由此完成A = B,A = C,则A = B= C的证明。

据此,说明“编码”选项确实会影响JPG文件长度,但对JPG文件质量无影响。采用同样的方法,可以检验各种声称“无损优化JPG”的软件是否真的无损:比较优化前后的JPG文件,最大值是0则真的无损,否则就有损,有损多少可以用统计特征值描述。

下面就用这个方法验证一下JPEGsnoop的作者Calvin Hass的说法:如果转存JPG文件时继续使用原JPG文件的量化表、色彩缩减倍数,则可以认为转存过程是无损(Recompress Losslessly)。验证操作步骤:

  1. 以教程十八中的图3、图4为测试对象,右键另存并更名为a.jpg、b.jpg。
  2. 启动CEP,点“恢复”按钮重置所有参数。
  3. 在JPG页点“设置”按钮进入“JPG质量细则”,勾选“优先使用原JPG质量系数”、“优先使用原JPG采样参数”、“优先使用原JPG编码参数”三个选项,确保CEP在转存时继续使用原JPG文件的量化表、色彩缩减倍数等。
    技术分享
  4. 用CEP打开步骤1保存的a.jpg,另存为a1.jpg;打开b.jpg,另存为b1.jpg。
  5. 用DOS下的DIR命令查看文件长度,用JpegQuality查看JPG文件的压缩参数,用CEP分别比较a.jpg和a1.jpg、b.jpg和bi.jpg,结果如表2。表中文件长度是用DOS重定向功能复制过来,其余均用WinCam32从JpegQuality、CEP界面直接复制过来,不存在手工输入错误的问题。以下各表不再重复说明。

表2

文件名 文件长度 质量系数 采样 是否渐进式JPEG 是否优化编码 最大值 不同像素 平均值 标准差
a.jpg 268,726 95 1x1 1x1 1x1

6/5/8

112599, 24.44% 0.89/0.71/1.06 0.79/0.61/0.86
a1.jpg 269,668 95 1x1 1x1 1x1
b.jpg 205,393 95 1x1 2x2 2x2 41/35/70 179664, 38.99% 2.10/1.63/2.43 3.74/2.48/3.83
b1.jpg 205,350 95 1x1 2x2 2x2

我对表2的解读:

  1. 采用直接copy原JPG文件压缩参数的方式转存JPG,文件长度确实能基本保持不变。
  2. 如果原JPG文件没有对色度进行缩水(表2中的灰色行),转存前后质量方面不能说没有差异,但从差异的最大值、平均值、标准差来看,这种差异还没有大到肉眼能够分辨的程度。
  3. 如果原JPG文件对色度进行了双向缩水(表2中的最后两行),转存时再缩一次,其差异可能已经到了肉眼能够分辨的程度了。证明过程很简单:在比较b.jpg、b1.jpg时,点击“保存差异图像”保存,然后打开保存的差异图像,在一片漆黑中其实已经能看到一些隐隐的灰色了。

以上验证过程证明Calvin Hass的说法是有漏洞的,不过这可能是因为他经常接触的JPG转存软件是Photoshop,而这个软件在质量7以上是不会对色度进行缩水的,所以他体会不到。readfree论坛上的人经常接触的是从PDG导出的JPG文件,不仅质量系数低到出奇,双向缩水更是必不可少,转存彩色图像的时候就不能不注意了。 不过就PDG文件的图像质量而言,其实注意不注意的关系也不大。

继续验证一下色度子采样(颜色缩水)对JPG文件长度和质量的影响。仍然采用教程十八中的示例PNG文件,操作步骤为:

  1. 启动CEP,点击“恢复”按钮清空参数,打开教程十八中的示例PNG文件。
  2. 把JPG拉到100,强制使用全1的量化矩阵,避免量化过程对质量的影响。
  3. 设置JPG质量细则,把“编码”中的“渐进式”、“优化编码”全部去掉,避免优化Huffman的影响。
  4. “颜色采样”的“方式”选“手动”,把“水平方向缩一半”、“垂直方向缩一半”全部去掉,把示例PNG文件另存为11.jpg。
    技术分享
  5. 勾选“水平方向缩一半”,去掉“垂直方向缩一半”,把示例PNG文件另存为12.jpg。
  6. 去掉“水平方向缩一半”,勾选“垂直方向缩一半”,把示例PNG文件另存为13.jpg。
  7. 勾选“水平方向缩一半”、“垂直方向缩一半”,把示例PNG文件另存为14.jpg。
  8. 把上述4个文件分别与示例PNG文件进行比较,结果见表3。

表3

文件名 文件长度(字节) 缩水倍数 最大值 不同像素 平均值 标准差
11.jpg 572,620 1x1 4/3/4 88531, 19.21% 0.54/0.35/0.84 0.61/0.49/0.66
12.jpg 453,626 2x1 94/54/230 410481, 89.08% 2.11/1.67/2.15 6.91/3.81/8.25
13.jpg 465,015 1x2 120/55/228 413083, 89.64% 2.43/1.88/2.77 7.81/4.21/10.08
14.jpg 397,500 2x2 157/79/255 162997, 35.37% 6.24/3.91/7.83 15.26/8.30/17.82

表3中的“缩水倍数”是从JpegQuality中复制的“采样”,即色度分量的缩水倍数;后面4栏是从CEP的“文件比较”界面中复制的,其中平均值、标准差只采用不同像素的,从“不同像素”的比例看全图平均会计入很多零,没啥意思,故不取。

我对表3的解读:

  1. 从总体数字上看,色度缩水确实可以减小文件长度,但缩水越多,差值的最大值、平均值、标准差就越大,说明“有损”造成的误差越大。
  2. 由于示例PNG文件是一个横幅图像,所以在“保持质量同时减小文件长度”方面,水平方向缩水比垂直方向缩水的效果更显著,这可能也是在教程十九的表2中相机厂商多选择水平方向缩水、垂直方向不缩水的原因,因为单反画面的比例是3:2,也是横的,DC画面比例一般是4:3,比单反的比例小一点,但与单反共用一个ISP时肯定以单反为准。
  3. “不同像素”栏的比例数字粗看起来有点奇怪,似乎缩水3/4后不同像素的比例反而变少了,其原因我认为是因为示例PNG文件是一个人工图像,有大量的纯色区,双向缩水后再插值回来,会产生模糊,反而减少了差异 ,参见后面图6、图7。
  4. 从11.jpg的统计量看,当JPG质量系数100%,又不对颜色进行缩水的情况下,虽然仍然不能达到真正的“无损”,但那么一点点误差,我真的不相信有谁的眼睛能看得出来,所以说“视觉无损”是完全没有问题的。

那么对于没有颜色可缩水的灰度图像,是否在质量系数100%(量化表全是1)时可以得到无损的结果呢?可以按照下面的步骤进行测试:

  1. 启动CEP,点击“恢复”按钮清空参数,打开教程十八中的示例PNG文件。
  2. 在“色彩”中选择“256级灰度”,转为灰度图像。
  3. 另存为1.png。
  4. 不要关闭文件,直接把JPG质量拉到100%,另存为2.jpg。
  5. 比较1.png和2.jpg,可以看出差值的最大值是1,我相信这样的误差没有谁的眼睛能看得出来,所以虽然数值上不是完全的无损,但心理上当作是无损的则应该不会有啥问题。至于误差源,我个人相信是浮点计算结果转整数时的圆整误差。

与颜色相关的说完了,下面再来看一下质量系数对文件长度和质量的影响。仍然采用教程十八中的示例PNG文件,操作步骤为:

  1. 启动CEP,点击“恢复”按钮清空参数,打开教程十八中的示例PNG文件。
  2. 设置JPG质量细则,把“编码”中的“渐进式”、“优化编码”全部去掉,避免优化Huffman的影响;把“颜色采样”的“方式”改为“手动”,把“水平方向缩一半”、“垂直方向缩一半”全部去掉,避免颜色缩水造成影响。
    技术分享
  3. 改变JPG质量系数,从100开始,逐次往下减小,每改一次把示例PNG文件存为JPG一次,文件名就是JPG质量系数。如质量系数为100%,则文件名为100.jpg;90%则文件名为90.jpg。
  4. 从这些文件中抽取一些,用“文件比较”功能与示例PNG文件进行比较,结果见表4。

表4

文件 文件长度 最大值 平均值 标准差
10.jpg 46,446 255/253/255 18.68/18.42/19.89 23.92/24.78/26.22
20.jpg 70,284 222/202/255 11.78/12.36/13.75 17.69/17.09/19.43
30.jpg 88,096 176/163/255 10.60/9.56/11.37 13.97/13.82/16.23
40.jpg 101,767 166/147/223 7.69/7.47/8.93 11.92/11.11/13.71
50.jpg 114,120 155/110/219 6.95/6.39/8.47 10.39/9.65/11.84
60.jpg 127,173 128/105/175 7.22/6.72/8.70 9.52/8.50/10.92
65.jpg 135,981 123/89/182 6.74/6.03/7.80 8.45/7.53/10.00
70.jpg 146,245 106/72/163 4.88/4.41/5.67 6.99/6.14/8.32
75.jpg 157,731 95/65/126 5.64/5.06/6.67 6.81/5.86/8.20
80.jpg 174,218 89/59/92 4.74/4.20/5.74 5.71/4.81/6.83
85.jpg 198,305 71/38/95 3.93/3.34/4.67 4.53/3.74/5.50
90.jpg 235,384 40/25/49 2.91/2.39/3.51 3.25/2.61/3.97
91.jpg 245,351 36/22/49 2.65/2.16/3.24 2.98/2.38/3.61
92.jpg 255,091 32/21/43 2.47/1.96/3.00 2.73/2.15/3.29
93.jpg 270,228 30/18/32 2.16/1.79/2.78 2.44/1.87/2.90
94.jpg 290,035 21/16/29 1.98/1.61/2.48 2.17/1.64/2.58
95.jpg 312,410 18/13/28 1.74/1.37/2.27 1.89/1.43/2.22
96.jpg 343,296 17/10/22 1.50/1.16/1.92 1.57/1.17/1.86
97.jpg 378,940 12/8/15 1.28/0.97/1.65 1.29/0.94/1.51
98.jpg 423,062 8/6/12 1.06/0.77/1.35 1.00/0.74/1.17
99.jpg 506,668 5/3/6 0.73/0.53/1.04 0.75/0.57/0.83
100.jpg 572,620 4/3/4 0.54/0.35/0.84 0.61/0.49/0.66

由于数据比较多,所以用Excel生成统计图,如图1、图2、图3、图4所示,图中的横轴均为CEP中的JPG质量系数。

技术分享
图1

技术分享
图2

技术分享
图3

技术分享
图4

结合表4、图1~4,可以看出:

  1. 在颜色不缩水的情况下,JPG图像误差基本上与CEP质量系数成线性反比关系,而文件长度则与质量系数成非线性关系,尤其在质量系数90%以上时文件长度随质量系数下降非常快,90%以下则相对降得慢一些,到30%以下又开始降得稍快一点。换句话说,质量系数90%以上时基本上在图像质量看不出明显差异的情况下文件长度随质量系数下降比较快,质量系数低于90%时就没那么明显了。
  2. 在教程十九的表1中,Photoshop的最高质量12反推出来的质量系数是98%,并不是100%。我猜测的原因是:用户既然选择了以JPG格式保存,多多少少还是贪图JPG格式的有损压缩带来的较小文件长度,但选质量12说明用户还是想要高质量,所以折中选了98%,与全1量化表的100%在质量上差距不是很大,但文件长度能减小不少。
  3. 在教程十九的表3中,除小米、酷派外没有质量系数低于90%的,基本上与前述第1点吻合。

注意前面的数据是基于“人工”图像的,一个原因是因为CEP通常处理的书籍扫描图像本来就属于人工图像的范畴,另一个原始是我手上的无损自然图像(尼康RAW格式照片)太大了,用起来不太方便,不过方法应该没有问题,所以结论应该也差不离。如果真的想抱着严肃的态度对自然图像的JPEG压缩质量进行研究,我觉得可以采用下列步骤:

  1. 用单反的RAW格式(注意某些品牌如佳能的RAW格式可选有损、无损,所以在开始前需人工检查相机内部设置,选择无损RAW),对人像、建筑、树木等典型自然图像场景进行拍摄。
  2. CEP是支持RAW格式的,所以可以仿照前面的步骤,在排除色度缩水、编码优化的前提下,把RAW格式按照不同的质量系数转存为JPG,然后逐一与原始RAW格式进行比较。当然为了加快处理速度,也可以把RAW格式转存为无损压缩的PNG文件。
  3. 如果真的有瘾,还可以组合质量系数、色度缩水倍数生成各种JPG,然后与原始RAW格式或从RAW生成的PNG进行比较。

这样的任务谁有兴趣谁去做,我就不玩了。 不过还可以继续看一下Photoshop的质量系数对JPG文件长度与质量的影响(注意Photoshop采用的量化表与CEP所用的IJG量化表是不一样的),操作步骤:

  1. 启动Adobe Photoshop CC 2015,打开教程十八中的示例PNG文件。
  2. 点击“文件->另存为”菜单,或按Ctrl+Shift+S键,将此PNG文件另存为JPG文件,文件名是在“JPEG选项”中选的“品质”(质量)数,从0开始,直到最高的12。注意“格式选项”选“基线(“标准”)”,以消除优化编码对文件长度的影响。
  3. 转存出13个文件后,在CEP里分别与教程十八中的示例PNG文件进行比较,结果如表5所示。

表5

文件 文件长度 最大值 平均值 标准差
0.jpg 124,000 230/189/255 9.77/8.82/11.66 14.63/12.35/17.76
1.jpg 127,551 206/185/255 9.87/8.09/11.19 14.17/12.21/17.28
2.jpg 136,763 195/164/255 8.10/7.25/9.69 13.58/10.97/16.24
3.jpg 146,030 215/129/255 6.96/5.86/8.34 12.31/9.07/14.65
4.jpg 155,781 183/112/255 6.32/5.05/7.84 11.77/8.38/13.90
5.jpg 168,437 171/104/255 6.31/5.13/7.61 11.83/7.86/14.11
6.jpg 182,364 164/86/255 5.44/4.16/6.73 11.45/6.95/13.67
7.jpg 193,079 115/78/195 4.18/3.15/4.55 5.54/4.92/7.55
8.jpg 225,304 83/51/103 3.47/2.91/4.50 4.35/3.51/5.90
9.jpg 254,497 57/32/73 2.28/1.86/2.89 2.82/2.17/3.84
10.jpg 300,190 29/20/38 2.03/1.50/2.60 2.24/1.63/2.80
11.jpg 362,455 16/10/22 1.45/1.03/1.84 1.48/1.05/1.79
12.jpg 461,321 6/4/8 0.87/0.57/1.11 0.79/0.58/0.91

表5数据用Excel生成统计图,如图5、图6、图7、图8所示,图中的横轴均为Photoshop中的JPG质量。

技术分享
图5

技术分享
图6

技术分享
图7

技术分享
图8

结合表5、图5~8,可以看出:

  1. 在PS中当质量系数低于8时,与原图的误差统计量随质量系数降低而增加的趋势很明显。低于6时对质量就不必太在意了。而从教程十九表1可知,PS的质量系数8大致相当于IJG的质量系数88%,与我对表4的解读中说的“质量系数90%”基本吻合。
  2. 质量系数不低于7时,文件长度随质量系数降低而降得较快,低于7时降得相对慢一点。
  3. 所以,如果想追求质量,建议在PS中存为JPEG时质量不要低于8。在PS中也是把12~10定义为“最佳”,9~8定义为“高”,7~5定义为“中”。

前面说的操作,基本上可以回答“有损了多少”的问题,下面则说明如何用“图像比较”功能解决“有损在哪里”的问题。

在教程十八中,我曾说与该教程中的图2相比,色度没有缩水的图3差距不明显,而色度缩过水的图4则差距明显。 下面就按如下步骤找出我所说的差距究竟在哪里:

  1. 把教程十八的图2、图3、图4全部右键另存下来。
  2. 进入CEP的“图像比较”界面,“源文件1”选从“图2”中存出来的文件,“源文件2”选从“图3”中存出来的文件,点击“差异图像”按钮,输入文件名“1.png”,CEP就会把两个图像的差异保存成无损压缩的PNG文件。
  3. “源文件1”保持从“图2”中存出来的文件不变,“源文件2”选从“图4”中存出来的文件,点击“差异图像”按钮,输入文件名“2.png”,CEP就会把两个图像的差异保存成无损压缩的PNG文件 ;点击“全图差异列表”,输入文件名“2.csv”,就会把差异保存为CSV文件,可以在Excel或其它软件中做分析。

现在可以用CEP分别打开上面保存的1.png、2.png,看看究竟有损在哪里了。注意在打开每个图像前先点CEP的“恢复”按钮,重置图像处理参数。

先打开1.png,看到的就是一片黑,说明两个图像之间的差异实在是太小了,肉眼根本看不出来。在“曲线”里把曲线拉成直角(图5),效果就比较明显了(图6)。

技术分享
图5

技术分享
图6

从图6看:

  1. 差异点都在图像颜色发生突变的地方,即教程十八中说的高频部分,而变化舒缓的低频(纯色区)无差异。而且图6中的误差完全无规则,看起来更像是随机噪声,说明只有最高频的部分被圆整掉。
  2. 由于JPEG压缩是针对8×8的像素块(参见教程十八中说的JPEG压缩过程),因此图6中的误差可以看出8×8像素块的边界。

然后打开2.png,这次肉眼都能看出差异了,见图7,然后在CEP的“曲线”中点“原画面发暗”,效果见图8。

技术分享
图7

技术分享
图8

从图7、图8看,由于色度进行了双向缩水,因此在颜色变化剧烈的地方差异比较明显。尤其是在圆圈部分,由于双向压缩后再插值放大,出现了条纹现象。

如果有兴趣,还可以把差异列表导入其它软件做进一步分析。图9、图10就是把前述操作中生成的2.csv文件导入Grapher软件生成的三维分布图与等高线图(注意图10中Y轴与原始图像相比是反的),我个人认为直观性不如图7、图8,不过貌似国内写论文的人更喜欢玩这些噱头?

技术分享
图9

技术分享
图10

到此,下次如果再有人问“究竟有损还是无损?无损在哪里?”的时候,各位知道该怎么回答了吧?

 

ComicEnhancerPro 系列教程二十:用“文件比较”看有损、无损