"); //-->
图像的输入/输出
从文件中加载图像:
如果读入的是一个JPG文件,默认状态下会创建一个3通道图像。如果你需要将其制成灰度图像,则使用以下代码:
注
文件格式由其内容(前几个字节)确定。将图像保存为一个文件:
注
文件的格式由其扩展名确定。
用CV :: imdecode和CV :: imencode从内存中读取和写入图像。
基本的图像操作
访问像素亮度值
为了获取像素亮度值,首先必须知道图像的类型和通道数。下面是一个单通道灰度图像的示例(数据类型8UC1)和像素坐标x和y:
C ++版本:intensity.val [0]包含从0到255的值,需要注意的是x和y的排序。OpenCV图像采用了结构化的矩阵来表示,使用以下两种情形使用同样的协议 - 基于0的行索引(或y坐标)在先,后面跟随基于0的列索引(或x坐标)。此外,也可以使用下面的符号(仅适用于C ++ ):
下面,来看一个BGR色彩排序的3通道图像(由imread返回默认格式):
C ++代码
Python
对于数据类型为浮点值的图像,可以使用相同的方法(例如,可以通过运行Sobel算子获取一个通道的图像)(仅适用于C ++):
利用相同的方法可以修改像素亮度值:
OpenCV中有一些函数,尤其是在calib3d模块中,如CV :: projectPoints函数,可以将 2D或3D像素点值转换成Mat形式的矩阵。该矩阵包含一列,每一行对应于一个点,矩阵类型为32FC2或32FC3。利用std::vector可以很容易地构建出这样的矩阵(仅适用于C ++):
利用相同的方法Mat::at可以访问矩阵中的点(仅适用于C ++):
内存管理和引用计数
Mat是保持矩阵/图像特性的一种结构(包括行数和列数,数据类型等)和一个指向数据的指针。对应一个相同的图像数据,可以构建出多个Mat实例,此外, Mat还包含一个引用计数器,当Mat对象被释放时,利用引用计数器指针来决定是否重新分配数据。下面的这个例子是在不进行数据复制的情况下,创建两个MAT矩阵: (仅适用于C ++)
结果得到了一个3列的32FC1矩阵,而不是一个1列的32FC3矩阵。pointsMat使用像素点的数据,释放时无需重新分配内存。在这种特殊情况下,开发人员必须确保 points的生命周期要比比pointsMat的生命周期更长。如果需要复制数据的话,则使用cv::Mat::copyTo或者 cv::Mat::clone两个函数:
应为上述每个函数提供一个空的Mat输出,每一次实现均是对目标矩阵调用一次Mat::create。如果矩阵为空,则利用该方法为矩阵分配数据。如果矩阵不为空,并且大小和数据类型均无误,则该方法不起作用。然而,如果大小或数据类型与输入参数不同,则重新分配(和丢失)原有数据,重新分配一个新的数据:
基本操作
每一个像素矩阵均定义有一些快捷的操作符。例如,下面是如何从现有的灰度图像中提取出黑色图像IMG
选择感兴趣的区域:
将彩色图像转换成灰度图像:
将图像类型从8UC1变为 32FC1:
可视化图像
在算法开发过程中,如果能看到运行的中间结果是非常有用的。OpenCV提供了一种可视化图像的便捷方式。采用以下代码可以显示一副8U图像:
调用waitKey()函数启动消息传递周期,等待“图像”窗口的一次键盘键入。此时,需要将32F图像转换为8U类型的图像。例如:
注
这里没有必要使用CV :: namedWindow函数,因为它后面紧跟着CV :: imshow。然而,可以用cv::createTrackbar来改变窗口属性。
本文以C++语言代码为例,获取Java和python版本可在原文中查看:
https://docs.opencv.org/4.5.2/d5/d98/tutorial_mat_operations.html
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。