OpenCV15-图像边缘检测:Sobel、Scharr、Laplace、Canny

这篇具有很好参考价值的文章主要介绍了OpenCV15-图像边缘检测:Sobel、Scharr、Laplace、Canny。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


1.边缘检测原理

图像的边缘指的是图像中像素灰度值突然发生变化的区域,如果将图像中的每一行像素和每一列像素都描述成一个关于灰度值的函数,那么图像的边缘对应在灰度值函数中是函数值突然变大的区域。函数值得变化趋势可以用导数描述,当函数值突然变大时,导数也必然会变大,而函数值变化较为平缓时,导数值也比较小,因此可以通过寻找导数值较大的区域寻找函数中突然变化的区域,进而确定图像中的边缘位置。

由于图像是练得信号,因此我们可以用临近的两个像素值来表示像素灰度值函数的导数,求导形式表示如下:
d f ( x , y ) d x = f ( x , y ) − f ( x − 1 , y ) \frac{df(x,y)}{dx} = f(x,y) - f(x-1,y) dxdf(x,y)=f(x,y)f(x1,y)
这种对x轴方向的滤波器为 [ − 1 1 ] \begin{bmatrix} -1 & 1 \end{bmatrix} [11],同样对y轴方向的求导对应的滤波器为 [ − 1 1 ] T \begin{bmatrix} -1 & 1 \end{bmatrix}^T [11]T

而表示某个像素处的梯度,最接近的方式是求取前一个像素和后一个像素的差值,于是修改上式为:
d f ( x , y ) d x = f ( x + 1 , y ) − f ( x − 1 , y ) 2 \frac{df(x,y)}{dx} = \frac{f(x+1,y) - f(x-1,y)}{2} dxdf(x,y)=2f(x+1,y)f(x1,y)
改进的求导方式对应的滤波器在 X 方向和 Y 方向分别为 [ − 0.5 0 0.5 ] \begin{bmatrix} -0.5 & 0 & 0.5 \end{bmatrix} [0.500.5] [ − 0.5 0 0.5 ] T \begin{bmatrix} -0.5 & 0 & 0.5 \end{bmatrix}^T [0.500.5]T

根据这种方式,也可以使用下面的滤波器计算 4 5 ∘ 45^\circ 45 方向的梯度:

X Y = [ 1 0 0 − 1 ] Y X = [ 0 1 − 1 0 ] XY = \begin{bmatrix} 1 & 0 \\ 0 & -1 \\ \end{bmatrix} YX = \begin{bmatrix} 0 & 1 \\ -1 & 0 \\ \end{bmatrix} XY=[1001]YX=[0110]

图像的边缘有可能是由高像素值变为低像素值,也有可能是由低像素值变成高像素值。通过上面的梯度公式,得到正数值表示像素值突然由低变高,得到的负数值表示像素值由高到低,这两种都是图像的边缘,因此,为了在图像中同时表示出这两种边缘信息,需要将计算的结果求取绝对值。

OpenCV中提供了 convertScaleAbs() 函数用于计算矩阵中的所有数据的的绝对值:

void convertScaleAbs(
    InputArray src,    // 输入图像
    OutputArray dst,   // 输出图像
    double alpha = 1,  // 缩放因子
    double beta = 0    // 偏置值
);

下面代码中给出了利用 filter2D() 函数实现图像边缘检测的算法,需要说明的是,由于求取边缘的结果可能会有负值,不在原始图像的 CV_8U 数据范围内,因此滤波后的图像数据类型不要用 “-1” ,而应该为 CV_16S。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//创建边缘检测滤波器
	Mat kernel1 = (Mat_<float>(1, 2) << 1, -1);  //X方向边缘检测滤波器
	Mat kernel2 = (Mat_<float>(1, 3) << 1, 0, -1);  //X方向边缘检测滤波器
	Mat kernel3 = (Mat_<float>(3, 1) << 1, 0, -1);  //X方向边缘检测滤波器
	Mat kernelXY = (Mat_<float>(2, 2) << 1, 0, 0, -1);  //由左上到右下方向边缘检测滤波器
	Mat kernelYX = (Mat_<float>(2, 2) << 0, -1, 1, 0);  //由右上到左下方向边缘检测滤波器

	//读取图像,黑白图像边缘检测结果较为明显
	Mat img = imread("equalLena.png", IMREAD_ANYCOLOR);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat result1, result2, result3, result4, result5, result6;

	//检测图像边缘
	//以[1 -1]检测水平方向边缘
	filter2D(img, result1, CV_16S, kernel1);
	convertScaleAbs(result1, result1);

	//以[1 0 -1]检测水平方向边缘
	filter2D(img, result2, CV_16S, kernel2);
	convertScaleAbs(result2, result2);

	//以[1 0 -1]'检测由垂直方向边缘
	filter2D(img, result3, CV_16S, kernel3);
	convertScaleAbs(result3, result3);

	//整幅图像的边缘
	result6 = result2 + result3;
	//检测由左上到右下方向边缘
	filter2D(img, result4, CV_16S, kernelXY);
	convertScaleAbs(result4, result4);

	//检测由右上到左下方向边缘
	filter2D(img, result5, CV_16S, kernelYX);
	convertScaleAbs(result5, result5);

	//显示边缘检测结果
	imshow("result1", result1);
	imshow("result2", result2);
	imshow("result3", result3);
	imshow("result4", result4);
	imshow("result5", result5);
	imshow("result6", result6);

	waitKey(0);
	return 0;
}

2.Sobel算子

使用Sobel边缘检测算子提取图像边缘的过程:

1.提取 X 方向的边缘,X方向的一阶 Sobel 边缘检测算子:
[ − 1 0 1 − 2 0 2 − 1 0 1 ] \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \\ \end{bmatrix} 121000121
2.提取 Y 方向的边缘,Y方向的一阶 Sobel 边缘检测算子:
[ − 1 − 2 − 1 0 0 0 1 2 1 ] \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \\ \end{bmatrix} 101202101
3.综合两个方向的边缘信息得到整幅图像的边缘。由两个方向的边缘得到整幅图像的边缘有两种计算方式,第一种是求取两幅图像对应像素的像素值的绝对值之和,第二种是求取两幅图像对应像素值的平方和的二次方根:
I ( x , y ) = I x ( x , y ) 2 + I y ( x , y ) 2 I ( x , y ) = ∣ I x ( x , y ) ∣ + ∣ I y ( x , y ) ∣ \begin{align} I(x,y) &= \sqrt{I_x(x,y)^2 + I_y(x,y)^2} \\ I(x,y) &= |I_x(x,y)| + |I_y(x,y)| \\ \end{align} I(x,y)I(x,y)=Ix(x,y)2+Iy(x,y)2 =Ix(x,y)+Iy(x,y)
OpenCV提供了对图像提取 Sobel 边缘的 Sobel() 函数:

void Sobel(
    InputArray src, 
    OutputArray dst, 
    int ddepth, // 输出图像的数据类型,-1表示自动选择
    int dx, // X方向差分阶数,即使用几阶Sobel算子
    int dy, // Y方向差分阶数,即使用几阶Sobel算子
    int ksize = 3, // Sobel算子尺寸,必须是1,3,5,7
    double scale = 1, // 对导数计算结果进行缩放
    double delta = 0, // 偏置值
    int borderType = BORDER_DEFAULT
);

dx、dy、ksize:任意一个方向的差分阶数都需要小于算子的尺寸。但有以下特殊情况:当ksize=1时,任意一个方向的阶数都需要小于3。

一般情况下,当差分阶数的最大值取1时,ksize取3;当差分阶数的最大值取2时,ksize取5;当差分阶数的最大值取3时,ksize取7;

当ksize=1时,程序中使用的算子尺寸不再是正方形,而是3x1或者1x3。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//读取图像,黑白图像边缘检测结果较为明显
	Mat img = imread("equalLena.png", IMREAD_ANYCOLOR);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat resultX, resultY, resultXY;

	//X方向一阶边缘
	Sobel(img, resultX, CV_16S, 1, 0, 1);
	convertScaleAbs(resultX, resultX);

	//Y方向一阶边缘
	Sobel(img, resultY, CV_16S, 0, 1, 3);
	convertScaleAbs(resultY, resultY);

	//整幅图像的一阶边缘
	resultXY = resultX + resultY;

	//显示图像
	imshow("resultX", resultX);
	imshow("resultY", resultY);
	imshow("resultXY", resultXY);

	waitKey(0);
	return 0;
}

3.Scharr算子

虽然Sobel算子可以有效地提取图像边缘,但是对于图像中较弱的边缘提取效果较差。因此,为了能够有效地提出较弱的边缘,需要将像素值间的差距值增大。

Socharr算子是对Sobel算子差异性的增强,两者在检测图像边缘的原理和使用方式上相同,Scharr算子在X方向和Y方向的边缘检测算子:
G x = [ − 3 0 3 − 10 0 10 − 3 0 3 ] G y = [ − 3 − 10 − 3 0 0 0 3 10 3 ] G_x = \begin{bmatrix} -3 & 0 & 3 \\ -10 & 0 & 10 \\ -3 & 0 & 3 \\ \end{bmatrix} G_y = \begin{bmatrix} -3 & -10 & -3 \\ 0 & 0 & 0 \\ 3 & 10 & 3 \\ \end{bmatrix} Gx= 31030003103 Gy= 30310010303
OpenCV提供了对图像提取Scharr边缘的 Scharr() 函数:

void Scharr(
    InputArray src, 
    OutputArray dst, 
    int ddepth,
    int dx, 
    int dy, 
    double scale = 1, 
    double delta = 0,
    int borderType = BORDER_DEFAULT
);

dx和dy只能有一个为1,并且不能同时为0。

下面代码中,分别提取X方向和Y方向边缘,并利用这两个方向的边缘求取整幅图像的边缘。可以看出Scharr算子比Sobel算子提取到更微弱的边缘。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//读取图像,黑白图像边缘检测结果较为明显
	Mat img = imread("equalLena.png", IMREAD_ANYDEPTH);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat resultX, resultY, resultXY;

	//X方向一阶边缘
	Scharr(img, resultX, CV_16S, 1, 0);
	convertScaleAbs(resultX, resultX);

	//Y方向一阶边缘
	Scharr(img, resultY, CV_16S, 0, 1);
	convertScaleAbs(resultY, resultY);

	//整幅图像的一阶边缘
	resultXY = resultX + resultY;

	//显示图像
	imshow("resultX", resultX);
	imshow("resultY", resultY);
	imshow("resultXY", resultXY);

	waitKey(0);
	return 0;
}

4.生成边缘检测滤波器

Scharr算子只有上面的两种,而Sobel算子有不同的尺寸、不同阶数。OpenCV中提供了 getDerivKernels() 函数可以得到不同尺寸、不同阶数的Sobel算子和Scharr算子滤波器。

void getDerivKernels(
    OutputArray kx, // 行滤波器系数输出矩阵 ksize x 1
    OutputArray ky, // 列滤波器系数输出矩阵 ksize x 1 
    int dx,     // X方向导数的阶次
    int dy,     // Y方向导数的阶次
    int ksize,  // 滤波器的大小可以为FILTER_SCHARR、1、3、5、7
    bool normalize = false, // 是否归一化
    int ktype = CV_32F      // 滤波器系数类型,CV_32F、CV_64F
);

下面的例子中给出利用 getDerivKernels() 函数生成Sobel算子和Scharr算子的代码:

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	Mat sobel_x1, sobel_y1, sobel_x2, sobel_y2, sobel_x3, sobel_y3;  //存放分离的Sobel算子
	Mat scharr_x, scharr_y;  //存放分离的Scharr算子
	Mat sobelX1, sobelX2, sobelX3, scharrX;  //存放最终算子

	//一阶X方向Sobel算子
	getDerivKernels(sobel_x1, sobel_y1, 1, 0, 3);
	sobel_x1 = sobel_x1.reshape(CV_8U, 1);
	sobelX1 = sobel_y1 * sobel_x1;  //计算滤波器

	//二阶X方向Sobel算子
	getDerivKernels(sobel_x2, sobel_y2, 2, 0, 5);
	sobel_x2 = sobel_x2.reshape(CV_8U, 1);
	sobelX2 = sobel_y2 * sobel_x2;  //计算滤波器

	//三阶X方向Sobel算子
	getDerivKernels(sobel_x3, sobel_y3, 3, 0, 7);
	sobel_x3 = sobel_x3.reshape(CV_8U, 1);
	sobelX3 = sobel_y3 * sobel_x3;  //计算滤波器

	//X方向Scharr算子
	getDerivKernels(scharr_x, scharr_y, 1, 0, FILTER_SCHARR);
	scharr_x = scharr_x.reshape(CV_8U, 1);
	scharrX = scharr_y * scharr_x;  //计算滤波器

	//输出结果
	cout << "X方向一阶Sobel算子:" << endl << sobelX1 << endl;
	cout << "X方向二阶Sobel算子:" << endl << sobelX2 << endl;
	cout << "X方向三阶Sobel算子:" << endl << sobelX3 << endl;
	cout << "X方向Scharr算子:" << endl << scharrX << endl;

	waitKey(0);
	return 0;
}
/*
X方向一阶Sobel算子:
[-1, 0, 1;
 -2, 0, 2;
 -1, 0, 1]
X方向二阶Sobel算子:
[1, 0, -2, 0, 1;
 4, 0, -8, 0, 4;
 6, 0, -12, 0, 6;
 4, 0, -8, 0, 4;
 1, 0, -2, 0, 1]
X方向三阶Sobel算子:
[-1, 0, 3, 0, -3, 0, 1;
 -6, 0, 18, 0, -18, 0, 6;
 -15, 0, 45, 0, -45, 0, 15;
 -20, 0, 60, 0, -60, 0, 20;
 -15, 0, 45, 0, -45, 0, 15;
 -6, 0, 18, 0, -18, 0, 6;
 -1, 0, 3, 0, -3, 0, 1]
X方向Scharr算子:
[-3, 0, 3;
 -10, 0, 10;
 -3, 0, 3]
*/

5.Laplacian算子

上述的边缘检测算子都具有方向性,因此都需要分别求取X方向的边缘和Y方向的边缘,之后将两个方向的边缘综合得到图像的整体边缘。Laplacian算子具有各个方向同性的特点,能够对任意方向的边缘进行提取,具有无方向性的优点。

Laplacian算子是一种二阶导数算子,对噪声比较敏感,因此常需要配合高斯滤波一起使用。

二维图像函数 f ( x , y ) f(x,y) f(x,y) ,图像的Laplace运算二阶导数定义:
∇ 2 f ( x , y ) = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 \nabla^2 f(x,y) = \frac{\partial^2 f}{\partial x^2} + \frac{\partial^2 f}{\partial y^2} 2f(x,y)=x22f+y22f
对于二维离散图像而言,图像的Laplace可表示吐下:
∇ 2 f ( x , y ) = f ( x + 1 , y ) + f ( x − 1 , y ) + f ( x , y + 1 ) + f ( x , y − 1 ) − 4 f ( x , y ) \nabla^2 f(x,y) = f(x+1,y) + f(x-1,y) + f(x,y+1) + f(x,y-1) - 4f(x,y) 2f(x,y)=f(x+1,y)+f(x1,y)+f(x,y+1)+f(x,y1)4f(x,y)
根据离散Laplace表达式,可以得到其滤波器:
G 1 = [ 0 1 0 1 − 4 1 0 1 0 ] G 2 = [ 1 1 1 1 − 8 1 1 1 1 ] G_1 = \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \\ \end{bmatrix} G_2 = \begin{bmatrix} 1 & 1 & 1 \\ 1 & -8 & 1 \\ 1 & 1 & 1 \\ \end{bmatrix} G1= 010141010 G2= 111181111
G 1 G_1 G1 G 2 G_2 G2 分别为离散拉普拉斯算子的模版与拓展模版,利用函数模版可以将图像中的奇异点如亮点变得更亮。对于图像中灰度变化剧烈的区域,拉普拉斯算子能实现其边缘检测。

OpenCV提供了Laplacian算子提取图像边缘的 Laplacian() 函数:

void Laplacian(
    InputArray src,
    OutputArray dst, 
    int ddepth,
    int ksize = 1,    // 滤波器大小,必须为正奇数
    double scale = 1, 
    double delta = 0,
    int borderType = BORDER_DEFAULT
);

ksize=1时,采用 G 1 G_1 G1 拉普拉斯算子。

下面代码中,采用图像去噪后通过拉普拉斯算子提取边缘变得更加准确:

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//读取图像,黑白图像边缘检测结果较为明显
	Mat img = imread("equalLena.png", IMREAD_ANYDEPTH);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat result, result_g, result_G;

	//未滤波提取边缘
	Laplacian(img, result, CV_16S, 3, 1, 0);
	convertScaleAbs(result, result);

	//滤波后提取Laplacian边缘
	GaussianBlur(img, result_g, Size(3, 3), 5, 0);  //高斯滤波
	Laplacian(result_g, result_G, CV_16S, 3, 1, 0);
	convertScaleAbs(result_G, result_G);

	//显示图像
	imshow("result", result);
	imshow("result_G", result_G);

	waitKey(0);
	return 0;
}

6.Canny算法

Canny算法不容易受到噪声的影响,能够识别图像中的若边缘和强边缘,并结合强弱边缘的位置关系,综合给出图像整体的边缘信息。Canny边缘检测算法是目前最优越的边缘检测算法之一。该方法的检测过程:

1.使用高斯滤波去噪,平滑图像,下面是5x5的高斯滤波器:
G = 1 139 [ 2 4 5 4 2 4 9 12 9 4 5 12 15 12 5 4 9 12 9 4 2 4 5 4 2 ] G = \frac{1}{139} \begin{bmatrix} 2 & 4 & 5 & 4 & 2 \\ 4 & 9 & 12 & 9 & 4 \\ 5 & 12 & 15 & 12 & 5 \\ 4 & 9 & 12 & 9 & 4 \\ 2 & 4 & 5 & 4 & 2 \\ \end{bmatrix} G=1391 245424912945121512549129424542
2.计算图像中每个像素的梯度幅值与方向。可以通过Sobel算子分别检测图像X方向和Y方向边缘,之后利用下面公式计算梯度的方向和幅值:
θ = a r c t a n ( I y I x ) G = a r c t a n I x 2 + I y 2 \theta = arctan(\frac{I_y}{I_x}) \\ G = arctan\sqrt{I_x^2 + I_y^2} θ=arctan(IxIy)G=arctanIx2+Iy2
其中梯度方向近似到下面4个取值: 0 ∘ 0^\circ 0 4 5 ∘ 45^\circ 45 9 0 ∘ 90^\circ 90 13 5 ∘ 135^\circ 135

3.利用非极大值抑制算法消除边缘检测带来的杂散响应。通俗意义上是指寻找像素点局部最大值,将非极大值点所对应的灰度值设置为背景像素点,如像素领域区域满足梯度值的局部最优值判断为该像素的边缘,对其余非极大值的相关信息进行抑制。

4.应用双阈值法划分强边缘和弱边缘。如果某一像素位置的幅值超过高阈值,该像素被保留为边缘;如果某一像素位置的幅值小于低阈值,该像素被排除;如果某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于阈值的像素时被保留。推荐高与低阈值比在 2:13:1 之间。

Canny算法流程复杂,好在OpenCV中提供了 Canny() 函数实现Canny算法检测图像中的边缘:

void Canny(
    InputArray image,  // CV_8U
    OutputArray edges, 
    double threshold1, // 第一个滞后阈值
    double threshold2, // 第二个滞后阈值
    int apertureSize = 3,   // Sobel算子直径
    bool L2gradient = false // 计算图像梯度幅值的方法是否使用L2范数
);

下面的代码中,通过设置不同的阈值来比较阈值的大小对图像边缘检测效果的影响,可以发现,较高的阈值会降低噪声信息的影响,但是也会减少边缘信息。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//读取图像,黑白图像边缘检测结果较为明显
	Mat img = imread("equalLena.png", IMREAD_ANYDEPTH);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat resultHigh, resultLow, resultG;

	//大阈值检测图像边缘
	Canny(img, resultHigh, 100, 200, 3);

	//小阈值检测图像边缘
	Canny(img, resultLow, 20, 40, 3);

	//高斯模糊后检测图像边缘
	GaussianBlur(img, resultG, Size(3, 3), 5);
	Canny(resultG, resultG, 100, 200, 3);

	//显示图像
	imshow("resultHigh", resultHigh);
	imshow("resultLow", resultLow);
	imshow("resultG", resultG);

	waitKey(0);
	return 0;
}

OpenCV15-图像边缘检测:Sobel、Scharr、Laplace、Canny,OpenCV,opencv,计算机视觉,c++文章来源地址https://www.toymoban.com/news/detail-721885.html

到了这里,关于OpenCV15-图像边缘检测:Sobel、Scharr、Laplace、Canny的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Halcon边缘检测Sobel、Laplace和Canny算子

    提示:文章参考了网络上其他作者的文章,以及相关书籍,如有侵权,请联系作者。        除了阈值分割外,也可以通过检测区域的边缘得到目标区域。区域的边缘像素的灰度值往往会发生灰度上的突变,针对这些跳跃性的突变进行检测和计算,可以得到区域的边缘轮廓

    2023年04月08日
    浏览(43)
  • Python边缘检测之prewitt, sobel, laplace算子

    ndimage 中提供了卷积算法,并且建立在卷积之上,提供了三种边缘检测的滤波方案: prewitt , sobel 以及 laplace 。 在convolve中列举了一个用于边缘检测的滤波算子,统一维度后,其 x x x 和 y y y 向的梯度算子分别写为 [ − 1 0 1 − 1 0 1 − 1 0 1 ] , [ − 1 − 1 − 1 0 0 0 1 1 1 ] begin{bma

    2024年02月03日
    浏览(41)
  • Halcon经典的边缘检测算子Sobel/Laplace/Canny

    关于边缘检测,有许多经典的算子,各大图形处理库都有各自的边缘检测算子,这里简要介绍几种。 Sobel算子结合了高斯平滑和微分求导。它是一阶导数的边缘检测算子,使用卷积核对图像中的每个像素点做卷积和运算,然后采用合适的阈值提取边缘。Soble算子有两个卷积核

    2024年01月22日
    浏览(51)
  • opencv基础41-图像梯度-sobel算子详解cv2.Sobel()(边缘检测基础)

    图像梯度是用于描述图像变化率的概念。在图像处理中,梯度指的是图像中每个像素的灰度值变化速率或方向。它常用于边缘检测和图像特征提取。 一维图像的梯度表示为函数 f(x) 的导数,而在二维图像中,梯度是一个向量,包含两个分量:水平方向和垂直方向的灰度变化率

    2024年02月14日
    浏览(48)
  • OpenCV——Scharr边缘检测

    OpenCV——Scharr边缘检测由CSDN点云侠原创,爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。    Scharr边缘检测算法是对Sobel算子差异性的增强,因此两者在检测图像边缘的原理和使用方式上相同。Scharr算子的边缘检测滤波尺寸为3x3,因此也

    2024年01月23日
    浏览(40)
  • 【Opencv入门到项目实战】(四):图像梯度计算|Sobel算子|Scharr算子|Laplacian算子

    在图像处理中,梯度是指图像中像素灰度变化的速率或幅度,我们先来看下面这张图 假设我们想要计算出A点的梯度,我们可以发现A点位于边缘点,A点左边为黑色,右边为白色,而计算图像的梯度可以提取出图像中的边缘信息,我们常用的方法是使用 Sobel算子 或 Scharr算子

    2024年02月13日
    浏览(51)
  • 《opencv实用探索·十二》opencv之laplacian(拉普拉斯)边缘检测,Scharr边缘检测,Log边缘检测

    1、Laplacian算子 Laplacian(拉普拉斯)算子是一种二阶导数算子,其具有旋转不变性,可以满足不同方向的图像边缘锐化(边缘检测)的要求。同时,在图像边缘处理中,二阶微分的边缘定位能力更强,锐化效果更好,因此在进行图像边缘处理时,直接采用二阶微分算子而不使

    2024年04月10日
    浏览(40)
  • 【OpenCv • c++】基础边缘检测算子 —— Laplace

    🚀 个人简介:CSDN「 博客新星 」TOP 10 , C/C++ 领域新星创作者 💟 作    者: 锡兰_CC ❣️ 📝 专    栏: 【OpenCV • c++】计算机视觉 🌈 若有帮助,还请 关注➕点赞➕收藏 ,不行的话我再努努力💪💪💪        边缘检测是图像处理与计算机视觉中最重要的技术之一,

    2024年02月05日
    浏览(71)
  • openCV实战-系列教程4:图像梯度计算(Sobel算子/开运算/梯度计算方法/scharr算子/lapkacian算子)、源码解读 ?????OpenCV实战系列总目录

    打印一个图片单独做出一个函数: 先读进来一个原型白色图 打印结果: 如图有两个3*3的卷积核,其中A是原始图片中的一个3*3的区域,这个A和3*3的卷积核所谓对应位置相乘的结果就分别是左右梯度和上下梯度 假如A是这个矩阵:  那么Gx的计算结果就为:-x1+x3-2x4+2x6-x7+x9 代码实

    2024年02月10日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包