首先,JPEG是有损压缩,且这种压缩可迭代,(肉眼看不出差别,但是图像的大小有差别)
import cv2
img1 = cv2.imread('imgresize1.jpeg')
img2 = cv2.resize(img1,(256,256))
cv2.imwrite("imgresize2.jpeg",img2)
如果我用这种方式保存图像的话,默认的压缩参数是95,
原图是1460KB,一次压缩变成46KB,再次变成15KB,即使后两者的图像分辨率都是256*256
正确的操作是把最后一句变成:
cv2.imwrite("imgresize3.jpeg",img2,[int(cv2.IMWRITE_JPEG_QUALITY), 100])
------------------------------------------------------------------------
其次,JPEG的压缩方式,是将图像分成许多个8*8的小block,对每一个block做DCT离散余弦变换,丢失大量高频信息。
(低频部分集中在每个8*8块的左上角,高频部分在右下角,所谓JPEG的有损压缩,损的是量化过程中的高频部分)
因此,在SRGAN 生成的过程中,观察到许多细小的artifact,如下图:
去除这种artifact的方式可以参考ARCNN(Deep Convolution Networks for Compression Artifacts Reduction, ICCV2015)
建议是要将artifact removal和super resolution分开做。
--------------------------------------------------------------------------------
最后,本着打破砂锅问到底的探究精神,cv2.resize()函数到底对图像做了什么?
参考了网上的很多教程,都是在讲如何使用,或者如果把图片放大怎么插值,但是我想知道的是,如果原图为256*256,resize成128*128,信息是如何损失的?
于是我去查了源码,https://github.com/opencv/opencv/blob/master/modules/imgproc/src/resize.cpp
3000多行,菜鸡如我当然看不懂...机缘巧合看到知乎手撕源码的大佬https://zhuanlan.zhihu.com/p/36736315
直接说结论:就是把几个点加权平均。
看最简单的情况下(例如把256*256resize成128*128):
if (cn == 1)
for( ; dx < w; ++dx )
{
int index = dx*2;
D[dx] = (T)((S[index] + S[index+1] + nextS[index] + nextS[index+1] + 2) >> 2);
}
做了个小测试,原图为46KB,缩小以后为14KB,约为1/4的关系(不知道这样理解对不对..)
其他参考链接:
https://blog.csdn.net/u013752202/article/details/78551592
https://www.zhihu.com/question/65058389