近日在用 opencv 做一些图像处理的操作时,需要对一些高分辨率的图像进行保存。比如,在操作一个容量为 230M 的图像后,并对该图像保存为 JPG 格式后,发现图像容量变为 80M 了!针对这个问题,忙了大半天,到处翻阅资料,终于知道为什么了。
先举个例子说明自己遇到的问题,为了看出效果,我特意用了一个高分辨率的图片做实验。
比如我有如下的一个 233M 的图片
经过下面的程序读进内存,再次保存后,图片容量就急剧变小了!
- #include<opencv2\opencv.hpp>
- #include<opencv2\highgui\highgui.hpp>
- using namespace std;
- using namespace cv;
- int main(int argc, char** argv)
- {
- Mat img = imread("src1.jpg");
- imwrite("test.jpg", img);
- return 0;
- }
保存后的图片,只剩下 126M 了!怎么回事!我什么都没做啊,图片大小怎么就大大缩水了呢?
通过翻阅一些资料才知道,原来是图片格式惹得祸。其实有些图片格式是自带压缩的,比如 jpg 格式,而 bmp 格式的图片是不带任何压缩,这就是每种图片的特点,如果对这些知识点不清楚的话,很容易踩坑!平时我们操作的图像大小大多数都以 KB 为单位,所以经过一番 "隐形压缩" 后我们很难发现图片大小变小了,但是,当我们操作大图的时候,这种压缩效果一下子就看出来了。
那么如果我们在使用 imwrite 保存图片时想提高保存图片的质量,该如何操作?
要改变保存的图片的质量,关键在于 imwrite 函数的第三个参数。
先看 imwrite 的声明
- CV_EXPORTS_W bool imwrite( const String& filename, InputArray img, const std::vector<int>& params = std::vector<int>());
第三个参数说明:const std::vector
opencv 的 imwrite 默认存储的 jpg 图片质量为 95,如果想进一步提高保存图片的质量,可以这么写
- #include<opencv2\opencv.hpp>
- #include<opencv2\highgui\highgui.hpp>
- using namespace std;
- using namespace cv;
- int main(int argc, char** argv)
- {
- Mat img = imread("src1.jpg");
- vector<int> compression_params;
- compression_params.push_back(CV_IMWRITE_JPEG_QUALITY); //选择jpeg
- compression_params.push_back(100); //在这个填入你要的图片质量
- imwrite("test2.jpg", img, compression_params);
- return 0;
- }
可以看出,经过参数调整后,jpg 格式保存的图片的大小有了很大的提升。
但是无论如何,以 jpg 格式保存图片还是不能百分百保存原图像的!
但是即使我们把图片质量写成 100,图片质量跟原图还是右一定压缩的,比如原图 233M,读入再保存为 jpg 格式容量就变为 229M。
那当我们不断读入图片,又不断存储图片为 jpg 格式,图片的质量就会不断降低!
所以有以下总结:
第一,opencv 的存储图片函数 imwrite 是可以通过第三个函数参数来调整保存图片的压缩比的,比如保存图片为 jpg 格式,我们如果我们写成
第二,jpg 格式的图片读进内存,如果再保存为 jpg 格式后,容量会被压缩的,这是 jpg 格式的特性,怎么调整压缩比都避免不了失真(损失图片质量)。
如果操作的而是 png 格式的图像,我们同样可以调整其保存的质量。
- #include<opencv2\opencv.hpp>
- #include<opencv2\highgui\highgui.hpp>
- using namespace std;
- using namespace cv;
- int main(int argc, char** argv)
- {
- Mat img = imread("src1.jpg");
- vector<int> compression_params;
- compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION); //PNG格式图片的压缩级别
- compression_params.push_back(9); //这里设置保存的图像质量级别
- imwrite("test3.png", img,compression_params);
- return 0;
- }
那如何不损失图片质量地保存图片,那就得将图片保存为其他格式的图片了。现在,就简单介绍一下我最常用的图片格式以及他们的特点:
位图(外语简称:BMP、外语全称:BitMaP)BMP 是一种与硬件设备无关的图像文件格式,使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP 文件所占用的空间很大。
联合照片专家组(外语简称 JPEG 外语全称:Joint Photographic Expert Group)JPEG 也是最常见的一种图像格式,它是由联合照片专家组(外语全称:Joint Photographic Experts Group),文件后辍名为 ".jpg" 或 ".jpeg",是最常用的图像文件格式,由一个软件开发联合会组织制定,是一种有损压缩格式,能够将图像压缩在很小的储存空间,图像中重复或不重要的资料会被丢失,因此容易造成图像数据的损伤。尤其是使用过高的压缩比例,将使最终解压缩后恢复的图像质量明显降低,如果追求高品质图像,不宜采用过高压缩比例。但是 JPEG 压缩技术十分先进,它用有损压缩方式去除冗余的图像数据,在获得极高的压缩率的同时能展现十分丰富生动的图像,换句话说,就是可以用最少的磁盘空间得到较好的图像品质。而且 JPEG 是一种很灵活的格式,具有调节图像质量的功能,允许用不同的压缩比例对文件进行压缩,支持多种压缩级别,压缩比率通常在 10:1 到 40:1 之间,压缩比越大,品质就越低;相反地,压缩比越小,品质就越好。
便携式网络图形(外语简称 PNG、外语全称:Portable Network Graphics),是网上接受的最新图像文件格式。PNG 能够提供长度比 GIF 小 30% 的无损压缩图像文件。它同时提供 24 位和 48 位真彩色图像支持以及其他诸多技术性支持。由于 PNG 非常新,所以并不是所有的程序都可以用它来存储图像文件,但 Photoshop 可以处理 PNG 图像文件,也可以用 PNG 图像文件格式存储。
来源: http://www.cnblogs.com/skyfsm/p/7136709.html