从文件加载图像:
如果您读取 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++ 代码
蟒蛇
您可以对浮点图像使用相同的方法(例如,您可以通过在 3 通道图像上运行 Sobel 来获取此类图像)(仅限 C++):
可以使用相同的方法更改像素强度:
OpenCV中有一些函数,特别是来自calib3d模块的函数,例如cv::p rojectPoints,它们以Mat的形式接受2D或3D点的数组。 矩阵应该正好包含一列,每行对应一个点,矩阵类型应该对应32FC2或32FC3。这样的矩阵可以很容易地从(仅限 C++)中构造:std::vector
可以使用相同的方法(仅限 C++)访问此矩阵中的点:Mat::at
Mat 是一种结构,用于保留矩阵/图像特征(行和列数、数据类型等)和指向数据的指针。因此,没有什么能阻止我们拥有对应于相同数据的多个 Mat 实例。Mat 保留一个引用计数,该计数指示在销毁特定 Mat 实例时是否必须释放数据。下面是在不复制数据的情况下创建两个矩阵的示例(仅限 C++):
结果,我们得到一个有 3 列的 32FC1 矩阵,而不是有 1 列的 32FC3 矩阵。 使用来自点的数据,并且在销毁时不会释放内存。然而,在这种特殊情况下,开发人员必须确保 的生存期长于 如果我们需要复制数据,可以使用例如 cv::Mat::copyTo 或 cv::Mat::clone:pointsMat
points
pointsMat
可以为每个功能提供一个空的输出垫。每个实现都为目标矩阵调用 Mat::create。如果矩阵为空,则此方法为矩阵分配数据。如果它不为空且具有正确的大小和类型,则该方法不执行任何操作。但是,如果大小或类型与输入参数不同,则会取消分配数据(并丢失)并分配新数据。例如:
矩阵上定义了许多方便的运算符。例如,以下是我们如何从现有的灰度图像中制作黑色图像img
选择感兴趣的区域:
从彩色到灰度的转换:
将映像类型从 8UC1 更改为 32FC1:
在开发过程中查看算法的中间结果非常有用。OpenCV 提供了一种可视化图像的便捷方式。可以使用以下方式显示 8U 图像:
对?waitKey()?的调用会启动一个消息传递周期,该周期在“image”窗口中等待击键。32F镜像需要转换为8U型。例如:
注意
这里?cv::namedWindow?不是必需的,因为它紧随其后的是?cv::imshow。不过,它可用于更改窗口属性或使用?cv::createTrackbar?时