笔者的学习资料参考为《OpenCV 3 Computer Vison Application Programming Cookbook,Third Edition》,所用OpenCV库版本为4.5.3,所用IDE为MS Visual Studio,所用语言为C++。
OpenCV是一个开源的计算机视觉程序库,可以在Windows、Linux等多平台下运行。OpenCV库分多个模块,我们可以在头文件opencv.hpp中找到这些模块对应的头文件。OpenCV整体分为两类,包含核心库( Core library)和若干可选模块(optional modules)。
core.hpp包含OpenCV库的核心功能。
// Then the list of defines is checked to include the correct headers
// Core library is always included --> without no OpenCV functionality available
#include "opencv2/core.hpp"
OpenCV也提供了若干可选模块,这里列出部分模块。比如imgproc模块包含主要的图像处理函数,highgui模块提供了读写图像和视频的函数以及一些用户交互函数等。在我们使用这些模块前,需要将对应头文件包含进去,当然在4.5.3版本中可以直接包含opencv.hpp,因此之后的模块学习不再单独列出。
#ifdef HAVE_OPENCV_IMGPROC
#include "opencv2/imgproc.hpp"
#endif
#ifdef HAVE_OPENCV_HIGHGUI
#include "opencv2/highgui.hpp"
#endif
最后只得注意的是,若在程序开头加上cv命名空间进行声明,则后续代码如cv::Mat可以直接写成Mat。
using namespace cv;
首先需要创建一个变量代表图像,在OpenCV中使用cv::Mat类创建对象。
cv::Mat image;//创建一个空图像
此时创建的图像尺寸为0×0 。在创建对象时可以指定初始尺寸大小。这里有两种方式
//创建一个未初始化的240行×320列的灰度图像
cv::Mat image1(240, 320, CV_8U);
//创建一个未初始化的320行×240列的彩色图像
cv::Mat image2(cv::Size(320,240),CV_8UC3);
注意:第三个参数的含义是每个矩阵元素的类型。CV_8U表示每个像素对应1字节(灰度图像),U表示无符号(S表示有符号),如果想要初始化灰度图像,需要调用cv::Scalar。三通道彩色图像表示为CV_8UC3,如果想要对三通道初始化,也需要调用cv::Scalar。
//创建一个红色图像
//通道次序为BGR
cv::Mat image2(240, 320, CV_8UC3, cv::Scalar(0, 0, 255));
//创建一个灰度100的图像
cv::Mat image1(240, 320, CV_8U, cv::Scalar(100));
我们可以通过访问cv::Mat的size属性来查看图像的尺寸。
cout << "This image is " << image.rows << " x " << image.cols << endl;
调用imread函数,从指定路径读入一个图像(若路径指定不完整,路径为默认目录),解码并分配内存。
image = cv::imread("1.bmp");//读取输入图像
在读取图像时,可以同时进行色彩转换,以适用于不同的计算机视觉算法。
//读取图像文件并将其转换为灰度图像 image = cv::imread("1.bmp", cv::IMREAD_GRAYSCALE); //读取图像文件并将其转换为三通道彩色图像 image = cv::imread("1.bmp", cv::IMREAD_COLOR);
注意,灰度图像由unsigned char构成,OpenCV中用常量CV_8U表示;三通道彩色图像中每个像素为3字节,OpenCV中用CV_8UC3表示。
在显示图像之前,我们可以先定义一个显示窗口。注意,我们可以用这个窗口显示不同图像,也可以用不同名称创建多个窗口。
//定义窗口
cv::namedWindow("Original Image");
然后使用Original Image窗口显示图像。
//显示图像
cv::imshow("Original Image", image);
调用destroyAllWindows()销毁我们创建的所有窗口。如果想销毁任意指定窗口,应该使用函数 destroyWindow(),参数是确切的窗口名。
cv::destroyAllWindows();//关闭所有窗口
cv::destroyWindow("Original Image");//关闭Original Image窗口
为了避免在main函数结束时关闭窗口,可以调用waitKey(0),待用户键入数值后再结束程序。
cv::waitKey(0);//0表示永远等待按键
//键入的正数表示等待的毫秒数
使用imwrite函数可以把处理过的图像储存在磁盘的指定路径(若路径指定不完整,路径为默认目录)。该函数返回值类型为布尔类型,成功将图像写入或保存到本地文件系统后返回布尔值 true,否则返回False。注意,保存时会根据文件名后缀决定使用哪种编码方式。
cv::imwrite("1.bmp",image);//保存image