OpenCV用定向滤波器检测边缘

OpenCV用定向滤波器检测边缘低通滤波器介绍了用核心矩阵进行线性滤波的概念。这些滤波器通过移除或减弱高频成分,取得模糊图像的效果。本文将执行一种反向的变换,即放大图像中的高频成分,再用本文介绍的高通滤波器进行边缘检测。

如何实现

我们将要使用的滤波器称为Sobel 滤波器。因为它只对垂直或水平方向的图像频率起作用(具体方向取决于滤波器选用的内核),所以被认为是一种定向滤波器。OpenCV中有一个函数可在图像上应用Sobel算子。水平方向滤波器的调用方法为:

          cv::Sobel(image,      // 输入
                    sobelX,     // 输出
                    CV_8U,      // 图像类型
                    1, 0,        // 内核规格
                    3,           // 正方形内核的尺寸
                    0.4, 128); // 比例和偏移量

垂直方向滤波的调用方法为(与水平方向滤波器非常类似):

          cv::Sobel(image,      // 输入
                    sobelY,     // 输出
                    CV_8U,      // 图像类型
                    0, 1,        // 内核规格
                    3,           // 正方形内核的尺寸
                    0.4, 128); // 比例和偏移量

函数用到了几个整型参数,注意,选用这些参数是为了生成一个8位的输出图像(CV_8U)。

水平方向Sobel算子得到的结果如下所示。
OpenCV用定向滤波器检测边缘

Sobel算子的内核中既有正数又有负数,因此Sobel滤波器的计算结果通常是16位的有符号整数图像(CV_16S)。为了把结果显示为8位图像(上图),我们用数值0代表灰度128。负数表示更暗的像素,正数表示更亮的像素。垂直方向Sobel图像如下所示。
OpenCV用定向滤波器检测边缘

如果你熟悉照片编辑软件,就会知道这和图像浮雕化特效很像。实际上,这种特效通常就是用定向滤波器生成的。

你可以组合这两个结果(垂直和水平方向),得到Sobel滤波器的范数:

// 计算Sobel滤波器的范数
cv::Sobel(image, sobelX, CV_16S,1,0);
cv::Sobel(image, sobelY, CV_16S,0,1);
cv::Mat sobel;
// 计算L1 范数
sobel= abs(sobelX)+abs(sobelY);

在convertTo方法中使用可选的缩放参数可得到一幅图像,图像中的白色用0表示,更黑的灰色阴影用大于0的值表示。这幅图像可以很方便地显示Sobel算子的范数,代码如下所示:

// 找到Sobel最大值
double sobmin, sobmax;
cv::minMaxLoc(sobel, &sobmin, &sobmax);
// 转换成8位图像
// sobelImage = -alpha*sobel + 255
cv::Mat sobelImage;
sobel.convertTo(sobelImage, CV_8U, -255./sobmax,255);

得到的结果如下所示。
OpenCV用定向滤波器检测边缘

从上图可以看出把Sobel算子称作边缘检测器的原因。接着,你可以对这幅图像阈值化,得到图像轮廓的二值分布图。代码片段和生成的图像如下所示:

cv::threshold(sobelImage, sobelThresholded,
              threshold, 255, cv::THRESH_BINARY);

OpenCV用定向滤波器检测边缘

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!