在使用opencv对图像进行处理时,图像的加载就是要走出的第一步。
1.图像的加载之imread函数
图像的加载在opencv中由”imread”函数来实现,在imread函数中可以加载想要进行处理的图像,imread函数支持多种图像格式。
windows位图:bmp, dib
JPEG文件:jpeg, jpg, jpe
JPEG2000文件: jp2
PNG图片: png
便携文件格式: pbm, pgm, ppm
光栅文件: sr, ras
TIFF文件: tiff, tif.
imread()函数原型如下:
CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR );
其参数如下含义:
第一个参数:const String& filename是指图片的名称,如果图片不在工程目录下,则需要包含图片的路径,在输入路径时Windows环境下使用”\\”,而在Linux环境下使用”//”。同样在添加库文件时Windows环境下使用”\”如:”opencv\core\core.hpp”,而在Linux环境下使用”/”如”opencv2/core/core.hpp”,这是在使用opencv时Windows环境和Linux环境下的一点区别。
第二个参数: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.
};
根据其原型可以看出,flags是一个枚举类型。对各个参数简单解释一下:
IMREAD_UNCHANGED:已经废除,不再使用
IMREAD_GRAYSCALE=0:将加载的图像转换为单通道灰度图。
IMREAD_COLOR=1:函数默认值,将图像转化为三通道BGR彩色图像
IMREAD_ANYDEPTH=2:若载入图像深度为16位或32为就返回其对应深度,否则将图像转换为8位图像
IMREAD_ANYCOLOR=4:保持图像原格式,可以读取任意可能的彩色格式
IMREAD_LOAD_GDAL=8:使用文件格式驱动加载图像,在现阶段用处不多。
在使用flags时可能会同时使用多种flags,如果发生冲突,函数将自动采用较小数字值对应的加载方式。如:IMREAD_COLOR | IMREAD_ANYCOLOR,则imread()函数将自动载入IMREAD_COLOR所对应的3通道彩色图。如果要载入图像原本的彩色格式和深度,则可以使用: IMREAD_ANYCOLOR | IMREAD_ANYDEPTH。
也可以利用flags是int类型的变量输入其他值以达到加载特定图像格式的目的,但符合一下标准:
flags > 0:返回一个三通道的彩色图像
flags = 0: 返回灰度图像
flags < 0: 返回包含Alpha通道的图像。
图像在默认情况下不是从Alpha通道进来的,如果需要载入Alpha通道的话就取负值。
2.namedWindow函数
创建一个窗口,原型如下:
CV_EXPORTS_W void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);
第一个参数const String& winname:窗口名称
第二个参数int flags:窗口属性
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_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_KEEPRATIO:图像比例受到约束。
namedWindow()函数是通过指定的名字创建一个作为图像和进度条显示的窗口,如果有相同名称的窗口已经存在,则函数不会重复创建窗口,而是什么都不做。我们可以调用destroyWindows()或者destroyAllWindows()函数来关闭窗口并取消之前分配的与窗口相关的所有内存空间。
3.imshow()
显示指定窗口,其函数原型如下:
CV_EXPORTS_W void imshow(const String& winname, InputArray mat);
第一个参数const String& winname:窗口名称,如果使用了namedWindow()函数创建窗口,则名字必须一致,如果没有使用namedWindow()函数,则可指定任意符合命名规则的名字。
第二个参数InputArray mat:要输出的图像。
imshow()在用于指定的窗口显示图像时,如果窗口用WINDOW_ATTOSIZE创建,那么显示图像原始大小。佛则将图像进行缩放以适合窗口。而imshow()函数缩放图像取决与图像深度:
如果载入图像是8位无符号类型(8-bis unsigned),就现实图像原本样子。
如果图像是16位无符号类型(16-bist unsigned)或32位无整型(32-bit integer),便使用像素值除以256.也就是说将像素值范围在[0,255x266]之间的元素映射到(0,255]范围内。
如果载入图像是32位浮点型(32-bit floating-point),像素值要乘以255.也就是说像素值范围在[0,1]映射到[0,255].
4.imwrite()
将处理后的图像写入到相应的文件夹。其用法与imread()函数类似。原型如下:
CV_EXPORTS_W bool imwrite( const String& filename, InputArray img, const std::vector<int>& params = std::vector<int>());
可以看出imwrite()是一个BOOL型函数,档期写入成功返回TRUE,否则返回FALSE。
第一个参数const String& filename:保存图像的文件名,一定要包含文件的后缀,如”lena.bmp”
第二个参数const 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。
实例代码如下:
#include
#include
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat srcImage = imread("//home//keith//图片//星空.jpg", IMREAD_COLOR); //读取图像到srcImage,注意图像路径即后缀
namedWindow("Opencv图像读取-星空", WINDOW_AUTOSIZE); //创建一个名字为“Opencv图像读取-星空”的窗口,窗口属性为自适应
imshow("Opencv图像读取-星空", srcImage); //显示读入的图像,窗口名称与namedWindow中名字要一致
Mat srcImageGray; //创建一个Mat类型用于存储将读取到的彩色图像转换为灰度图之后的图像
cvtColor(srcImage, srcImageGray, CV_RGB2GRAY); //使用函数CV_RGB2GRAY将彩色图像转换为灰度图
namedWindow("星空灰度图", WINDOW_NORMAL);
imshow("星空灰度图",srcImageGray);
imwrite("星空灰度图.jpg",srcImageGray); //将转换的灰度图以.bmp格式存储,默认路径为工程目录下
waitKey(0);
return 0;
}
PS:代码格式又乱了。。。。