近日在用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&类型的params,表示为特定格式保存的参数编码,它有默认值std::vector(),所以一般情况下不需要填写。如果更改的话,对于不同的图片格式,其对应的值不同功能不同,如下:

  • 对于JPEG格式的图片,这个参数表示从0-100的图片质量(CV_IMWRITE_JPEG_QUALITY),默认值是95.

  • 对于PNG格式的图片,这个参数表示压缩级别(CV_IMWRITE_PNG_COMPRESSION)从0-9.较高的值意味着更小的尺寸和更长的压缩时间而默认值是3.

  • 对于PPM,PGM或PBM格式的图片,这个参数表示一个二进制格式标志(CV_IMWRITE_PXM_BINARY),取值为0或1,而默认值为1.

调整jpg图像格式的保存质量

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图像格式的保存质量

如果操作的而是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格式(无压缩)

位图(外语简称:BMP、外语全称:BitMaP)BMP是一种与硬件设备无关的图像文件格式,使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。

JPEG格式(有损压缩)

联合照片专家组(外语简称JPEG外语全称:Joint Photographic Expert Group)JPEG也是最常见的一种图像格式,它是由联合照片专家组(外语全称:Joint Photographic Experts Group),文件后辍名为".jpg"或".jpeg",是最常用的图像文件格式,由一个软件开发联合会组织制定,是一种有损压缩格式,能够将图像压缩在很小的储存空间,图像中重复或不重要的资料会被丢失,因此容易造成图像数据的损伤。尤其是使用过高的压缩比例,将使最终解压缩后恢复的图像质量明显降低,如果追求高品质图像,不宜采用过高压缩比例。但是JPEG压缩技术十分先进,它用有损压缩方式去除冗余的图像数据,在获得极高的压缩率的同时能展现十分丰富生动的图像,换句话说,就是可以用最少的磁盘空间得到较好的图像品质。而且JPEG是一种很灵活的格式,具有调节图像质量的功能,允许用不同的压缩比例对文件进行压缩,支持多种压缩级别,压缩比率通常在10:1到40:1之间,压缩比越大,品质就越低;相反地,压缩比越小,品质就越好。

PNG格式(无损压缩)

便携式网络图形(外语简称PNG、外语全称:Portable Network Graphics),是网上接受的最新图像文件格式。PNG能够提供长度比GIF小30%的无损压缩图像文件。它同时提供24位和48位真彩色图像支持以及其他诸多技术性支持。由于PNG非常新,所以并不是所有的程序都可以用它来存储图像文件,但Photoshop可以处理PNG图像文件,也可以用PNG图像文件格式存储。

OpenCV探索之路(十八):使用imwrite调整保存的图片质量的更多相关文章

  1. OpenCV探索之路(八):重映射与仿射变换

    重映射 重映射就是把一幅图像中某个位置的像素放置到另一个图片中指定位置的过程. 用一个数学公式来表示就是: 其中的 f 就是映射方式,也就说,像素点在另一个图像中的位置是由 f 来计算的. 在Open ...

  2. Opencv笔记(十八)——轮廓的更多函数及其层次结构

    凸缺陷 前面我们已经学习了轮廓的凸包,对象上的任何凹陷都被成为凸缺陷.OpenCV 中有一个函数 cv.convexityDefect() 可以帮助我们找到凸缺陷.函数调用如下: hull = cv2 ...

  3. 第十八篇、keychain保存UUID(保持唯一性,应用卸载,下载安装也不变)和获取IP地址

    .h #import <Foundation/Foundation.h> #import <Security/Security.h> /**使用**/ //-(void) se ...

  4. OpenCV探索之路(二十四)图像拼接和图像融合技术

    图像拼接在实际的应用场景很广,比如无人机航拍,遥感图像等等,图像拼接是进一步做图像理解基础步骤,拼接效果的好坏直接影响接下来的工作,所以一个好的图像拼接算法非常重要. 再举一个身边的例子吧,你用你的手 ...

  5. 【OpenCV新手教程之十八】OpenCV仿射变换 &amp; SURF特征点描写叙述合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/33320997 作者:毛星云(浅墨)  ...

  6. 命令模式 Command 行为型 设计模式(十八)

    命令模式(Command) 请分析上图中这条命令的涉及到的角色以及执行过程,一种可能的理解方式是这样子的: 涉及角色为:大狗子和大狗子他妈 过程为:大狗子他妈角色 调用 大狗子的“回家吃饭”方法 引子 ...

  7. 最全的MySQL基础【燕十八传世】

    1.课前准备! 开启mysql服务:1).配置环境变量;2).net start mysql 将该sql文件导入到你的数据库中,以下所有操作都是基于该数据库表操作的!!! [此笔记是本人看着视频加上自 ...

  8. NeHe OpenGL教程 第四十八课:轨迹球

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  9. Python之路【第十八篇】:Web框架们

    Python之路[第十八篇]:Web框架们   Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Pytho ...

随机推荐

  1. 小程序的1024KB

    1024kb 只是一个目前编译后代码可上传最大限制,至于后期会不会更改,不得而知.个人只是想借 1024kb 来和大家一起交流一下,如何在限制下,挥舞大刀- 微信官方回答了,为什么有 1024kb 的 ...

  2. 关于DB2死锁处理

    昨天在修改字段类型的时候引起了死锁,我一般会使用REORG命令处理,在控制中心下 只需要执行 REORG TABLE TABLENAME  命令就可以, 但是在 RazorSQL 下执行此命令会报缺失 ...

  3. 开涛spring3(6.3) - AOP 之 6.3 基于Schema的AOP

    6.3  基于Schema的AOP 基于Schema的AOP从Spring2.0之后通过“aop”命名空间来定义切面.切入点及声明通知. 在Spring配置文件中,所以AOP相关定义必须放在<a ...

  4. matlab错误:Subscript indices must either be real positive integers or logicals.

    matlab错误:Subscript indices must either be real positive integers or logicals. 中文解释:下标索引必须是正整数类型或者逻辑类 ...

  5. 东正王增涛浅析OA信息化整合平台系统在企业中的应用价值

    王增涛说OA信息化整合平台系统作为企业管理中最基础的管理软件,已在企业成长道路上存在多年,它的应用开启了智能移动办公的先河,也让企业的办公流程管理更加的便捷.高效.流畅.省时.省力,它的使用不但让企业 ...

  6. VR全景智慧城市--2017年VR项目加盟将是一个机遇

    全景智慧城市项目是河南艺境空间文化传播有限公司自主开发的国内第一家商业全景平台, 旨在构建全景城市,实现智慧生活,让人们随时随地身临其境拥有全世界,享受快捷.真实.趣味.优质生活. 以VR虚拟现实技术 ...

  7. Java 9 揭秘(1.Java入门介绍)

    文 by / 林本托 在第一部分中,主要讲解如下内容: JDK 9 包含了哪些内容 运行代码的系统要求 如何安装 NetBeans 1 JDK 介绍 JDK 9是Java开发工具包的第九个主要版本,计 ...

  8. Redis 小白指南(四)- 数据的持久化保存(草稿)

    Redis 小白指南(四)- 数据的持久化保存 简介 因为 redis 将数据保存在内存中,很容易诱发的一个问题就是,程序崩溃或服务器重启等情况如何保证数据的正常存储. 当我们以 redis 作为主数 ...

  9. 移动端H5通用表单验证插件

    将表单验证的通用部分提炼出来,做成一个简易插件,方便调用. 已将源码放到GitHub上,名字叫zValidate. 手机可扫描下图查看示例,PC端可点击此处查看: 一.原理 1)需要引入zepto.j ...

  10. spring.handlers、spring.schemas、spring.tooling被覆盖的三种解决方式

    在用到spring时,本地IDE里面跑的很正常,但是打jar包后在集群上运行时报错. 查找资料后确定了问题的根源,由于在依赖中调用了spring的许多包,每个包都有自己的spring.schemas文 ...