opencv——边缘检测算法(总结)

article/2025/9/15 3:52:04

前言

笔记。

一、边缘检测算法

边缘检测算法是指利用灰度值的不连续性质,以灰度突变为基础分割出目标区域。对铝铸件表面进行成像后会产生一些带缺陷的区域,这些区域的灰度值比较低,与背景图像相比在灰度上会有突变,这是由于这些区域对光线产生散射所引起的。因此边缘检测算子可以用来对特征的提取。

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) 用高斯滤波器对输入图像做平滑处理 (大小为 5x5 的高斯核)去噪

 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);//转换格式 8uSobel(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 算子的检测效果优于梯度算子,能够检测出图像较细的边缘部分。不同的系统,针对不同的环境条件和要求,选择合适的算子来对图像进行边缘检测。


http://chatgpt.dhexx.cn/article/JahWAHoO.shtml

相关文章

用OpenCV的边缘检测

使用OpenCV的边缘检测 代码如下&#xff1a; #include "infer.h"using namespace cv; using namespace std;int main::getResult(string fileName) {Mat src imread(fileName);Mat dst;cvtColor(src, src, COLOR_BGR2GRAY);blur(src, src, Size(3, 3));Canny(src,…

基于opencv的边缘检测方法

1、梯度运算 用OpenCV的形态变换&#xff08; 膨胀、腐蚀、开运算和闭运算&#xff09;函数morphologyEx 梯度运算即膨胀结果-腐蚀结果&#xff1a; 【注意】对于二值图像来说&#xff0c;必须是前景图像为白色&#xff0c;背景为黑色&#xff0c;否则需要进行反二值化处理 …

OpenCV——Canny边缘检测

目录 简介 实现步骤 代码 原图 效果图 简介 Canny边缘检测是一种使用多级边缘检测算法检测边缘的方法。 实现步骤 step1&#xff1a;去噪。噪声会影响边缘检测的准确性&#xff0c;因此首先要将噪声过滤掉。 方法&#xff1a;图像边缘容易受到噪声的干扰&#xff0c;因此…

OpenCV——边缘检测原理

边缘检测原理 图像的边缘指的是图像中像素灰度值突然发生变化的区域&#xff0c;如果将图像的每一行像素和每一列像素都描述成一个关于灰度值的函数&#xff0c;那么图像的边缘对应在灰度值函数中是函数值突然变大的区域。函数值的变化趋势可以用函数的导数描述。当函数值突然…

OpenCV 边缘检测之Canny算法(代码应用)

Canny算法 Canny是边缘检测算法&#xff0c;在1986年提出的。 是一个很好的边缘检测器 很常用也很实用的图像处理方法 Canny算法步骤 消除噪声&#xff1a;高斯模糊 - GaussianBlur灰度转换 - cvtColor计算梯度 – Sobel/Scharr非最大信号抑制高低阈值输出二值图像 API&…

opencv边缘检测加提取(圆形和矩形)

因为加密了的原因&#xff0c;不好直接复制&#xff0c;大家看一下代码就好。

OpenCV之边缘检测

1.图片的高斯模糊 import cv2 import matplotlib.pyplot as pltimg cv2.imread(r"C:\Users\Curry\Desktop\goutou.png") gray cv2.cvtColor(img, codecv2.COLOR_BGR2GRAY) gray2 cv2.GaussianBlur(gray,(19,19),0) #高斯模糊 # canny cv2.Canny()cv2.imshow(gra…

OpenCV如何进行图像的边缘检测?OpenCV边缘检测操作流程

OpenCV提供了几种常见的图像边缘检测算法&#xff0c;包括Sobel算子、Scharr算子、Laplacian算子和Canny边缘检测算法。下面分别介绍这些算法及其实现方法。 Sobel算子 Sobel算子是一种常见的图像边缘检测算法&#xff0c;其原理是通过对图像进行卷积操作&#xff0c;计算出图像…

opencv-边缘检测

文章目录 一、Canny边缘检测1.1高斯滤波器2.1梯度和方向3.1非极大值抑制4.1双阈值检测 一、Canny边缘检测 Canny边缘检测器是一种被广泛使用的算法&#xff0c;并被认为是边缘检测最优的算法&#xff0c;该方法使用了比高斯差分算法更复杂的技巧&#xff0c;如多向灰度梯度和滞…

opencv边缘检测算子

实验三 边缘检测算子 一、 实验目的 利用opencv或其他工具编写实现下图的sobel算子和robert算子边缘检测 二、 实验过程 利用opencv python实现sobel算子和robert算子边缘检测 (1)在python安装opencv库 这个步骤我在第二个实验&#xff0c;图像滤波里写过了&#xff0c;就不…

OpenCV:边缘检测算法

边缘检测&#xff08;英语&#xff1a;Edge detection&#xff09;是图像处理和计算机视觉中的基本问题&#xff0c;边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。这些包括&#xff08;i&#xff09;深度上的不连续、…

opencv边缘检测 roberts算子

定义roberts两个算子 分别为135度 和45度。 [1,0, 0,-1] [0,1 -1,0] 这里展示在c实现的过程。先展示下效果图 分别是45度角 135度角和边缘效果图。 #include<opencv2/opencv.hpp> #include<opencv2/core/core.hpp> #include<opencv2/imgproc/imgproc.hpp> #…

基于QT+OpenCV边缘检测、面积检测

没什么好说的就是调库&#xff0c;直接看下效果图&#xff0c;&#xff0c;基于OPENC4.5.1&#xff0c;如需要请 原图&#xff1a; 对图形进行描边并进行标号 面积检测

【学习OpenCV4】OpenCV边缘检测算法总结

本文分享内容来自图书《学习OpenCV 4&#xff1a;基于Python的算法实战》&#xff0c;该书内容如下&#xff1a; 第1章 OpenCV快速入门&#xff1b; 第2章 图像读写模块imgcodecs&#xff1b; 第3章 核心库模块core&#xff1b; 第4章 图像处理模块imgproc&#xff08;一&…

Opencv边缘检测、轮廓发现、绘制轮廓

Opencv边缘检测、轮廓发现、绘制轮廓 提取图像轮廓的2个步骤 1、 findContours函数找轮廓&#xff0c; 2、 drawContours函数画轮廓 轮廓的查找——cv::findContours() 函数cv::findContour是从二值图像中来计算轮廓的&#xff0c;它可以使用cv::Canny()函数处理的图像&am…

基于Python的Opencv边缘检测

边缘检测实际上就是对图像进行系统的梯度计算&#xff0c;包含了图像的噪声处理&#xff0c;非极大值抑制&#xff0c;双阈值检测等一系列图像处理方式&#xff0c;通过这些方式处理图像后得到图像的轮廓。这些方式在之前的博客都已经提到过i了&#xff0c;而Opencv提供了一个非…

OpenCV 边缘检测

一. 实验内容 用OpenCV对图片进行边缘检测。 二. 实验代码 //边缘检测 class Task17 { public:void deal() {Mat src_img imread("img\\1.jpg");imshow("边缘检测[原图]", src_img);Mat gray_img;cvtColor(src_img, gray_img, COLOR_BGR2GRAY);Mat out…

java-opencv边缘检测

安装opencv 导入jar包需要dll jar包在opencv\build\java目录里&#xff0c;dll文件在opencv\build\java\64x目录里 边缘检测 package opencv;import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc…

python opencv边缘检测

通过Opencv进行边缘检测可以说是十分常见了&#xff0c;接下来让我们聊一聊如何通过python opencv一步一步实现边缘检测 重要函数讲解 图片读取函数: pic cv2.imread(file_path, flagNone) 参数&#xff1a; file_path:读取的图片的路径。这里要注意如果图像不能读取(由于…

python-opencv边缘检测

9.python-opencv边缘检测 第一章 python-opencv-图片导入和显示 第二章 python-opencv图像简单处理 第三章 python-opencv图像mask掩膜处理 第四章 python-opencv图像马赛克 第五章 python-opencv人脸马赛克 第六章 python-opencv人脸检测 第七章 python-opencv图像张贴 第八章…