OpenCV计算机视觉开发入门与实践<六>:OpenCV架构模块简介

OpenCV计算机视觉开发入门与实践<六>:OpenCV架构模块简介

1.OpenCV模块

OpenCV 现在已经发展得比较庞大了,针对不同的应用,它划分了不同的模块,每个模块专注于不同的功能。一个模块下面可能有类、 全局函数、枚举、全局变量等。所有全局函数或变量都在命名空间 cv 下。

这些模块有的经过多个版本的更新已经较为完善,包含较多的功能, 有的模块还在逐渐发展中,包含的功能相对较少。接下来按照文件夹的顺序(字母顺序)介绍模块的功能。

  • calib3d: 这个模块名称由 calibration(校准)和 3D 这两个单词的缩写组合而成的,通过名字可以知道,模块主要包含相机标定与立体视觉等功能,例如物体位姿估计、三维重建、 摄像头标定等。

  • core: 核心功能模块,主要包含 OpenCV 库的基础结构以及基本操作,例如 OpenCV 基本数据结构、绘图函数、数组操作相关函数、动态数据结构等。

  • dnn: 深度学习模块,这个模块是 OpenCV 4 版本的一个特色,其主要包括构建神经网络、加载序列化网络模型等。但是该模块目前仅适用于正向传递计算(测试网络),原则上不 支持反向计算(训练网络)。

  • features2d: 这个模块名称是由 features(特征)和 2D 这两个单词的缩写组合而成的,其功能主要为处理图像特征点,例如特征检测、描述与匹配等。

  • flann: 这个模块名称是 Fast Library for Approximate Nearest Neighbors (快速近似最近邻库)的缩写,这个模块是高维的近似近邻快速搜索算法库,主要包含快速近似最近邻搜索与聚类等。

  • highgui: 高层 GUI 图形用户界面,包含创建和操作显示图像的窗口、处理鼠标事件以及键 盘命令、提供图形交互可视化界面等。

  • imgcodecs: 图像文件读取与保存模块,主要用于图像文件读取与保存。

  • imgproc: 这个模块名称由 image(图像)和 process(处理)两个单词的缩写组合而成的,是重要的图像处理模块,主要包括图像滤波、几何变换、直斱图、特征检测与目标检测等。

  • ml: 机器学习模块,主要为统计分类、回归和数据聚类等。

  • objdetect: 目标检测模块,主要用于图像目标检测,例如检测 Haar 特征。

  • photo: 计算摄影模块,主要包含图像修复和去噪等。

  • stitching: 图像拼接模块,主要包含特征点寻找与匹配图像、估计旋转、自动校准、接缝 估计等图像拼接过程的相关内容。

  • video: 视频分析模块,主要包含运动估计、背景分离、对象跟踪等视频处理相关内容。

  • videoio: 视频输入输出模块,主要用于读取与写入视频或者图像序列。

通过对 OpenCV 4.5 模块构架的介绍,我们对 OpenCV 4.5 整体架构有了一定的了解。其实简单来说, OpenCV 就是将众多图像处理和视觉处理工具集成在一起的软件开发(Software Development Kit, SDK),其自身并不复杂,只要通过学习都可以轻松掌握其使用方式。

2.图像输入输出模块 imgcodecs

要处理图像,第一步就是把图像文件从磁盘上读取到内存,处理完毕后再保存到内存。所以我们先来看图像文件读取与保存模块 imgproc。 imgproc 提供了一系列全局函数用于读取或保存图像文件。

imgproc 模块中的函数都在 opencv2/imgcodecs.hpp 中声明。由于 opencv2\opencv.hpp 中已经包含 opencv2/imgcodecs.hpp, 因此程序中也可以只包含 opencv2\opencv.hpp,比如:

#include<opencv2\opencv.hpp>

因为 opencv.hpp 中有如下代码:

#ifdefHAVE_OPENCV_IMGCODECS#include"opencv2/imgcodecs.hpp"#endif
2.1 imread 读取图像文件

函数 imread 用于读取图像文件(或叫加载图像文件) 。该函数声明如下:

Mat cv::imread(constString&filename,intflags=IMREAD_COLOR);

其中参数 filename 表示要读取的图像文件名。 flags 表示读取模式, flags 可以从枚举cv::ImreadModes 中取值,默认取值是 IMREAD_COLOR,表示始终将图像转换为三通道 BGR 彩色图像。如果从指定文件加载图像成功,就返回 Mat 矩阵,如果无法读取图像(由于缺少文件、权限不正确、格式不受支持或无效),函数就返回空矩(Mat::data==NULL)。
imread 支持常见的图像格式,某些图像格式需要(免费提供的)第三方类库。 在 Windows 操作系统下, OpenCV 的 imread 函数支持如下类型的图像载入:

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

如果读取失败,通常可以用两种方式来判断:直接判断是否为 NULL,或者调用 Mat::empty()函数,比如:

Mat img;...//开始判断是否加载成功if(img.data==NULL)puts("load failed");//if (img.empty()) puts("load failed");

值得注意的是,函数 imread 根据内容而不是文件扩展名来确定图像的类型,比如我们把某个BMP 文件改为后缀名为.jpg, imread 依然能探测到这个文件是 BMP 图像文件。

另外, imread 的第一个参数一般是图像文件的绝对路径或相对路径。 对于绝对路径, imread除了不支持单右斜线形式(\) 外,其他斜线形式都支持,比如双右斜线形式(\)、双左斜线形式(//)、单左斜线形式(/)等。但通常相对路径更加方便点,只要把图像文件放在工程目录下即可。

#include<iostream>#include<opencv2\opencv.hpp>usingnamespacestd;usingnamespacecv;#pragmacomment(lib,"opencv_world450d.lib")//引用引入库intmain(intargc,char*argv[]){Mat img;//string imgpath = "d:\\我的图片\\p1.jpg"; //--1--双右斜线法,路径中含有中文//string imgpath = "d://test//p1.jpg"; //-- 2 --双左斜线法// string imgpath = "d:/test/p1.jpg"; //-- 3 --单左斜线法// string imgpath = "d:/test//test2\\test3//test4//p1.jpg";//-- 4 --以上三种混合法string imgpath="p1.jpg";////-- 5 --相对路径法, 放工程目录下//string imgpath = argv[1];//-- 6 --命令行参数法img=imread(imgpath,1);if(img.data==NULL)//或 img.empty()puts("load failed");elseimshow("img",img);waitKey(0);return0;}

对上面 6 种路径进行了测试,任何一种都是支持的,都可以成功读取并显示图片。较常用的是相对路径方式,也就是第 5 种。 如果在工程中运行程序,相对路径就是把图像文件放到工程目录下即可,如果是直接双击生成的可执行程序 test.exe,则要把图像文件和 test.exe 放在同一路径下。

2.2 imwrite 保存图片

函数 imwrite 可以用来输出图像到文件,其声明如下:

boolcv::imwrite(constString&filename,InputArray img,conststd::vector<int>&params=std::vector<int>());

其中参数 filename 表示需要写入的文件名,必须加上后缀,比如 123.png,注意要保存图片为哪种格式,就带什么后缀; img 表示 Mat 类型的图像数据,就是要保存到文件中的源图像数据; 参数 params 表示为特定格式保存的参数编码,它有一个默认值 std::vector< int >(),所以一般情况下不用写。

通常,使用此函数能保存8位单通道或三通道(具有BGR通道顺序)图像。16位无符号(CV_16U)图像可以保存为 PNG、 JPEG 2000 和 TIFF 格式。 32 位浮点(CV_32F)图像可以保存为 PFM、 TIFF、OpenEXR 和 Radiance HDR 格式; 三通道(CV_32FC3) TIFF 图像将使用 LogLuv 高动态范围编码(每像素 4 字节)保存。

另外, 使用此函数可以保存带有 alpha 通道的 PNG 图像。为此,创建 8
位(或 16 位) 4 通道图像 BGRA,其中 alpha 通道最后到达。完全透明的像素应该将 alpha 通道设置为 0,完全不透明的像素应该将 alpha 设置为 255/65535。如果格式、深度或通道顺序不同, 就在保存之前使用 Mat::convertTo 和 cv::cvtColor 进行转换。或者,使用通用文件存储 I/O 函数将图像保存为 XML 或 YAML 格式。

下面的示例将演示如何创建 BGRA 图像并将其保存到 PNG 文件中, 还将演示如何设置自定义压缩参数。

#include<iostream>#include<opencv2/opencv.hpp>#include<opencv2/core/utils/logger.hpp>usingnamespacecv;//所有 OpenCV 类都在命名空间 cv 下usingnamespacestd;staticvoidcreateAlphaMat(Mat&mat){CV_Assert(mat.channels()==4);for(inti=0;i<mat.rows;++i){for(intj=0;j<mat.cols;++j){Vec4b&bgra=mat.at<Vec4b>(i,j);bgra[0]=UCHAR_MAX;// 蓝色bgra[1]=saturate_cast<uchar>((float(mat.cols-j))/((float)mat.cols)*UCHAR_MAX);// 绿色bgra[2]=saturate_cast<uchar>((float(mat.rows-i))/((float)mat.rows)*UCHAR_MAX);// 红色bgra[3]=saturate_cast<uchar>(0.5*(bgra[1]+bgra[2]));// Alpha}}}intmain(){// Create mat with alpha channelMatmat(480,640,CV_8UC4);createAlphaMat(mat);vector<int>compression_params;compression_params.push_back(IMWRITE_PNG_COMPRESSION);compression_params.push_back(9);boolresult=false;try{result=imwrite("alpha.png",mat,compression_params);}catch(constcv::Exception&ex){fprintf(stderr,"Exception converting image to PNG format: %s\n",ex.what());}if(result)printf("Saved PNG file with alpha data.\n");elseprintf("ERROR: Can't save PNG file.\n");returnresult?0:1;}


在代 码 中 , createAlphaMat 是 一 个 自 定 义 函 数 , 用 于 使 用 alpha 通 道 创 建 材 质 。compression_params 用于存放压缩参数。函数 imwrite 把图像矩阵以compression_params 压缩参数保存到工程目录下的 alpha.png 中,文件 alpha.png 会自动创建。