从文件加载图像
如果你加载的是 jpg 文件,将会默认创建一个 3 通道的图像,如果你需要灰度图,可以用:
注意
文件的根据市根据文件内容自动识别的(一般是前几个字节的内容)
将突破保存到文件:
文件的格式是通过其扩展名进行识别.
请使用 imdecode 和 imencode 来读写内存中的图片,而不是文件中的图片。
待处理
为了获得像素强度值,你需要知道图片的类型已经包含多少个通道。这里是一个单通道灰度图的例子(8uc1 类型), 其像素坐标为 x 和 y:
intensity.val[0] 包含了值范围从 0 到 255。请注意 x 和 y 参数的顺序。因为 opencv 的图像是使用和阵列相同结构的方式存储,我们使用相同的约定来处理两种方式:基于 0 的行索引(或者称为纵坐标)作为首个参数以及基于 0 的列索引(横坐标)跟进其后。你也可以使用下面的方式来代替:
现在让我们考虑一个使用 bgr 色彩顺序 3 通道的图像(通过 imread 返回默认的格式):
你可以对浮点图像使用相同的方法(例如通过运行 sobel 在一个三通道图像来获取图像):
可以使用相同的方法来修改像素强度:
opencv 的 calib3d 模块有很多函数,例如 projectpoints 使用 mat 形式来获取 2d 和 3d 点的数组。矩阵包含了一列数据,每一行对应一个点,矩阵类型可以是 32fc2 或者 32fc3。可以使用 std::vector 来构建一个矩阵:
你可以使用 mat::at 方法来访问阵列中的点:
mat 是一个用来保存阵列/图像特征的数据结构(包含行列编号、数据类型等),同时包含了指向数据的指针。因此同一个数据我们可以有多个 mat 实例。一个 mat 实例保存了一个数据的引用计数,当 mat 实例被销毁时引用计数会减一。下面是一个无需拷贝数据的情况下创建两个矩阵的示例代码:
上述结果返回一个 32fc1 的矩阵,包含 3 列数据,而不是 32fc3 的 1 列数据。pointsmat 使用这些点数据,在销毁的时候不会释放内存。在这个特定的情况下,开发者必须确保点阵的生命周期比 pointsmat 要长才行。如果我们需要复制数据,可以使用 mat::copyto 或者 mat::clone:
与开发人员所创建的输出图像的相反,一个空的输出 mat 可以提供给每个函数。该方法为一个空的矩阵分配数据。如果矩阵的数据和类型都无误,则该方法什么都不做。如果输入参数的大小和类型不一致,该数据就会被释放(并丢失)然后分配新的数据,例如:
一个阵列有很多的基本操作。例如我们可以从一个已有的灰度图总生成一个黑色图像::
selecting a region of interest:
将 mat 转成 c api 数据结构:
注意这里没有做任何的数据拷贝。
将彩色图转成灰度图:
将图片类型从 8uc1 改为 32fc1:
在开发过程中看到通过你算法出来的图片是很爽的。opencv 提供了一个便捷的方式来显示图像。一个8u图像可以使用如下代码显示:
waitkey() 方法调用开始一个消息的传递循环,等待用户在图像窗口中按键。32f 的图像需要转成 8u 才可以显示,例如: