【OpenCV开发】imread和imwrite的类型以及第三个参数关于图片压缩质量等

本片参考博客:http://blog.csdn.net/poem_qianmo/article/details/20537737
基于OpenCV3.0,与原博客有出入。

在OpenCV1.0时代,基于C语言借口而建立的图像存储格式IpIImage*,如果在退出时忘记release掉的话会造成内存泄漏。自OpenCV2.0开始,用Mat类型数据作为主打之后,OpenCV变得像Matlab那样需要很少的编程涵养。
图像的载入、显示和输出分别对应三个函数:imread(),namedWindow(),imshow().

1.imread函数
在OpenCV3.0官方文档中查到其原型为:CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR );  

**第一个参数const string&类型的filename,填需要载入的图片路径名,路径名为双“\”。在Windows操作系统下,OpenCV的imread函数支持如下类型的图像载入:
   Windows位图 - *.bmp, *.dib
JPEG文件 - *.jpeg, *.jpg, *.jpe JPEG 2000文件- *.jp2 PNG图片 - *.png 便携文件格式- *.pbm, *.pgm, *.ppm Sun rasters光栅文件 - *.sr, *.ras TIFF 文件 - *.tiff, *.tif

**第二个参数int类型的flags,为载入标识指定一个加载图像的颜色类型。其自带IMREAD_COLOR.所以在某些情况下我们可以直接将这个参数忽略,系统默认为其缺省值.我们发现这个枚举的定义是这样的:
enum ImreadModes {  
       IMREAD_UNCHANGED  = -1, //!< If set, return the loaded image as is (with alpha channel, otherwise it gets cropped).  
       IMREAD_GRAYSCALE  = 0,  //!< If set, always convert image to the single channel grayscale image.  
       IMREAD_COLOR      = 1,  //!< If set, always convert image to the 3 channel BGR color image.  
       IMREAD_ANYDEPTH   = 2,  //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.  
       IMREAD_ANYCOLOR   = 4,  //!< If set, the image is read in any possible color format.  
       IMREAD_LOAD_GDAL  = 8   //!< If set, use the gdal driver for loading the image.  
     };  


相应解释:

IMTEAD_UNCHANGED = -1:废置!
IMREAD_GRAYSCALE  = 0:设置此表示,将图像转化为单通道灰度图。
IMREAD_COLOR      = 1:将图像转化为三通道BGR彩色图像。
IMREAD_ANYDEPTH   = 2:若载入图像的深度为16或32位就返回对应深度的图像,否则将图像转换为8位图像
IMREAD_ANYCOLOR = 4:图像可被读取为任意可能的彩色格式
IMREAD_LOAD_GDAL = 8:使用文件格式驱动加载图像

**PS:如果输入有冲突的标志,将采用较小的数字值。比如:IMREAD_COLOR|IMTEAD_ANYCOLOR将载入3通道图。如果要载入最真实的图像选择IMREAD_ANYCOLOR|IMTEAD_ANYPTH。
因为flags是int类型的变量,如果我们不再这个枚举体中取值的话还可以:
flags > 0返回一个三通道的彩色图像。
flags = 0返回灰度图像。
flags < 0返回包含Alpha通道的加载的图像。

PS:输出的图像默认情况下不是载入Alpha通道进来的。如果我们需要载入Alpha通道的话就取负值。

2.namedWindow函数。
用于创建一个窗口。函数原型:
CV_EXPORTS_W void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);  


第一个参数:const string&类型的name, 即填呗用作窗口标识符的窗口名称。
第二个参数:int类型的flags,窗口大小的标识符,在库中的函数枚举如下:
enum { WINDOW_NORMAL     = 0x00000000, // the user can resize the window (no constraint) / also use to switch a fullscreen window to a normal size  
       WINDOW_AUTOSIZE   = 0x00000001, // the user cannot resize the window, the size is constrainted by the image displayed  
       WINDOW_OPENGL     = 0x00001000, // window with opengl support  
  
       WINDOW_FULLSCREEN = 1,          // change the window to fullscreen  
       WINDOW_FREERATIO  = 0x00000100, // the image expends as much as it can (no ratio constraint)  
       WINDOW_KEEPRATIO  = 0x00000000  // the ratio of the image is respected  
     };  



WINDOW_NORMAL:用户可以改变窗口的大小(没有限制),也可以将一个满屏的窗口转换成常用大小。
WINDOW_AUTOSIZE:窗口大小会自动调整以适应所显示的图像并且不能手动更改窗口大小。
WINDOW_OPENGL:创建支持OpenGL的窗口。
WINDOW_FULLSCREEN:将整个窗口充满屏幕
WINDOW_FREETATIO:图像将尽可能展开(没有比例约束)
WINDOW_KEEPTARIO:图像比例受到约束。

对于我们大多数人来讲前四个是最常用的格式。

namedWindow()函数是通过制定的名字创建一个作为图像和进度条的容器窗口。如果有相同名称的窗口已经存在,则函数不做任何事。
我们可以调用destroyWindow()或者destroyAllWindows()函数来关闭窗口并取消之前分配的与窗口相关的所有内存空间。


3.imshow函数
在指定窗口中显示图像,其函数原型为:
CV_EXPORTS_W void imshow(const String& winname, InputArray mat);  


第一个参数:const string&类型的name, 填写需要显示的窗口表示名称,与函数namedWindow()函数中命名的窗口标识一致
第二个参数:inputArray mat,填写需要显示的图像,即用imread读取的Mat类型的图像。
在mat.hpp中查询InputArray原型如下:
typedef const _InputArray& InputArray;  



imshow函数用于在指定的窗口中显示图像。如果窗口时用WINDOW_AUTOSIZE创建,那么显示图像原始大小。否则将图像进行缩放以适合窗口。而imshow函数缩放图像取决于图像的深度:
如果载入的图像是8位无符号类型(8-bit unsigned),就显示图像本来的样子。
如果图像是16位无符号类型(16-bit unsigned)或32位整型(32-bit integer),便用像素值除以256。也就是说值的范围是[0,255×256]映射到[0,255]。
如果图像是32位浮点型(32-bit floating-point),像素值便要乘以255。也就是说该值的范围是[0,1]映射到[0,255]。

针对以上三种函数,示例代码如下:
Mat imageTest = imread("F:\opencvProgram\TestImage\帆板迎浪而上.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);  
    namedWindow("帆板迎浪而上", WINDOW_NORMAL);  
    imshow("帆板迎浪而上", imageTest);  



4.imwrite函数

在OpenCV中其声明如下:

CV_EXPORTS_W bool imwrite( const String& filename, InputArray img, const std::vector<int>& params = std::vector<int>());  



第一个参数:const string&类型的filename,设置为需要写入的文件名就行了(包含后缀)。
第二个参数:InputArray类型的img,一般是一个Mat类型的图像数据。
第三个参数:const std::vector<int>&类型的params,表示为特定格式保存的参数编码,它有默认值std::vector<int>(),所以一般情况下不需要填写。如果更改的话,对于不同的图片格式,其对应的值不同功能不同,如下:

对于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.

imwrite函数用于将图像保存到指定的文件。图像格式是基于文件扩展名的,可保存的阔扎名和imread函数中可以读取的图像扩展名一样:
   Windows位图 - *.bmp, *.dib
JPEG文件 - *.jpeg, *.jpg, *.jpe JPEG 2000文件- *.jp2 PNG图片 - *.png 便携文件格式- *.pbm, *.pgm, *.ppm Sun rasters光栅文件 - *.sr, *.ras TIFF 文件 - *.tiff, *.tif

源代码(浅墨CSDN,博客开头已声明):
/*opencv中,输出图像到文件一般用imwrite函数*/  
/*函数声明如下:bool imwrite(const string& filename, 
InputArray img, const vector<int>& params=vector<int>())*/  
#include <vector>  
#include <iostream>  
#include <opencv2opencv.hpp>  
  
using namespace std;  
using namespace cv;  
  
void creatAlphaMat(Mat &mat)  
{  
    /*通过转到定义,Mat为一个重载的函数其原型为:*/  
    /*Mat(int rows, int cols, int type);*/  
  
    for (int i = 0; i < mat.rows; ++i)  
    {  
        for (int j = 0; j < mat.cols; ++j)  
        {  
            Vec4b&rgba = mat.at<Vec4b>(i, j);  
            rgba[0] = UCHAR_MAX; //unsigned char 的最大值  
            rgba[1] = saturate_cast<uchar>((float(mat.cols - j)) / ((float)mat.cols)*UCHAR_MAX);  
            rgba[2] = saturate_cast<uchar>((float(mat.rows - i)) / ((float)mat.rows)*UCHAR_MAX);  
            rgba[3] = saturate_cast<uchar>(0.5*(rgba[1] + rgba[2]));  
        }  
    }  
}  
  
int main(void)  
{  
    Mat mat(480, 640, CV_8UC4); //类型为8-bit unsigned integers(0..255),矩阵类型为四通道  
    creatAlphaMat(mat);  
  
    vector<int>compression_params;  
    compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION); //PNG格式图片的压缩级别  
    compression_params.push_back(9);  
  
    try  
    {  
        imwrite("透明Alpha值图.png", mat, compression_params);  
    }  
    catch (runtime_error& ex)  
    {  
        fprintf(stderr, "图像转换成PNG格式发生错误:%s
", ex.what());  
        return 1;  
    }  
  
    fprintf(stdout, "PNG图片文件的alpha数据保存完毕!
");  
  
    return 0;  
}  


原文地址:https://www.cnblogs.com/huty/p/8518035.html