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算子得到的结果如下所示。
Sobel算子的内核中既有正数又有负数,因此Sobel滤波器的计算结果通常是16位的有符号整数图像(CV_16S)。为了把结果显示为8位图像(上图),我们用数值0代表灰度128。负数表示更暗的像素,正数表示更亮的像素。垂直方向Sobel图像如下所示。
如果你熟悉照片编辑软件,就会知道这和图像浮雕化特效很像。实际上,这种特效通常就是用定向滤波器生成的。
你可以组合这两个结果(垂直和水平方向),得到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);
得到的结果如下所示。
从上图可以看出把Sobel算子称作边缘检测器的原因。接着,你可以对这幅图像阈值化,得到图像轮廓的二值分布图。代码片段和生成的图像如下所示:
cv::threshold(sobelImage, sobelThresholded,
threshold, 255, cv::THRESH_BINARY);
酷客网相关文章:
评论前必须登录!
注册