大家好,欢迎来到IT知识分享网。
前言
笔记。
一、边缘检测算法
边缘检测算法是指利用灰度值的不连续性质,以灰度突变为基础分割出目标区域。对铝铸件表面进行成像后会产生一些带缺陷的区域,这些区域的灰度值比较低,与背景图像相比在灰度上会有突变,这是由于这些区域对光线产生散射所引起的。因此边缘检测算子可以用来对特征的提取。
1、一阶算子
一种是基于一阶微分的算子,也称基于搜索的算子,首先通过一阶导数计算边缘强度,然后采用梯度的方向来对边缘的局部方向进行寻找,同时根据该方向来寻找出局部梯度模的最大值,由此定位边缘,如Roberts Cross算子,Prewitt算子Sobel算子,Kirsch算子,Canny算子,罗盘算子等;
图像中的边缘区域,像素值会发生“跳跃”,对这些像素求导,在其一阶导数在边缘位置为极值,这就是Sobel算子使用的原理——极值处就是边缘。
2、二阶算子
另一种是基于二阶微分的算子,也称基于零交叉的算子,通过寻找由图像得到的二阶导数的过零点来定位检测边缘,如Marr-Hildreth算子,Laplacian算子,LOG算子等。如果对像素值求二阶导数,会发现边缘处的导数值为0。
二、一阶算子分析
一阶微分算子进行边缘检测的思路大致就是通过指定大小的核(kernal)(也称为算子)与图像进行卷积,将得到的梯度进行平方和或者最大值作为新的梯度赋值给对应的像素点,不同的一阶微分算子主要的不同在于其算子即核的元素不同以及核的大小不一样
以下是连续函数的一阶导数求导公式:因为图像是一个面,就相当于是灰度值关于x,y两个方向的函数,要求某一点的导数,则是各个方向的偏导数的平方和再进行开方运算。
离散函数的一阶导数公式:
y’=[y(x0+h)-y(x0-h)]/(2h);这是一维函数的一阶求导,h是步长,在图像处理中一般为1
首先复习一下什么是卷积?
卷积就是对应的元素相乘再进行累加的过程
实例图片:
1、Roberts算子
Robert算子是用于求解对角线方向的梯度,因为根据算子GX和GY的元素设置可以看到,只有对角线上的元素非零,其本质就是以对角线作为差分的方向来检测。
检测垂直边缘的效果好于斜向边缘,定位精度高,对噪声敏感,无法抑制噪声的影响。
不同方向的算子模板: 梯度的计算:
代码示例:
#include<opencv2/opencv.hpp> #include<opencv2/core/core.hpp> #include<opencv2/imgproc/imgproc.hpp> #include<opencv2/highgui/highgui.hpp> #include<iostream> using namespace std; using namespace cv; Mat roberts(Mat srcImage); int main(int argc, char** argv) { Mat src,src_binary,src_gray; src = imread("D:/opencv练习图片/薛之谦.jpg"); imshow("原图", src); cvtColor(src, src_gray, COLOR_BGR2GRAY); GaussianBlur(src_gray, src_binary, Size(3, 3),0, 0, BORDER_DEFAULT); Mat dstImage = roberts(src_binary); imshow("dstImage", dstImage); waitKey(0); return 0; } //roberts 边缘检测 Mat roberts(Mat srcImage) { Mat dstImage = srcImage.clone(); int nRows = dstImage.rows; int nCols = dstImage.cols; for (int i = 0; i < nRows - 1; i++) { for (int j = 0; j < nCols - 1; j++) { //根据公式计算 int t1 = (srcImage.at<uchar>(i, j) - srcImage.at<uchar>(i + 1, j + 1))* (srcImage.at<uchar>(i, j) - srcImage.at<uchar>(i + 1, j + 1)); int t2 = (srcImage.at<uchar>(i + 1, j) - srcImage.at<uchar>(i, j + 1))* (srcImage.at<uchar>(i + 1, j) - srcImage.at<uchar>(i, j + 1)); //计算g(x,y) dstImage.at<uchar>(i, j) = (uchar)sqrt(t1 + t2); } } return dstImage; }
效果展示:
2、Sobel算子
Sobel算子是主要用于边缘检测的离散微分算子,它结合了高斯平滑和微分求导,用于计算图像灰度函数的近似梯度。
因为Sobel算子结合了高斯平滑和分化,因此结果会具有更多的抗噪性。
不同方向的算子模板: 梯度的计算:
opencv中sobel函数的参数如下:
void cv::Sobel ( InputArray src, // 输入图像 OutputArray dst, // 输出图像 int ddepth, // 输出图像深度,-1 表示等于 src.depth() int dx, // 水平方向的阶数 int dy, // 垂直方向的阶数 int ksize = 3, // 卷积核的大小,常取 1, 3, 5, 7 等奇数 double scale = 1, // 缩放因子,应用于计算结果 double delta = 0, // 增量数值,应用于计算结果 int borderType = BORDER_DEFAULT // 边界模式 )
3、Prewitt算子
Prewitt算子利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用 。其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的。
这两个方向模板一个检测水平边缘,一个检测垂直边缘。
不同方向的算子模板:
Prewitt算子定位精度不如Sobel算子,在真正的使用中,一般不会用到这个算子,效果较差,因此不多做分析。
4、Canny算子
可以说,Canny 边缘检测算法是被业界公认的性能最为优良的边缘检测算法之一。Canny算法不是像Roberts、Prewitt、Sobel等这样简单梯度算子或锐化模板,它是在梯度算子基础上,引入了一种能获得抗噪性能好、定位精度高的单像素边缘的计算策略。
Canny 算子,在一阶微分的基础上,增加了非最大值抑制和双阈值检测,是边缘检测算子中最常用的一种,常被其它算子作为标准算子来进行优劣比较。
4.1算法步骤
1) 用高斯滤波器对输入图像做平滑处理 (大小为 5×5 的高斯核)去噪
2) 计算图像的梯度强度和角度方向 ( x 和 y 方向上的卷积核)
角度方向近似为四个可能值,即 0, 45, 90, 135
3) 对图像的梯度强度进行非极大抑制
可看做边缘细化:只有候选边缘点被保留,其余的点被移除
4) 利用双阈值检测和连接边缘
若候选边缘点大于上阈值,则被保留;小于下阈值,则被舍弃;处于二者之间,须视其所连接的像素点,大于上阈值则被保留,反之舍弃
opencv中canny函数的参数如下:
void cv::Canny ( InputArray image, // 输入图像 (8位) OutputArray edges, // 输出图像 (单通道,8位) double threshold1, // 下阈值 double threshold2, // 上阈值 int apertureSize = 3, bool L2gradient = false )
一般 上阈值 / 下阈值 = 2 ~ 3
L2gradient 默认 flase,表示图像梯度强度的计算采用近似形式;若为 true,则表示采用更精确的形式
5、Laplace(拉普拉斯算子)
索贝尔算子 (Sobel) 和拉普拉斯算子 (Laplace) 都是用来对图像进行边缘检测的,不同之处在于,前者是求一阶导,后者是求二阶导。
常用算子模块:
opencv中Laplace函数的参数如下:
void Laplacian ( InputArray src, OutputArray dst, int ddepth, int ksize = 1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT )
简单对比
在进行 Sobel,Laplacian 和 Canny 边缘检测之前,统一调用 GaussianBlur 来降低图像噪声
using namespace std; using namespace cv; int main(int argc, char** argv) { Mat src,src_binary,src_gray; Mat grad_x, grad_y; Mat abs_grad_x, abs_grad_y, dst; src = imread("D:/opencv练习图片/薛之谦.jpg"); imshow("原图", src); GaussianBlur(src, src, Size(3, 3), 0); cvtColor(src, src_gray, COLOR_BGR2GRAY); Sobel(src_gray, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);//求x方向梯度 convertScaleAbs(grad_x, abs_grad_x);//转换格式 8u Sobel(src_gray, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);//求y方向梯度 convertScaleAbs(grad_y, abs_grad_y); //合并梯度 addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst); imshow("solbel算子", dst); Canny(src_gray, dst, 100, 300); imshow("Canny算子", dst); Laplacian(src_gray, dst, -1, 3); imshow("Laplace算子", dst); waitKey(0); return 0; }
效果展示:
六.LOG算子
LOG(Laplacian of Gaussian)边缘检测算子是David Courtnay Marr和Ellen Hildreth在1980年共同提出的,也称为Marr & Hildreth算子,它根据图像的信噪比来求检测边缘的最优滤波器。该算法首先对图像做高斯滤波,然后再求其拉普拉斯(Laplacian)二阶导数,根据二阶导数的过零点来检测图像的边界,即通过检测滤波结果的零交叉(Zero crossings)来获得图像或物体的边缘。
LOG算子该综合考虑了对噪声的抑制和对边缘的检测两个方面,并且把Gauss平滑滤波器和Laplacian锐化滤波器结合了起来,先平滑掉噪声,再进行边缘检测,所以效果会更好。 该算子与视觉生理中的数学模型相似,因此在图像处理领域中得到了广泛的应用。它具有抗干扰能力强,边界定位精度高,边缘连续性好,能有效提取对比度弱的边界等特点。
常见的LOG算子是5*5模板,如下所示:
由于LOG算子到中心的距离与位置加权系数的关系曲线像墨西哥草帽的剖面,所以LOG算子也叫墨西哥草帽滤波器,如图所示。
LOG算子的边缘提取实现代码如下所示:
# -*- coding: utf-8 -*-
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取图像
img = cv2.imread('lena.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 = [u'原始图像', u'LOG算子']
images = [lenna_img, LOG]
for i in xrange(2):
plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
其运行结果如下图所示:
LOG滤波器方法通过检测二阶导数过零点来判断边缘点。LOG滤波器中的a正比于低通滤波器的宽度,a越大,平滑作用越显著,去除噪声越好,但图像的细节也损失越大,边缘精度也就越低。所以在边缘定位精度和消除噪声级间存在着矛盾,应该根据具体问题对噪声水平和边缘点定位精度要求适当选取。
讨论和比较了几种常用的边缘检测算子。梯度算子计算简单,但精度不高,只能检测出图像大致的轮廓,而对于比较细的边缘可能会忽略。Prewitt 和Sobel 算子比Roberts 效果要好一些。LOG 滤波器和Canny 算子的检测效果优于梯度算子,能够检测出图像较细的边缘部分。不同的系统,针对不同的环境条件和要求,选择合适的算子来对图像进行边缘检测。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/10876.html