Opencv核心功能---对矩阵进行掩码操作

矩阵上的掩码操作非常简单。 我们的想法是根据掩模矩阵(也称为内核)重新计算图像中的每个像素值。 此掩码包含的值将调整相邻像素(和当前像素)对新像素值的影响程度。 从数学的角度来看,我们使用指定的值进行加权平均。

测试样例

让我们考虑图像对比度增强方法的问题。 基本上我们想要为图像的每个像素应用以下公式:

第一种表示法是使用公式,而第二种表示法是第一种使用掩码的压缩版本。 您可以通过将掩码矩阵的中心(在零大小索引中用大写字母表示)放在要计算的像素上来使用掩码,并将像素值与重叠矩阵值相乘。 这是一回事,但是对于大型矩阵,后一种表示法更容易查看。

基本的实现方式

首先,我们确保输入图像数据是无符号字符格式。 我们使用cv :: CV_Assert函数,该函数在其中的表达式为false时抛出错误。

我们创建一个输出图像,其大小和类型与输入相同。 正如您在存储部分中看到的,根据通道的数量,我们可能有一个或多个子列。 我们将通过指针迭代它们,因此元素的总数取决于此数字。

我们将使用普通的C []运算符来访问像素。 因为我们需要同时访问多行,所以我们将获取每个行的指针(前一个,当前行和下一行)。 我们需要另一个指向我们要保存计算的位置的指针。 然后使用[]运算符访问正确的项目。 为了将输出指针向前移动,我们只需在每次操作后增加(使用一个字节):

在图像的边界上,上面的符号表示不存在的像素位置(例如减去1 - 减1)。 在这些方面,我们的公式是不确定的。 一个简单的解决方案是不在这些点中应用内核,例如,将边框上的像素设置为零:

filter2D函数

这样的滤波器在图像处理中非常常见,以至于在OpenCV中存在将负责应用掩模的功能(在某些地方也称为内核)。 为此,您首先需要定义一个保存mask的Mat对象:

然后调用cv :: filter2D函数指定要使用的输入,输出图像和kernell:

该函数甚至有第五个可选参数来指定内核的中心,第六个用于确定在操作未定义的区域(边框)中要做什么。 使用此函数的优点是它更短,更简洁,并且因为实现了一些优化技术,它通常比手动编码方法更快。具体的运行示例:

源代码下载网址:https://github.com/opencv/opencv/blob/master/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp

猜你喜欢

转载自blog.csdn.net/LYKymy/article/details/83119643