OpenCV学习(二):imread,cvtColor,imshow,imwrite的使用

时间:2023-02-04 19:02:12

上一篇介绍了OpenCV环境搭建,具体地址在这里,OpenCV环境搭建(一),这一篇打算介绍下那个测试程序里面几个函数的使用,只用当我们知道函数具体用法,才能方便后续的学习。

(小小的说下,上篇我用的OpenCV是3.0的,我后来还是改成3.3的,只要懂了环境搭建的过程,搭建还是很快的。)

先来放张本篇文章的测试图片


OpenCV学习(二):imread,cvtColor,imshow,imwrite的使用


imread

用于读取一个图片,并转换成一个Mat对象,它有两个参数,查看官方文档,该函数的定义

Mat imread( const String& filename, int flags = IMREAD_COLOR );

它有两个参数,第一个参数表示要加载的图片,我一般使用的时候是用绝对路径表示图片的路径。

该参数可以接收的图片类型为:

  • Windows位图 - .bmp, .dib
  • JPEG文件 - .jpeg, .jpg, *.jpe
  • JPEG 2000文件- *.jp2
  • PNG图片 - *.png
  • 便携文件格式- .pbm, .pgm, *.ppm
  • Sun rasters光栅文件 - .sr, .ras
  • TIFF 文件 - .tiff, .tif

第二个参数表示要加载的图片类型,该参数自带一个缺省值,我们在使用时, 可以只用传入第一个参数,第二个参数查看文档缺省值为1,也就是默认将原图作为BGR图像加载进来,并且跳转到函数定义中,该函数可以加载的类型都封装到一个enum类型中,以下几种类型都是可以直接加载的:

OpenCV学习(二):imread,cvtColor,imshow,imwrite的使用

总体来说该函数可以加载大概三种类型:
< a >. IMREAD_UNCHANGED < 0 表示加载原图,不做任何改变
< b >. IMREAD_GRAYSCALE = 0 表示把原图作为灰度图像加载进来
< c >. IMREAD_COLOR > 0 表示把原图作为BGR图像加载进来

补充:Mat函数

Mat即矩阵(Matrix)的缩写,用于保存图像以及其他矩阵数据的数据结构,Mat数据结构主要包含2部分:Header和Pointer。Header中主要包含矩阵的大小,存储方式,存储地址等信息;Pointer中存储指向像素值的指针。我们在读取图片的时候就是将图片定义为Mat类型。具体的可以看这里,也推荐下这篇,都是挺好的,这里就不赘述了。

eg:

Mat inMat = imread("1.png");  

这里为了简单点,直接将图片和源文件放在同一个目录下。该句话读取了1.png的图片,并将其载入到Mat类型的inMat中。没有传第二个参数,直接使用了缺省值1。


namedWindow

图片读取到了,接下来就需要创建一个窗口,用来作为图像显示的地方,如果具有相同名称的窗口已经存在,则函数不做任何事情。窗口的创建可以使用namedWindow 来实现,查看文档该,函数的定义如下:

void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);

创建一个窗口,由OpenCV自动创建和销毁,无需我们手动销毁,该函数有两个参数,第一个为窗口的名称,第二个窗口的标识,通过查看源码的定义,可以知道可以传的参数为下面的这几种:

OpenCV学习(二):imread,cvtColor,imshow,imwrite的使用

一般使用的时候默认为WINDOW_AUTOSIZE,会自动根据图像大小,显示窗口大小,不能人为改变窗口大小。这个参数是缺省的,即我们传的时候,默认就是这个参数。还有一种经常会使用到的是WINDOW_NORMAL,跟QT集成的时候会使用,允许修改窗口大小。如果想支持OpenGl,可以填这个参数WINDOW_OPENGL,使用它就会支持OpenGl。

我们可以调用destroyWindow()或者destroyAllWindows()函数来关闭窗口,并取消之前分配的与窗口相关的所有内存空间。但话是这样说,其实对于代码量不大的简单小程序来说,我们完全没有必要手动调用上述的destroyWindow()或者destroyAllWindows()函数,因为在退出时,所有的资源和应用程序的窗口会被操作系统会自动关闭。


imshow

根据窗口名称显示图像到指定的窗口上去,函数原型

void imshow(const String& winname, InputArray mat);
  • 参数一:要显示的窗口名字
  • 参数二:InputArray 类型的mat,填需要显示的图像。

一般来说,我们只需要将InputArray当作简单的mat就好了。

详细可以看这篇文章写得挺好的,图像的载入,显示和输出 一站式完全解析

imwrite

保存图像文件到指定目录路径,查看源码定义:

bool imwrite( const String& filename, InputArray img,
const std::vector<int>& params = std::vector<int>());
  • 第一个参数,const string&类型的filename,填需要写入的文件名就行了,带上后缀,比如,“123.jpg”这样。
  • 第二个参数,InputArray类型的img,一般填一个Mat类型的图像数据就行了。
  • 第三个参数,const vector< int >&类型的params,表示为特定格式保存的参数编码,它有默认值vector< int >(),所以一般情况下不需要填写。

注意:
< a >只有8位、16位的PNG、JPG、Tiff文件格式而且是单通道或者三通道的BGR的图像才可以通过这种方式保存
< b >保存PNG格式的时候可以保存透明通道的图片
< c > 可以指定压缩参数


cvtColor

把图像从一个彩色空间转换到另外一个色彩空间,查看源码定义:

void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );

参数一:要转换的源图像
参数二:转换后的图像
参数三:表示转换目标的彩色空间
参数四:默认值,目标图像的通道数,如果设置为0,则和源图像的通道数以及代码有关。


综合案例

通过前面的一系列详细解释,已经基本知道怎么使用这些函数了,对于基本的图像读取,显示和写入已经基本了解了,接下来就提供一个例子,入门使用

#include <iostream> 
#include <opencv2/opencv.hpp>
#include <math.h>

using namespace std;
using namespace cv;

void test();
void test2();

int main()
{

cout << "图像处理开始啦" << endl;

test2();
//test();
// 不让窗口关闭
waitKey();
}

/*
图像加载,修改,保存
*/

void test2() {
//参数一:要加载的图像路径
//参数二:加载的图像是什么类型
//返回值:为一个MAT类型
Mat inMat = imread("1.png");
if (inMat.empty()) {
cout << "图像加载失败啦" << endl;
return;
}

//参数一:创建一个OpenCV窗口,由OpenCV自动创建和销毁,无需我们手动销毁,参数意思是窗口名称
//参数二:
namedWindow("<1>这是一个窗口", WINDOW_AUTOSIZE);
//参数一:根据窗口名称显示图像到指定窗口,窗口名称
//参数二:带有指定图像的Mat对象
imshow("<1>这是一个窗口", inMat);

Mat outMat;
cvtColor(inMat, outMat, CV_BGR2HLS);

namedWindow("<2>cvtColor转换之后的窗口");
imshow("<2>cvtColor转换之后的窗口", outMat);

//保存图像到本地
imwrite("test.tiff", outMat);
}

/*

测试环境是否搭建好了

*/

void test() {

// 读入一张图片
Mat img = imread("D:\\15.jpg");
// 创建一个名为 "test"窗口
namedWindow("test");
// 在窗口中显示 test
imshow("test", img);

}

运行结果:

读取的图像:

OpenCV学习(二):imread,cvtColor,imshow,imwrite的使用

通过CV_BGR2HLS转换之后的图像:

OpenCV学习(二):imread,cvtColor,imshow,imwrite的使用

end