资讯专栏INFORMATION COLUMN

OpenCV基础(11)基于OpenCV的边缘检测

RobinQu / 1524人阅读

摘要:对图像进行两个方向的梯度,将原始图像提取为边缘结构表示,使其结构完整性保持不变。边缘检测边缘检测是应用最广泛的边缘检测算法之一。在性能方面,边缘检测得到了最好的结果,因为它不仅使用了边缘检测,而且还使用了非最大抑制和迟滞阈值。

边缘检测是一种图像处理技术,用于识别图像中目标或区域的边界(边缘)。边缘是图像中最重要的特征之一。我们通过图像的边缘来了解图像的基本结构。因此,计算机视觉处理管道在应用中广泛地使用边缘检测。

1.如何检测边缘?

边缘的特征是像素强度的突然变化。为了检测边缘,我们需要在邻近的像素中寻找这些变化。来吧,让我们探讨一下OpenCV中可用的两种重要边缘检测算法的使用:Sobel边缘检测和Canny边缘检测。我们将讨论这些理论,并演示它们在OpenCV中的使用。

2.简单的代码示例

首先,看一看演示边缘检测的代码。我们将详细讨论每一行代码,以便您能够完全理解它。
(1)Python

import cv2# 读取原始图像img = cv2.imread("test.jpg") # 显示原始图像cv2.imshow("Original", img)cv2.waitKey(0)# 转换为灰度图img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 模糊图像以更好地检测边缘img_blur = cv2.GaussianBlur(img_gray, (3,3), 0) # Sobel边缘检测sobelx = cv2.Sobel(src=img_blur, ddepth=cv2.CV_64F, dx=1, dy=0, ksize=5) # X轴上的Sobel边缘检测sobely = cv2.Sobel(src=img_blur, ddepth=cv2.CV_64F, dx=0, dy=1, ksize=5) # Y轴上的Sobel边缘检测sobelxy = cv2.Sobel(src=img_blur, ddepth=cv2.CV_64F, dx=1, dy=1, ksize=5) # 结合X和Y的Sobel边缘检测# 显示Sobel边缘检测图像cv2.imshow("Sobel X", sobelx)cv2.waitKey(0)cv2.imshow("Sobel Y", sobely)cv2.waitKey(0)cv2.imshow("Sobel X Y using Sobel() function", sobelxy)# Canny边缘检测edges = cv2.Canny(image=img_blur, threshold1=100, threshold2=200) # 显示Canny边缘检测图像cv2.imshow("Canny Edge Detection", edges)cv2.waitKey(0)

(2)C++

#include #include // 命名空间using namespace std;using namespace cv;int main(){    // 读取原始图像    Mat img = imread("test.jpg");    // 显示原始图像    imshow("original Image", img);    waitKey(0);    // 转换为灰度图    Mat img_gray;    cvtColor(img, img_gray, COLOR_BGR2GRAY);    // 模糊图像以更好地检测边缘    Mat img_blur;    GaussianBlur(img_gray, img_blur, Size(3,3), 0);        // Sobel边缘检测    Mat sobelx, sobely, sobelxy;    Sobel(img_blur, sobelx, CV_64F, 1, 0, 5);    Sobel(img_blur, sobely, CV_64F, 0, 1, 5);    Sobel(img_blur, sobelxy, CV_64F, 1, 1, 5);    // 显示Sobel边缘检测图像    imshow("Sobel X", sobelx);    waitKey(0);    imshow("Sobel Y", sobely);    waitKey(0);    imshow("Sobel XY using Sobel() function", sobelxy);    waitKey(0);    // Canny 边缘检测    Mat edges;    Canny(img_blur, edges, 100, 200, 3, false);    // 显示Canny边缘检测图像    imshow("Canny edge detection", edges);    waitKey(0);        destroyAllWindows();    return 0;}




查看Sobel图像在x方向上主要识别垂直边缘(即那些在x方向上梯度最大的)。而在y方向上则表示水平边(即在y方向上梯度最大的)。仔细看看这两张照片上老虎的条纹。注意,在Sobel图像中,条纹的垂直边缘在x方向上更加明显。对Sobel图像进行两个方向的梯度,将原始图像提取为边缘结构表示,使其结构完整性保持不变。

我们使用的下限为100,上限为200。正如你所看到的,该算法已经识别出了图像中的主要边缘,在这个过程中消除了那些对整体结构不太重要的边缘。然而,结果可以很容易地调整,所以去尝试不同的图像,改变模糊的数量,并尝试不同的阈值来获得自己的感觉。

3.Sobel边缘检测

Sobel边缘检测是应用最广泛的边缘检测算法之一。Sobel算子检测像素强度突然变化的边缘,如下图所示。

当我们画出强度函数的一阶导数时,强度的增加就更加明显了。

从上图可以看出,在梯度高于某一特定阈值的区域可以检测到边缘。此外,导数的突然变化也会显示像素强度的变化。记住这个,我们可以用3×3核来近似导数。我们使用一个核来检测X方向上像素强度的突然变化,另一个在Y方向上。

这些是用于Sobel边缘检测的核:


当这些核与原始图像进行卷积时,就得到了Sobel边缘图像.

  • 如果我们只使用垂直核,卷积产生一个Sobel图像,边缘在x方向增强
  • 使用水平核生成一个Sobel图像,在y方向上增强边缘。

G x G_x Gx G y G_y Gy分别表示x和y方向上的强度梯度。如果A和B表示上面定义的X和Y核:
G x = A ∗ I G y = B ∗ I G_x = A * I//G_y = B * I Gx=AIGy=BI其中 ∗ * 为卷积算子, I I I为输入图像。

梯度幅值 G G G的最终近似可计算为: G = G x 2 + G y 2 G=/sqrt{G^2_x+G^2_y} G=Gx2+Gy2

梯度的方向可以近似为: Θ = a r c t a n ( G y G x ) /Theta=arctan(/frac{G_y}{G_x}) Θ=arctan(GxGy)

在下面的代码示例中,我们使用Sobel()函数进行计算:Sobel(src, ddepth, dx, dy)
参数ddepth指定输出图像的精度,而dxdy指定每个方向的导数的顺序。例如:

  • 如果dx=1 dy=0,我们计算x方向上的一阶Sobel像。
  • 如果dx=1 dy=1,我们计算两个方向上的一阶Sobel像
  • 如果dx=0 dy=1,我们计算y方向上的一阶Sobel像。

4.Canny边缘检测

Canny边缘检测是当今最流行的边缘检测方法之一,因为它具有很强的鲁棒性和灵活性。这一过程分为四个阶段,包括:

  • 降噪
  • 计算图像的强度梯度
  • 伪边抑制
  • 迟滞阈值法

1)降噪

在Canny边缘检测中,高斯模糊滤波器被用来去除或最小化不必要的细节,这些细节可能导致不理想的边缘。看看下面两张图片中的老虎,右边的图片应用了高斯模糊。正如你所看到的,它看起来有点模糊,但仍然保留了大量的细节,从这些细节可以计算出边缘。

2)计算图像的强度梯度

一旦图像被平滑(模糊),它被一个包含水平和垂直的Sobel核过滤。然后使用这些滤波操作的结果来计算每个像素的强度梯度大小( G G G)和方向( Θ /Theta Θ),如下所示。
G = G x 2 + G y 2 Θ = a r c t a n ( G y G x ) G=/sqrt{G^2_x+G^2_y}///Theta=arctan(/frac{G_y}{G_x}) G=Gx2+Gy2 Θ=arctan(GxGy)
然后将梯度方向四舍五入到最近的45度角。下图(右)显示了这个组合处理步骤的结果。

3)伪边抑制

在降低噪声和计算强度梯度之后,这一步的算法使用了一种称为非最大边缘抑制的技术来过滤掉不需要的像素(实际上可能不构成边缘)。为了做到这一点,每个像素与它的邻近像素比较,在正和负梯度方向。如果当前像素的梯度大小大于其相邻像素,则保持不变。否则,当前像素的大小设置为零。下面的图片演示了一个示例。如你所见,老虎皮毛的许多边缘都被明显弱化了。

4)迟滞阈值法

在Canny边缘检测的最后一步中,将梯度值与两个较小的阈值进行比较。

  • 如果梯度幅值高于较大的阈值,则这些像素与强边缘相关联,并包含在最终的边缘图中。
  • 如果梯度幅值低于较小的阈值,则像素被抑制,并从最终的边缘图中排除。
  • 所有其他像素,其梯度大小落在这两个阈值之间,被标记为“弱”边缘(即它们成为最终边缘图中的候选者)。
  • 如果“弱”像素与那些与强边缘相关的像素相连接,那么它们也会被包含在最终的边缘图中。

面是使用OpenCV应用Canny边缘检测的语法:Canny(image, threshold1, threshold2)
Canny()函数实现了上面描述的方法。我们只提供Canny边缘检测算法使用的两个阈值,OpenCV处理所有实现细节。在调用Canny()函数之前,不要忘记模糊图像。这是一个强烈推荐的预处理步骤。

在性能方面,Canny边缘检测得到了最好的结果,因为它不仅使用了Sobel边缘检测,而且还使用了非最大抑制和迟滞阈值。这为在算法的最后阶段如何识别和连接边提供了更多的灵活性。

总结

我们讨论了什么使边缘检测成为如此重要的图像处理技术,并重点了解了它的两个最重要的算法(Sobel边缘检测和Canny边缘检测)。在演示它们在OpenCV中的使用时,我们强调了为什么模糊是如此重要的预处理步骤。

您还看到了Canny边缘检测实际上是如何使用Sobel算子来计算数值导数的。并且具有鲁棒性和灵活性,甚至使用非最大抑制和迟滞阈值来获得最大优势。最后,您了解了为什么Canny边缘检测是执行边缘检测的首选和最广泛使用的方法。

参考目录

https://learnopencv.com/edge-detection-using-opencv/

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/121115.html

相关文章

  • 机器视觉、模式识别库汇总

    摘要:十开放模式识别项目开放模式识别项目,致力于开发出一套包含图像处理计算机视觉自然语言处理模式识别机器学习和相关领域算法的函数库。 一、开源生物特征识别库 OpenBROpenBR 是一个用来从照片中识别人脸的工具。还支持推算性别与年龄。使用方法:$ br -algorithm FaceRecognition -compare me.jpg you.jpg二、计算机视觉库 OpenCVOpenC...

    habren 评论0 收藏0
  • OpenCV图像梯度(Sobel和Scharr)

    摘要:图像梯度是什么图像梯度是许多计算机视觉和图像处理程序的基本组成部分。因此,边缘可以对应于图像中对象的边界图像中阴影或光照条件的边界对象中局部的边界图像梯度定义为图像强度的方向变化。 ...

    chunquedong 评论0 收藏0
  • 首次公开,整理12年积累博客收藏夹,零距离展示《收藏夹吃灰》系列博客

    摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...

    Harriet666 评论0 收藏0
  • Python 计算机视觉(十四)—— OpenCV 进行霍夫变换

    摘要:霍夫变换霍夫变换是图像处理中的一种特征提取技术,它通过一种投票算法检测具有特定形状的物体。该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换的结果。 参考的一些文章以及论文我都会给大家分享出来 —— 链接就贴在原文,论文我上传到资源中去,大家可以免...

    用户83 评论0 收藏0
  • OpenCV-Python 图像边缘检测

    摘要:设置兼容中文算子代表沿方向做算子代表沿方向做算子格式转换边缘检测结果原图算子边缘检测算子边缘检测算子更能体现细节代表沿方向做算子代表沿方向做算子格式转换边缘检测结果原图算子边缘检 ...

    番茄西红柿 评论0 收藏2637

发表评论

0条评论

最新活动
阅读需要支付1元查看
<