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,比如:

cpp 复制代码
#include<opencv2\opencv.hpp>

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

cpp 复制代码
#ifdef HAVE_OPENCV_IMGCODECS
#include "opencv2/imgcodecs.hpp"
#endif
2.1 imread 读取图像文件

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

cpp 复制代码
Mat cv::imread (const String & filename, int flags = IMREAD_COLOR );

  其中参数 filename 表示要读取的图像文件名。 flags 表示读取模式, flags 可以从枚举cv::ImreadModes 中取值,默认取值是 IMREAD_COLOR,表示始终将图像转换为三通道 BGR 彩色图像。如果从指定文件加载图像成功,就返回 Mat 矩阵,如果无法读取图像(由于缺少文件、权限不正确、格式不受支持或无效),函数就返回空矩(Mat::data==NULL)。

  imread 支持常见的图像格式,某些图像格式需要(免费提供的)第三方类库。 在 Windows 操作系统下, OpenCV 的 imread 函数支持如下类型的图像载入:

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

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

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

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

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

cpp 复制代码
#include <iostream>
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
#pragma comment(lib, "opencv_world450d.lib") //引用引入库
int main(int argc, 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");
	else imshow("img", img);
	waitKey(0);
	return 0;
}

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

2.2 imwrite 保存图片

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

cpp 复制代码
bool cv::imwrite (const String & filename, InputArray img,
const std::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 文件中, 还将演示如何设置自定义压缩参数。

cpp 复制代码
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/utils/logger.hpp>
using namespace cv; //所有 OpenCV 类都在命名空间 cv 下
using namespace std;

static void createAlphaMat(Mat& mat)
{
	CV_Assert(mat.channels() == 4);
	for (int i = 0; i < mat.rows; ++i)
	{
		for (int j = 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
		}
	}
}
int main()
{
	// Create mat with alpha channel
	Mat mat(480, 640, CV_8UC4);
	createAlphaMat(mat);
	vector<int> compression_params;
	compression_params.push_back(IMWRITE_PNG_COMPRESSION);
	compression_params.push_back(9);
	bool result = false;
	try
	{
		result = imwrite("alpha.png", mat, compression_params);
	}
	catch (const cv::Exception& ex)
	{
		fprintf(stderr, "Exception converting image to PNG format: %s\n",
			ex.what());
	}
	if (result)
		printf("Saved PNG file with alpha data.\n");
	else
		printf("ERROR: Can't save PNG file.\n");
	return result ? 0 : 1;
}

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

相关推荐
liuyunshengsir2 小时前
从 TVM 到 TileLang:一文读懂深度学习编译器为什么走向 Tile 化
人工智能·深度学习·tvm·tilelang
海天一色y2 小时前
GSPO:重新定义大语言模型的强化学习训练范式
人工智能·机器学习·语言模型
云和数据.ChenGuang2 小时前
fastapi项目拆分实战数据模型
java·服务器·数据库·人工智能·深度学习·fastapi·强化学习
watersink2 小时前
机器学习HMM
人工智能·机器学习
东方小月2 小时前
从零开发一个 Coding Agent(九):实现 Agent 的工具调用闭环
人工智能·前端框架·node.js
Luhui Dev2 小时前
如何在 WorkBuddy 中使用大角几何:从 MCP 接入到 AI 几何作图
人工智能·数学·算法·agent·luhuidev
孙启超3 小时前
【AI应用开发】什么是混合检索(Hybrid Search)?向量检索 + BM25 关键词检索,适用场景与 RRF 融合原理
人工智能·缓存·llm·向量数据库·bm25·向量化·ai应用开发
小龙报3 小时前
【优选算法】1.搜索插入位置 2.x的平方根
java·c语言·数据结构·c++·python·算法·蓝桥杯
The moon forgets3 小时前
Qwen团队提出Ego2Robot, 第一人称视频助力具身VLA训练新数据
人工智能·机器学习·音视频