Python OpenCV实现边缘检测

本文实例为大家分享了Python OpenCV实现边缘检测的具体代码,供大家参考,具体内容如下

1. Sobel 算子检测

Sobel 算子是高斯平滑和微分运算的组合,抗噪能力很强,用途也很多,尤其是效率要求高但对细纹理不是很在意的时候。

对于不连续的函数,有:

假设要处理的图像为I,在两个方向求导。

水平变化:用奇数大小的模板对图像I卷积,结果为Gx。例如,当模板大小为3时,Gx为:

垂直变化:用奇数大小的模板对图像I卷积,结果为Gy。例如,当模板大小为3时,Gy为:

在图像的每个点,结合以上两个结果,得到:

极大值的位置是图像的边缘。

当核大小为3时,上述Sobel核可能会产生更明显的误差。 为了解决这个问题,可以使用 Scharr 函数。这个函数只对大小为 3 的核有效,运算速度和 Sobel 函数一样快,但是结果更准确。 计算方法为:

cv.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)
参数:
src 传入的图像
ddepth 图像的深度
dx、dy 指求导的阶数,0表示这个方向上没有求导,取值为0、1。
ksize Sobel算子的大小,即卷积核的大小,必须为奇数1、3、5、7,默认为3。-1代表3x3的Scharr算子。
scale 缩放导数的比例常数,默认情况为没有伸缩系数。
borderType 图像边界的模式,默认值为cv.BORDER_DEFAULT。

需要对x和y两个方向都调用一次cv.Sobel()函数。然后,对每个方向调用cv.convertScaleAbs()函数将其转回uint8格式,再调用cv2.addWeighted()函数将两个方向组合起来。

2. Laplacian 算子检测

Laplacian 使用二阶导数来检测边缘。 因为图像是二维的,所以我们需要从两个方向求导:

不连续函数的二阶导数是:

使用的卷积核是:

cv.Laplacian(src, ddepth, ksize)
参数:
src 需要处理的图像
ddepth 图像的深度,-1表示采用的是原图像相同的深度,目标图像的深度必须大于等于原图像的深度
ksize 算子的大小,即卷积核的大小,必须为1、3、5、7。

然后,对返回值调用cv.convertScaleAbs(res)即可获得边缘图像。

3.  Canny 边缘检测

Canny 边缘检测算法由4个步骤组成。

1)去噪。由于边缘检测容易受噪声影响,首先使用5*5高斯滤波器去除噪声。

2)计算图像梯度。在平滑图像上使用 Sobel 算子计算水平和垂直方向的一阶导数(Gx 和 Gy)。 根据得到的两个梯度图(Gx和Gy)求出边界的梯度和方向,公式如下:

如果一个像素是一个边缘,它的梯度方向总是垂直于边缘。 梯度方向分为四类:垂直方向、水平方向和两个对角线方向。

3)非极大值抑制。得到梯度的方向和大小后,扫描整个图像去除那些非边界点。 检查每个像素点,看这个点的梯度是否在周围具有相同梯度方向的点中最大。

A点位于图像的边缘。在其梯度变化的方向,选择像素B和C,检查A点的梯度是否为极大值。 如果是极大值,则保留,否则A点将被抑制,最后得到的结果是边缘细的二值图像。

4)滞后阈值。现在来确定真正的边界。我们设置了两个阈值:minVal 和 maxVal。 当图像的灰度梯度高于 maxVal 时,认为是真正的边界,低于minVal 的边界将被丢弃。 如果介于两者之间,则取决于该点是否连接到确定为真的边界点。 如果是,则认为是边界点,如果不是,则将其丢弃。 minVal 较小的阈值将间断的边缘连接起来,maxVal 较大的阈值检测图像中明显的边缘。如下图:

A 高于阈值 maxVal,因此它是真正的边界点。虽然 C 低于 maxVal 但高于 minVal 并与 A 相连,所以它也被视为真正的边界点。 B 会被丢弃,因为它低于 maxVal ,并且没有连接到真正的边界点。 所以,选择合适的 maxVal 和 minVal 对于获得好的结果非常重要。

cv.Canny(image, threshold1, threshold2)
参数:
image 灰度图
threshold1 minval,较小的阈值
threshold2 maxval,较大的阈值

例:使用Sobel、Laplacian、Canny算法检测下面图像的边缘。

import matplotlib
import cv2 as cv
import matplotlib.pyplot as plt

font = {
    "family": "Microsoft YaHei"
}
matplotlib.rc("font", **font)

img = cv.imread("./image/horse.jpg", 0)

# Sobel
x = cv.Sobel(img, cv.CV_16S, 1, 0)
y = cv.Sobel(img, cv.CV_16S, 0, 1)
absx = cv.convertScaleAbs(x)
absy = cv.convertScaleAbs(y)
res = cv.addWeighted(absx, 0.5, absy, 0.5, 0)
plt.imshow(res, cmap=plt.cm.gray)
plt.title("Sobel")
plt.show()

# Schaar
x = cv.Sobel(img, cv.CV_16S, 1, 0, ksize=-1)
y = cv.Sobel(img, cv.CV_16S, 0, 1, ksize=-1)
absx = cv.convertScaleAbs(x)
absy = cv.convertScaleAbs(y)
res = cv.addWeighted(absx, 0.5, absy, 0.5, 0)
plt.imshow(res, cmap=plt.cm.gray)
plt.title("Schaar")
plt.show()

# Laplacian
res = cv.Laplacian(img, cv.CV_16S)
res = cv.convertScaleAbs(res)
plt.imshow(res, cmap=plt.cm.gray)
plt.title("Laplacian")
plt.show()

# Canny
res = cv.Canny(img, 0, 100)
plt.imshow(res, cmap=plt.cm.gray)
plt.title("Canny")
plt.show()

输出:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 使用Python中OpenCV和深度学习进行全面嵌套边缘检测

    这篇博客将介绍如何使用OpenCV和深度学习应用全面嵌套的边缘检测.并将对图像和视频流应用全面嵌套边缘检测,然后将结果与OpenCV的标准Canny边缘检测器进行比较. 1. 效果图 愤怒的小鸟--原始图 VS Canny边缘检测图 VS HED边缘检测图 花朵--原始图 VS Canny边缘检测图 VS HED边缘检测图 视频效果图GIF 如下 2. 全面嵌套边缘检测与Canny边缘检测 2.1 Hed与Canny边缘检测对比 Holistically-Nested Edge Detectio

  • 使用OpenCV-python3实现滑动条更新图像的Canny边缘检测功能

    import cv2 from matplotlib import pyplot as plt import numpy as np img= cv2.imread('39.jpg')#加载图片 cv2.namedWindow('Canny edge detect')#设置窗口,cv2.WINDOW_NORMAL表示窗口大小可自动调节 cv2.namedWindow('Original Image',cv2.WINDOW_NORMAL) cv2.namedWindow('Canny edgeIm

  • Python使用Opencv实现边缘检测以及轮廓检测的实现

    边缘检测 Canny边缘检测器是一种被广泛使用的算法,并被认为是边缘检测最优的算法,该方法使用了比高斯差分算法更复杂的技巧,如多向灰度梯度和滞后阈值化. Canny边缘检测器算法基本步骤: 平滑图像:通过使用合适的模糊半径执行高斯模糊来减少图像内的噪声. 计算图像的梯度:这里计算图像的梯度,并将梯度分类为垂直.水平和斜对角.这一步的输出用于在下一步中计算真正的边缘. 非最大值抑制:利用上一步计算出来的梯度方向,检测某一像素在梯度的正方向和负方向上是否是局部最大值,如果是,则抑制该像素(像素不属于

  • python opencv实现图像边缘检测

    本文利用python opencv进行图像的边缘检测,一般要经过如下几个步骤: 1.去噪 如cv2.GaussianBlur()等函数: 2.计算图像梯度 图像梯度表达的是各个像素点之间,像素值大小的变化幅度大小,变化较大,则可以认为是出于边缘位置,最多可简化为如下形式: 3.非极大值抑制 在获得梯度的方向和大小之后,应该对整幅图像做一个扫描,去除那些非边界上的点.对每一个像素进行检查,看这个点的梯度是不是周围具有相同梯度方向的点中最大的.如下图所示: 4.滞后阈值 现在要确定那些边界才是真正的

  • Python实现Opencv cv2.Canny()边缘检测

    目录 1. 效果图 2. 源码 补充:OpenCV-Python 中 Canny() 参数 这篇博客将介绍Canny边缘检测的概念,并利用cv2.Canny()实现边缘检测: Canny边缘检测是一种流行的边缘检测算法.它是由约翰F开发的,是一个多阶段的算法: Canny边缘检测大致包含4个步骤: 降噪(使用高斯滤波去除高频噪声): 计算边缘梯度和方向(SobelX.SobleY核在水平方向和垂直方向对平滑后的图像进行滤波,找到每个像素的边缘梯度和方向): 非最大抑制(在得到梯度大小和方向后,对

  • Python OpenCV实现边缘检测

    本文实例为大家分享了Python OpenCV实现边缘检测的具体代码,供大家参考,具体内容如下 1. Sobel 算子检测 Sobel 算子是高斯平滑和微分运算的组合,抗噪能力很强,用途也很多,尤其是效率要求高但对细纹理不是很在意的时候. 对于不连续的函数,有: 假设要处理的图像为I,在两个方向求导. 水平变化:用奇数大小的模板对图像I卷积,结果为Gx.例如,当模板大小为3时,Gx为: 垂直变化:用奇数大小的模板对图像I卷积,结果为Gy.例如,当模板大小为3时,Gy为: 在图像的每个点,结合以上

  • Python+OpenCV 图像边缘检测四种实现方法

    目录 1.Sobel算子 2.Schaar算子(更能体现细节) 3.Laplacian算子(基于零穿越的,二阶导数的0值点) 4.Canny边缘检测(被认为是最优的边缘检测算法) 总结 import cv2 as cv import numpy as np import matplotlib.pyplot as plt # 设置兼容中文 plt.rcParams['font.family'] = ['sans-serif'] plt.rcParams['font.sans-serif'] = [

  • Python OpenCV Canny边缘检测算法的原理实现详解

    目录 Gaussian smoothing Computing the gradient magnitude and orientation Non-maxima suppression Hysteresis thresholding OpenCV实现 Gaussian smoothing 总的来说,Canny边缘检测可以分为四个步骤: 由于边缘检测对噪声敏感,因此对图像应用高斯平滑以帮助减少噪声.具体做法是,采用一个5*5的高斯平滑滤波器对图像进行滤波处理. Computing the gra

  • Python OpenCV 图像矫正的原理实现

    目录 题目描述 基本思路 核心代码 题目描述 目录hw1下的图像是一些胶片的照片,请将其进行度量矫正. 推荐流程:采用Canny算子,检测边缘点:采用Hough直线检测,根据边缘点检测胶片边缘对应的4条直线:4条直线在图像平面中的交点为胶片图像的4个顶点.根据4个顶点与真实世界中胶片的位置(假设胶片图像长宽比为4:3),得到两个平面之间的单应变换矩阵,并根据单应变换矩阵实现图像矫正. 基本思路 使用Canny算子,检测边缘点:以边缘点作为输入,采用Hough直线检测,检测出最多点共线的四条直线,

  • python中opencv Canny边缘检测

    目录 Canny边缘检测 Canny边缘检测基础 高斯滤波去除图像噪声 计算梯度 非极大值抑制 应用双阈值确定边缘 Canny函数及使用 Canny边缘检测 Canny边缘检测是一种使用多级边缘检测算法检测边缘的方法. OpenCV提供了函数cv2.Canny()实现Canny边缘检测. Canny边缘检测基础 Canny边缘检测分为如下几个步骤: 去噪.噪声会影响边缘检测的准确性,因此首先要将噪声过滤掉. 计算梯度的幅度与方向 非极大值抑制,即适当地让边缘“变瘦” 确定边缘.使用双阈值算法确定

  • python+opencv识别图片中的圆形

    本文实例为大家分享了python+opencv识别图片中足球的方法,供大家参考,具体内容如下 先补充下霍夫圆变换的几个参数知识: dp,用来检测圆心的累加器图像的分辨率于输入图像之比的倒数,且此参数允许创建一个比输入图像分辨率低的累加器.上述文字不好理解的话,来看例子吧.例如,如果dp= 1时,累加器和输入图像具有相同的分辨率.如果dp=2,累加器便有输入图像一半那么大的宽度和高度. minDist,为霍夫变换检测到的圆的圆心之间的最小距离,即让我们的算法能明显区分的两个不同圆之间的最小距离.这

  • python+opencv轮廓检测代码解析

    首先大家可以对OpenCV有个初步的了解,可以参考:简单了解OpenCV 轮廓(Contours),指的是有相同颜色或者密度,连接所有连续点的一条曲线.检测轮廓的工作对形状分析和物体检测与识别都非常有用. 在轮廓检测之前,首先要对图片进行二值化或者Canny边缘检测.在OpenCV中,寻找的物体是白色的,而背景必须是黑色的,因此图片预处理时必须保证这一点. import cv2 #读入图片 img = cv2.imread("1.png") # 必须先转化成灰度图 gray = cv2

  • python实现canny边缘检测

    canny边缘检测原理 canny边缘检测共有5部分组成,下边我会分别来介绍. 1 高斯模糊(略) 2 计算梯度幅值和方向. 可选用的模板:soble算子.Prewitt算子.Roberts模板等等; 一般采用soble算子,OpenCV也是如此,利用soble水平和垂直算子与输入图像卷积计算dx.dy: 进一步可以得到图像梯度的幅值: 为了简化计算,幅值也可以作如下近似: 角度为: 如下图表示了中心点的梯度向量.方位角以及边缘方向(任一点的边缘与梯度向量正交) : θ = θm = arcta

随机推荐