OpenCV-Python官方文档中文翻译19:Canny Edge Detection

Canny Edge Detection

Goal

In this chapter, we will learn about

  • Concept of Canny edge detection
  • OpenCV functions for that : cv.Canny()
  • Canny边缘检测的概念
  • 函数:cv.Canny()

Theory

Canny Edge Detection is a popular edge detection algorithm. It was developed by John F. Canny in

  1. It is a multi-stage algorithm and we will go through each stages.#这是一种多阶段的算法,我们将经历每个阶段。

  2. Noise Reduction#降噪

    Since edge detection is susceptible to noise in the image, first step is to remove the noise in the image with a 5x5 Gaussian filter. We have already seen this in previous chapters.

    因为边缘检测容易受到图像中的噪声影响,第一步就是用5x5的高斯滤波器去除图像中的噪声。

  3. Finding Intensity Gradient of the Image#找到图像的梯度强度

    Smoothened image is then filtered with a Sobel kernel in both horizontal and vertical direction to get first derivative in horizontal direction ( Gx) and vertical direction ( Gy). From these two images, we can find edge gradient and direction for each pixel as follows:

    Edge_Gradient(G)=G2x+G2y−−−−−−−√Angle(θ)=tan−1(GyGx)

    Gradient direction is always perpendicular to edges. It is rounded to one of four angles representing vertical, horizontal and two diagonal directions.

    然后用sobel内核在平滑图像的水平和垂直方向滤波,得到一阶导数。从这两张图片,我们可以看出每个像素的边缘梯度和方向。

  4. Non-maximum Suppression#非极大值抑制

    After getting gradient magnitude and direction, a full scan of image is done to remove any unwanted pixels which may not constitute the edge. For this, at every pixel, pixel is checked if it is a local maximum in its neighborhood in the direction of gradient. Check the image below:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TE8EZlxt-1614254067922)(https://docs.opencv.org/4.5.1/nms.jpg)]

    image

    Point A is on the edge ( in vertical direction). Gradient direction is normal to the edge. Point B and C are in gradient directions. So point A is checked with point B and C to see if it forms a local maximum. If so, it is considered for next stage, otherwise, it is suppressed ( put to zero).

    In short, the result you get is a binary image with “thin edges”.

  5. Hysteresis Thresholding#磁滞阈值

    This stage decides which are all edges are really edges and which are not. For this, we need two threshold values, minVal and maxVal. Any edges with intensity gradient more than maxVal are sure to be edges and those below minVal are sure to be non-edges, so discarded. Those who lie between these two thresholds are classified edges or non-edges based on their connectivity. If they are connected to “sure-edge” pixels, they are considered to be part of edges. Otherwise, they are also discarded. See the image below:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nRnPT9Jd-1614254067927)(https://docs.opencv.org/4.5.1/hysteresis.jpg)]

    image

    The edge A is above the maxVal, so considered as “sure-edge”. Although edge C is below maxVal, it is connected to edge A, so that also considered as valid edge and we get that full curve. But edge B, although it is above minVal and is in same region as that of edge C, it is not connected to any “sure-edge”, so that is discarded. So it is very important that we have to select minVal and maxVal accordingly to get the correct result.

    This stage also removes small pixels noises on the assumption that edges are long lines.

So what we finally get is strong edges in the image.

Canny Edge Detection in OpenCV

OpenCV puts all the above in single function, cv.Canny(). We will see how to use it. First argument is our input image. Second and third arguments are our minVal and maxVal respectively. Third argument is aperture_size. It is the size of Sobel kernel used for find image gradients. By default it is 3. Last argument is L2gradient which specifies the equation for finding gradient magnitude. If it is True, it uses the equation mentioned above which is more accurate, otherwise it uses this function: Edge_Gradient(G)=|Gx|+|Gy|. By default, it is False.

import numpy as np
import cv2 as cv 
from matplotlib import pyplot as plt
img = cv.imread("messi5.jpg",0)
edges = cv.Canny(img,100,200)
plt.subplot(121),plt.imshow(img,camp = 'gray')
plt.title('origianl image'),plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()

See the result below:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ztNYz79G-1614254067931)(https://docs.opencv.org/4.5.1/canny1.jpg)]

image

Additional Resources

  1. Canny edge detector at Wikipedia
  2. Canny Edge Detection Tutorial by Bill Green, 2002.

Exercises

  1. Write a small application to find the Canny edge detection whose threshold values can be varied using two trackbars. This way, you can understand the effect of threshold values.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于利用OpenCV实现边缘检测功能,我可以给你一些简要的介绍和代码示例。 1. Canny算法 Canny算法是一种经典的边缘检测算法,它的基本原理是通过求取图像灰度梯度的幅值和方向,然后通过非极大值抑制和双阈值处理来检测边缘。 下面是一个基本的Canny算法的代码示例: ```python import cv2 # 读取图像 img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE) # Canny算法边缘检测 edges = cv2.Canny(img, 100, 200) # 显示结果 cv2.imshow('Canny Edge Detection', edges) cv2.waitKey(0) cv2.destroyAllWindows() ``` 2. 外轮廓检测 外轮廓检测是指在图像中找到所有的边缘,并将它们连接成一个连续的轮廓。OpenCV提供了`cv2.findContours()`函数来实现外轮廓检测。 下面是一个基本的外轮廓检测的代码示例: ```python import cv2 # 读取图像 img = cv2.imread('image.jpg') # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化处理 ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 外轮廓检测 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 绘制轮廓 cv2.drawContours(img, contours, -1, (0, 0, 255), 2) # 显示结果 cv2.imshow('Contours Detection', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 3. 填充轮廓 填充轮廓是指在图像中找到所有的轮廓,并将其填充为指定的颜色。OpenCV提供了`cv2.drawContours()`函数来实现轮廓的填充。 下面是一个基本的轮廓填充的代码示例: ```python import cv2 # 读取图像 img = cv2.imread('image.jpg') # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化处理 ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 外轮廓检测 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 填充轮廓 cv2.drawContours(img, contours, -1, (0, 0, 255), -1) # 显示结果 cv2.imshow('Contours Filling', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 以上就是利用OpenCV实现边缘检测功能的一些简要介绍和代码示例,希望能对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值