Python图像锐化与边缘检测之Scharr,Canny,LOG算子详解

目录
  • 一.Scharr算子
  • 二.Cann算子
  • 三.LOG算子
  • 四.总结

一.Scharr算子

由于Sobel算子在计算相对较小的核的时候,其近似计算导数的精度比较低,比如一个3×3的Sobel算子,当梯度角度接近水平或垂直方向时,其不精确性就越发明显。Scharr算子同Sobel算子的速度一样快,但是准确率更高,尤其是计算较小核的情景,所以利用3×3滤波器实现图像边缘提取更推荐使用Scharr算子。

Scharr算子又称为Scharr滤波器,也是计算x或y方向上的图像差分,在OpenCV中主要是配合Sobel算子的运算而存在的,其滤波器的滤波系数如下:

Scharr算子的函数原型如下所示,和Sobel算子几乎一致,只是没有ksize参数。

dst = Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]]])

  • – src表示输入图像
  • – dst表示输出的边缘图,其大小和通道数与输入图像相同
  • – ddepth表示目标图像所需的深度,针对不同的输入图像,输出目标图像有不同的深度
  • – dx表示x方向上的差分阶数,取值1或 0
  • – dy表示y方向上的差分阶数,取值1或0
  • – scale表示缩放导数的比例常数,默认情况下没有伸缩系数
  • – delta表示将结果存入目标图像之前,添加到结果中的可选增量值
  • – borderType表示边框模式,更多详细信息查阅BorderTypes

Scharr算子的实现代码如下所示。

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取图像
img = cv2.imread('luo.png')
lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

#灰度化处理图像
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Scharr算子
x = cv2.Scharr(grayImage, cv2.CV_32F, 1, 0) #X方向
y = cv2.Scharr(grayImage, cv2.CV_32F, 0, 1) #Y方向
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
Scharr = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', 'Scharr算子']
images = [lenna_img, Scharr]
for i in range(2):
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])
plt.show()

其运行结果如图1所示:

二.Cann算子

John F.Canny于1986年发明了一个多级边缘检测算法——Canny边缘检测算子,并创立了边缘检测计算理论(Computational theory of edge detection),该理论有效地解释了这项技术的工作理论。

边缘检测通常是在保留原有图像属性的情况下,对图像数据规模进行缩减,提取图像边缘轮廓的处理方式。Canny算法是一种被广泛应用于边缘检测的标准算法,其目标是找到一个最优的边缘检测解或找寻一幅图像中灰度强度变化最强的位置。最优边缘检测主要通过低错误率、高定位性和最小响应三个标准进行评价。Canny算子的实现步骤如下:

第一步,使用高斯平滑(如公式2所示)去除噪声。

第二步,按照Sobel滤波器步骤计算梯度幅值和方向,寻找图像的强度梯度。先将卷积模板分别作用x和y方向,再计算梯度幅值和方向,其公式如下所示。梯度方向一般取0度、45度、90度和135度四个方向。

第三步,通过非极大值抑制(Non-maximum Suppression)过滤掉非边缘像素,将模糊的边界变得清晰。该过程保留了每个像素点上梯度强度的极大值,过滤掉其他的值。对于每个像素点,它进行如下操作:

  • 将其梯度方向近似为以下值中的一个,包括0、45、90、135、180、225、270和315,即表示上下左右和45度方向;
  • 比较该像素点和其梯度正负方向的像素点的梯度强度,如果该像素点梯度强度最大则保留,否则抑制(删除,即置为0)。其处理后效果如图2所示,左边表示梯度值,右边表示非极大值抑制处理后的边缘。

第四步,利用双阈值方法来确定潜在的边界。经过非极大抑制后图像中仍然有很多噪声点,此时需要通过双阈值技术处理,即设定一个阈值上界和阈值下界。图像中的像素点如果大于阈值上界则认为必然是边界(称为强边界,strong edge),小于阈值下界则认为必然不是边界,两者之间的则认为是候选项(称为弱边界,weak edge)。经过双阈值处理的图像如图3所示,左边为非极大值抑制处理后的边缘,右边为双阈值技术处理的效果图。

第五步,利用滞后技术来跟踪边界。若某一像素位置和强边界相连的弱边界认为是边界,其他的弱边界则被删除。
在OpenCV中,Canny()函数原型如下所示:

edges = Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])

  • – image表示输入图像
  • – edges表示输出的边缘图,其大小和类型与输入图像相同
  • – threshold1表示第一个滞后性阈值
  • – threshold2表示第二个滞后性阈值
  • – apertureSize表示应用Sobel算子的孔径大小,其默认值为3
  • – L2gradient表示一个计算图像梯度幅值的标识,默认值为false

Canny算子的边缘提取实现代码如下所示:

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取图像
img = cv2.imread('luo.png')
lenna_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

#灰度化处理图像
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#高斯滤波降噪
gaussian = cv2.GaussianBlur(grayImage, (3,3), 0)

#Canny算子
Canny = cv2.Canny(gaussian, 50, 150) 

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', 'Canny算子']
images = [lenna_img, Canny]
for i in range(2):
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])
plt.show()

其运行结果如图4所示:

三.LOG算子

LOG(Laplacian of Gaussian)边缘检测算子是David Courtnay Marr和Ellen Hildreth在1980年共同提出的,也称为Marr & Hildreth算子,它根据图像的信噪比来求检测边缘的最优滤波器。该算法首先对图像做高斯滤波,然后再求其拉普拉斯(Laplacian)二阶导数,根据二阶导数的过零点来检测图像的边界,即通过检测滤波结果的零交叉(Zero crossings)来获得图像或物体的边缘。

LOG算子综合考虑了对噪声的抑制和对边缘的检测两个方面,并且把Gauss平滑滤波器和Laplacian锐化滤波器结合了起来,先平滑掉噪声,再进行边缘检测,所以效果会更好。 该算子与视觉生理中的数学模型相似,因此在图像处理领域中得到了广泛的应用。它具有抗干扰能力强,边界定位精度高,边缘连续性好,能有效提取对比度弱的边界等特点。

常见的LOG算子是5×5模板,如下所示:

由于LOG算子到中心的距离与位置加权系数的关系曲线像墨西哥草帽的剖面,所以LOG算子也叫墨西哥草帽滤波器,如图5所示。

LOG算子的边缘提取实现代码如下所示:

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取图像
img = cv2.imread('luo.png')
lenna_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

#灰度化处理图像
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#先通过高斯滤波降噪
gaussian = cv2.GaussianBlur(grayImage, (3,3), 0)

#再通过拉普拉斯算子做边缘检测
dst = cv2.Laplacian(gaussian, cv2.CV_16S, ksize = 3)
LOG = cv2.convertScaleAbs(dst)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图形
titles = ['原始图像', 'LOG算子']
images = [lenna_img, LOG]
for i in range(2):
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])
plt.show()

其运行结果如图6所示:

四.总结

该系列文章主要通过Roberts算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr算子、Canny算子和LOG算子实现图像锐化和边缘检测,有效地提取了图像的轮廓,并进行了详细地实验处理。

到此这篇关于Python图像锐化与边缘检测之Scharr,Canny,LOG算子详解的文章就介绍到这了,更多相关Python Scharr Canny LOG内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python实现二值掩膜影像去噪与边缘强化方法详解

    目录 前言 一.方法 二.代码 三.效果测试 前言 这篇博客主要解决的一个问题是掩膜图像的噪声去除和边缘强化,如下图1所示.可以看到掩膜图像上有很多的斑点噪声,而且掩膜的轮廓也不够清晰.所以我们的目标就是一方面尽可能把这些斑点噪声去除,另一方面尽量突出掩膜边界.另外处理后的掩膜可以比真值大一些,但最好不能小. 图1 原始二值化影像 一.方法 因为之前有做过相关的工作,所以对于保留边界的斑点噪声消除第一反应是使用中值滤波.但很显然对于我们这个应用,单纯中值滤波是不够的.所以就想着那就采用多步处理,

  • Python图像锐化与边缘检测之Sobel与Laplacian算子详解

    目录 一.Sobel算子 二.Laplacian算子 三.总结 一.Sobel算子 Sobel算子是一种用于边缘检测的离散微分算子,它结合了高斯平滑和微分求导.该算子用于计算图像明暗程度近似值,根据图像边缘旁边明暗程度把该区域内超过某个数的特定点记为边缘.Sobel算子在Prewitt算子的基础上增加了权重的概念,认为相邻点的距离远近对当前像素点的影响是不同的,距离越近的像素点对应当前像素的影响越大,从而实现图像锐化并突出边缘轮廓[1-4]. Sobel算子的边缘定位更准确,常用于噪声较多.灰度

  • Python图像处理之边缘检测原理详解

    目录 原理 Sobel检测算子 Laplacian算子 算子比较 原理 边缘检测是图像处理和计算机视觉当中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点,图像的边缘检测可以大幅度的减少数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性,它们绝大多数可以分为两类:基于搜索和基于零穿越. 基于搜索:通过寻找图像一阶导数中max来检测边界,然后利用计算结果估计边缘的局部方向,通常采用梯度的方向,并在此方向找到局部梯度模的最大值,代表的算法是Sobel算子和Scharr算子.

  • Python图像运算之图像锐化和边缘检测

    目录 一.图像锐化 1.一阶微分算子 2.二阶微分算子 二.Roberts算子 三.Prewitt算子 四.总结 一.图像锐化 由于收集图像数据的器件或传输图像的通道存在一些质量缺陷,或者受其他外界因素的影响,使得图像存在模糊和有噪声的情况,从而影响到图像识别工作的开展.一般来说,图像的能量主要集中在其低频部分,噪声所在的频段主要在高频段,同时图像边缘信息主要集中在其高频部分.这将导致原始图像在平滑处理之后,图像边缘和图像轮廓模糊的情况出现.为了减少这类不利效果的影响,就需要利用图像锐化技术,使

  • Python图像锐化与边缘检测之Scharr,Canny,LOG算子详解

    目录 一.Scharr算子 二.Cann算子 三.LOG算子 四.总结 一.Scharr算子 由于Sobel算子在计算相对较小的核的时候,其近似计算导数的精度比较低,比如一个3×3的Sobel算子,当梯度角度接近水平或垂直方向时,其不精确性就越发明显.Scharr算子同Sobel算子的速度一样快,但是准确率更高,尤其是计算较小核的情景,所以利用3×3滤波器实现图像边缘提取更推荐使用Scharr算子. Scharr算子又称为Scharr滤波器,也是计算x或y方向上的图像差分,在OpenCV中主要是

  • Python图像运算之顶帽运算和底帽运算详解

    目录 一.图像顶帽运算 二.图像底帽运算 三.总结 一.图像顶帽运算 图像顶帽运算(top-hat transformation)又称为图像礼帽运算,它是用原始图像减去图像开运算后的结果,常用于解决由于光照不均匀图像分割出错的问题.其公式定义如下: 图像顶帽运算是用一个结构元通过开运算从一幅图像中删除物体,顶帽运算用于暗背景上的亮物体,它的一个重要用途是校正不均匀光照的影响.其效果图如图1所示. 在Python中,图像顶帽运算主要调用morphologyEx()实现,其中参数cv2.MORPH_

  • Python 计算机视觉编程进阶之OpenCV 图像锐化及边缘检测

    目录 前言 (1)图像锐化 (2)图像边缘检测 a. 图像边缘 b. 边缘检测 1. 一阶微分算算子.二阶微分算子 2. 读取图像信息 3. Sobel 算子 4. Laplacian 算子 5. Scharr 算子 6. Canny 算子 7. 总结 8. 参考论文 参考的一些文章以及论文我都会给大家分享出来 -- 链接就贴在原文,论文我上传到资源中去,大家可以免费下载学习,如果当天资源区找不到论文,那就等等,可能正在审核,审核完后就可以下载了.大家一起学习,一起进步!加油!! 前言 (1)图

  • OpenCV学习之图像梯度算子详解

    目录 1.Sobel算子 2.Scharr算子 3.laplacian算子 本文是OpenCV图像视觉入门之路的第12篇文章,本文详细的介绍了图像梯度算子的各种操作,例如:Sobel算子Scharr算子laplacian算子等操作. 1.Sobel算子 Sobel算子是一种图像边缘检测算子,它是一种空间滤波器,可以检测图像中的边缘,而梯度运算是一种求导数的方法,可以用来检测图像中的局部变化. import cv2 import numpy as np from numpy import unic

  • python二维码操作:对QRCode和MyQR入门详解

    python是所有编程语言中模块最丰富的 生活中常见的二维码功能在使用python第三方库来生成十分容易 三个大矩形是定位图案,用于标记二维码的大小.这三个定位图案有白边,通过这三个矩形就可以标识一个二维码了. QRCode 生成这个二维码只用一行 import qrcode qrcode.make("不睡觉干嘛呢").get_image().show() #设置URL必须添加http:// 安装导入QRCode pip install qrcode #方法多,体量小 安装导入MyQR

  • python实现图像处理之PiL依赖库的案例应用详解

    Python实现图像处理:PiL依赖库的应用 本文包含的练习题主要是PIL依赖库,即pillow相关的应用. 练习一:使用python给图片增加数字 实现思路: 使用PIL的Image.open导入图片. 获取图片的大小. 调用ImageDraw,在图片的指定位置写上数字. #coding=utf-8 #Auther by Alice #在图片的右上角增加一个数字 from PIL import Image,ImageFont,ImageDraw image = Image.open('/Use

  • python类:class创建、数据方法属性及访问控制详解

    在Python中,可以通过class关键字定义自己的类,然后通过自定义的类对象类创建实例对象. python中创建类 创建一个Student的类,并且实现了这个类的初始化函数"__init__": class Student(object):     count = 0     books = []     def __init__(self, name):         self.name = name 接下来就通过上面的Student类来看看Python中类的相关内容. 类构造和

  • Python 3.6 性能测试框架Locust安装及使用方法(详解)

    背景 Python3.6 性能测试框架Locust的搭建与使用 基础 python版本:python3.6 开发工具:pycharm Locust的安装与配置 点击"File"→"setting" 点击"setting",进入设置窗口,选择"Project Interpreter" 点击"+" 输入需要"Locust",点击"Install Package" 安装完成

  • 浅谈Python生成器generator之next和send的运行流程(详解)

    对于普通的生成器,第一个next调用,相当于启动生成器,会从生成器函数的第一行代码开始执行,直到第一次执行完yield语句(第4行)后,跳出生成器函数. 然后第二个next调用,进入生成器函数后,从yield语句的下一句语句(第5行)开始执行,然后重新运行到yield语句,执行后,跳出生成器函数,后面再次调用next,依次类推. 下面是一个列子: def consumer(): r = 'here' for i in xrange(3): yield r r = '200 OK'+ str(i)

随机推荐