使用 Prewitt、Scharr 和 Sobel 算子进行边缘检测
在数字图像处理中,用于突出显示数字图像中物体的边界/边界的技术称为边缘检测。我们可以使用 MATLAB 执行此操作。为此,MATLAB 库中定义了几个不同的内置函数和运算符。
在本教程中,我将解释三个这样的运算符,即"Prewitt 算子"、"Scharr 算子"和"Sobel 算子"。这三个运算符都是 MATLAB 库中常用的基于梯度的边缘检测运算符。
在讨论这些边缘检测运算符之前,让我们先简要概述一下边缘检测技术。
什么是边缘检测?
边缘检测是数字图像处理中的一个过程,用于检测数字图像中对象的边界。
在边缘检测过程中,会突出显示图像中发生快速强度变化的区域。
在图像处理领域,边缘检测很重要,因为它有助于对象识别、图像分割、提取图像中的重要特征、图像质量增强、图像压缩等。
它通常用于各种领域,例如工业应用中的质量控制、检测肿瘤的医学成像、计算机视觉中的物体检测(如自动驾驶汽车、机器人等)、遥感、图像编辑和更多。
现在,让我们讨论如何使用"Prewitt 算子"、"Scharr 算子"和"Sobel 算子"在 MATLAB 中执行边缘检测。
在 MATLAB 中使用 Prewitt 算子进行边缘检测
Prewitt 算子是一种基于梯度的边缘检测算子,用于检测数字图像中对象的边界。为了检测和突出显示边缘,Prewitt 算子会近似每个像素处图像强度的梯度。
从技术上讲,Prewitt 算子利用两个 3×3 卷积核来检测边缘。一个用于检测水平边缘,另一个用于检测图像中对象的垂直边缘。这些内核如下所示。
水平内核
-1 0 1 -1 0 1 -1 0 1
垂直核
0 0 0 1 1 1
这些 Prewitt 核与图像进行卷积,以计算每个像素的梯度强度。其中,水平核计算从左到右(即沿水平方向)的梯度强度变化。而垂直核计算从上到下(即沿垂直方向)的梯度强度变化。最后,将两个梯度图像组合起来,得到边缘突出的结果图像。
Prewitt 运算符语法
在 MATLAB 中,要应用 Prewitt 运算符来检测图像中的边缘,请使用"imfilter"函数。它将具有以下语法:
out_img = imfilter(in_img, prewitt_kernel);
这里,"in_img"是要执行边缘检测的输入图像。"kernel"是 Prewitt 运算符内核。
示例 (1)
以下示例演示了 Prewitt 运算符的实现,用于检测图像中的边缘。
% 使用 Prewitt 运算符进行边缘检测的 MATLAB 代码 % 加载输入图像 in_img = imread('https://www.tutorialspoint.com/assets/questions/media/14304-1687425236.jpg'); % 将输入图像转换为灰度 gray_img = rgb2gray(in_img); % 将图像转换为双精度以便计算 gray_img = double(gray_img); % 指定 Prewitt 算子核 h_kernel = [-1, 0, 1; -1, 0, 1; -1, 0, 1]; % 水平核 v_kernel = [-1, -1, -1; 0, 0, 0; 1, 1, 1]; % 垂直核 % 使用 Prewitt 算子核计算梯度强度 h_gradient = imfilter(gray_img, h_kernel); v_gradient = imfilter(gray_img, v_kernel); % 计算梯度幅度 gradient_magnitude = sqrt(h_gradient.^2 + v_gradient.^2); % 显示原始图像和边缘检测图像 figure; subplot(2, 1, 1); imshow(in_img); title('原始图像'); subplot(2, 1, 2); imshow(uint8(gradient_magnitude)); title('Prewitt 边缘检测图像');
输出

代码说明
在此 MATLAB 示例中,我们首先读取输入图像,然后将其转换为灰度和双精度以进行计算。之后,我们定义水平和垂直 Prewitt 核,并使用"imfilter"函数将 Prewitt 算子应用于输入图像以进行边缘检测。
接下来,我们计算梯度幅度,这基本上是对图像中检测到的对象边缘的可视化。最后,我们使用"imshow"函数显示原始图像和边缘检测图像。
在 MATLAB 中使用 Scharr 算子进行边缘检测
与 Prewitt 算子类似,Scharr 算子是 MATLAB 中用于检测图像内对象边界的另一个边缘检测算子。
此算子专门用于我们必须检测对角线边缘的地方,因为它具有更多的旋转对称边缘检测特性。因此,Scharr 算子在边缘检测中提供了相对更好的结果。
然而,这也是一个基于梯度的边缘检测算子,利用两个 3×3 卷积核来近似图像每个像素的梯度强度。这里,一个 Scharr 核用于检测水平边缘,而另一个用于检测垂直边缘。这些 Scharr 核如下所示。
水平 Scharr 核
-3 0 3 -10 0 10 -3 0 3
垂直 Scharr 核
-3 -10 -3 0 0 0 3 10 3
这两个核与图像进行卷积,以检测输入图像内物体的边缘。
Scharr 运算符语法
在 MATLAB 中,使用"imfilter"函数应用 Scharr 运算符,该函数具有以下语法,
out_img = imfilter(in_img, scharr_kernel);
现在,让我们了解如何在 MATLAB 中实现代码以使用 Scharr 运算符执行边缘检测。
示例 (2)
% 使用 Scharr 运算符执行边缘检测的 MATLAB 代码 % 加载输入图像 in_img = imread('https://www.tutorialspoint.com/assets/questions/media/14304-1687425236.jpg'); % 将输入图像转换为灰度 gray_img = rgb2gray(in_img); % 将图像转换为双精度以便更好地计算 gray_img = double(gray_img); % 指定 Scharr 运算符核 h_kernel = [-3, 0, 3; -10, 0, 10; -3, 0, 3]; % 水平核 v_kernel = [-3, -10, -3; 0, 0, 0; 3, 10, 3]; % 垂直核 % 使用 Scharr 算子核计算图像中的梯度 h_gradient = imfilter(gray_img, h_kernel); v_gradient = imfilter(gray_img, v_kernel); % 计算梯度幅度 gradient_magnitude = sqrt(h_gradient.^2 + v_gradient.^2); % 显示原始图像和边缘检测图像 figure; subplot(2, 1, 1); imshow(in_img); title('原始图像'); subplot(2, 1, 2); imshow(uint8(gradient_magnitude)); title('Scharr 边缘检测图像');
输出

代码说明
此代码的实现与 Prewitt 算子的代码类似。唯一的区别是,在此示例中,用于边缘检测的核是 Scharr 算子核。从输出图像中可以清楚地看出,Scharr 算子提供了更好的结果。
现在让我们了解如何使用 Sobel 算子来检测图像中对象的边缘。
在 MATLAB 中使用 Sobel 算子进行边缘检测
与 Prewitt 和 Scharr 算子类似,Sobel 算子也是基于梯度的边缘检测算子,用于数字图像处理以检测图像中对象的边界。该算子还使用两个 3×3 卷积核,即水平 Sobel 核和垂直 Sobel 核。这些 Sobel 核如下所示。
水平 Sobel 核
-1 0 1 -2 0 2 -1 0 1
垂直 Sobel 核
-1 -2 -1 0 0 0 1 2 1
使用 Sobel 算子检测边缘的过程与 Prewitt 和 Scharr 算子的过程类似。
Sobel 算子语法
在 MATLAB 中,Sobel 算子使用"imfilter"函数应用。为此,使用以下语法,
out_img = imfilter(in_img, sobel_kernel);
现在让我们举一个例子来理解如何使用 Sobel 算子检测图像中的边缘。
示例 (3)
% 使用 Sobel 算子检测边缘的 MATLAB 代码 % 加载输入图像 in_img = imread('https://www.tutorialspoint.com/assets/questions/media/14304-1687425236.jpg'); % 将输入图像转换为灰度 gray_img = rgb2gray(in_img); % 将灰度图像转换为双精度 gray_img = double(gray_img); % 指定 Sobel 算子核 h_kernel = [-1, 0, 1; -2, 0, 2; -1, 0, 1]; % 水平核 v_kernel = [-1, -2, -1; 0, 0, 0; 1, 2, 1]; % 垂直核 % 使用 Sobel 算子核计算梯度 h_gradient = imfilter(gray_img, h_kernel); v_gradient = imfilter(gray_img, v_kernel); % 计算梯度幅度 gradient_magnitude = sqrt(h_gradient.^2 + v_gradient.^2); % 显示原始图像和边缘检测图像 figure; subplot(2, 1, 1); imshow(in_img); title('原始图像'); subplot(2, 1, 2); imshow(uint8(gradient_magnitude)); title('Sobel 边缘检测图像');
输出

代码解释
代码实现和执行与上述两个示例类似。这里,我们仅使用 Sobel 算子核来检测边缘。
结论
在本教程中,我借助示例程序解释了所有这些算子。总之,Prewitt、Scharr 和 Sobel 算子用于使用 MATLAB 对数字图像中的对象进行边缘检测。