今天在使用cv::imwrite保存PNG图像的时候发现了一个有趣的现象:
保存128*128分辨率16位的图像,PNG图像压缩参数CV_IMWRITE_PNG_COMPRESSION设置为0,得到大小为32.2kB(33012字节),计算每一个像素的值为128*128*16/8/1024=32kB,算上文件头等信息是刚刚好的;
保存256*256分辨率16位的图像,PNG图像压缩参数CV_IMWRITE_PNG_COMPRESSION设置为0,得到大小为22.3kB(22934字节),计算每一个像素的值为256*256*16/8/1024=128kB,算上文件头等信息应该是128kB多一点。
选择的参数是一样的,图像容量应该变为4倍才是正常的,为什么反而变小了呢?还是得参看源代码。
查到了cv::imwriteFlags(连接),发现了下表:
Enumerator | |
---|---|
IMWRITE_JPEG_QUALITY | For JPEG, it can be a quality from 0 to 100 (the higher is the better). Default value is 95. |
IMWRITE_JPEG_PROGRESSIVE | Enable JPEG features, 0 or 1, default is False. |
IMWRITE_JPEG_OPTIMIZE | Enable JPEG features, 0 or 1, default is False. |
IMWRITE_JPEG_RST_INTERVAL | JPEG restart interval, 0 - 65535, default is 0 - no restart. |
IMWRITE_JPEG_LUMA_QUALITY | Separate luma quality level, 0 - 100, default is 0 - don't use. |
IMWRITE_JPEG_CHROMA_QUALITY | Separate chroma quality level, 0 - 100, default is 0 - don't use. |
IMWRITE_PNG_COMPRESSION | For PNG, it can be the compression level from 0 to 9. A higher value means a smaller size and longer compression time. Default value is 3. |
IMWRITE_PNG_STRATEGY | One of cv::ImwritePNGFlags, default is IMWRITE_PNG_STRATEGY_DEFAULT. |
IMWRITE_PNG_BILEVEL | Binary level PNG, 0 or 1, default is 0. |
IMWRITE_PXM_BINARY | For PPM, PGM, or PBM, it can be a binary format flag, 0 or 1. Default value is 1. |
IMWRITE_WEBP_QUALITY | For WEBP, it can be a quality from 1 to 100 (the higher is the better). By default (without any parameter) and for quality above 100 the lossless compression is used. |
Enumerator | |
---|---|
IMWRITE_PNG_STRATEGY_DEFAULT | |
IMWRITE_PNG_STRATEGY_FILTERED | |
IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY | |
IMWRITE_PNG_STRATEGY_RLE | |
IMWRITE_PNG_STRATEGY_FIXED |
还需要验证,继续查找资料,通过bing搜索,前面的几个链接里面找到了下表(地址):
vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(0); // 无压缩png.
compression_params.push_back(IMWRITE_PNG_STRATEGY);
compression_params.push_back(IMWRITE_PNG_STRATEGY_DEFAULT);
imwrite(depthName, depthMat, compression_params);
输出的图像为128kB(131608字节),符合预期。
到这里应该没什么问题了,图像体积变小了是因为①图像中含有大量0点,②cv::imwrite保存图像是自动选择了某种编码方式压缩体积。