《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测

这篇具有很好参考价值的文章主要介绍了《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、前言

边缘检测:
图像边缘检测是指在图像中寻找灰度、颜色、纹理等变化比较剧烈的区域,它们可能代表着物体之间的边界或物体内部的特征。边缘检测是图像处理中的一项基本操作,可以用于人脸识别、物体识别、图像分割等多个领域。

边缘检测实质上是计算当前点和周围点灰度的差别。

图像边缘检测流程主要分为以下几个步骤:
(1)读取待处理图像;
(1)图像滤波,例如使用高斯滤波器,平滑图像,去除噪声;
(2)计算图像中每个像素点的梯度强度和方向;
(3)应用非极大值抑制(Non-Maximum Suooression),保留梯度方向上的局部最大值,抑制非边缘点,消除边缘检测带来的杂散响应;
(4)应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘,即将梯度幅值映射到两个阈值,根据梯度值高于高阈值或在高低阈值之间的情况,将像素标记为强边缘、弱边缘或非边缘。
(5)边缘连接,通过连接相邻的强边缘像素和与之相连的弱边缘像素,形成最终的边缘图像;
(6)显示结果。

在介绍各种边缘检测算子之前先简单阐述下怎么寻找边缘。

下面左图是一张黑白相间的图,右图是左图的每个像素的灰度值
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python
我们设定一个卷积核如下(关于卷积的介绍请看之前的文章):
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python
原图在通过卷积核进行卷积计算后得到的图像如下:
可以看到原图在卷积运算后黑色向白色突变的边缘被很好的保留了下来,因此可以通过这个卷积核找到图像中垂直的边缘。
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python
同理,如果我们用下面的卷积核也可以找到图像中水平的边缘。
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python
卷积运算后:
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python

2、Prewitt算子边缘检测
如果我们把上面两个卷积核组合起来再对图像进行卷积便可以同时找到图像中水平和垂直的边缘,这种卷积核就是prewitt算子。
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python

标准的 Prewitt 边缘检测算子由以下两个卷积核组成。
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python
下面是用prewitt算子进行边缘检测的案例:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;

int main() {
    // 读取图像
    Mat image = imread("your_image.jpg", IMREAD_GRAYSCALE);

    // 定义Prewitt算子
    Mat prewitt_x = (Mat_<float>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
    Mat prewitt_y = (Mat_<float>(3, 3) << -1, -1, -1, 0, 0, 0, 1, 1, 1);

    // 对图像应用Prewitt算子
    Mat edges_x, edges_y;
    filter2D(image, edges_x, CV_64F, prewitt_x);
    filter2D(image, edges_y, CV_64F, prewitt_y);

    // 计算梯度幅值和方向
    Mat gradient_magnitude, gradient_direction;
    magnitude(edges_x, edges_y, gradient_magnitude);
    phase(edges_x, edges_y, gradient_direction, true);

 	// 归一化梯度幅值
    cv::normalize(gradient_magnitude, gradient_magnitude, 0, 1, cv::NORM_MINMAX);

    // 显示结果
    imshow("Original Image", image);  //原灰度图
    imshow("Gradient Magnitude", gradient_magnitude);  //prewitt算子边缘检测图
    waitKey(0);
    destroyAllWindows();

    return 0;
}

代码解读:
(1)在代码中我们先分别定义一个水平方向和垂直方向的prewitt算子edges_x和edges_y
(2)filter2D是对图像进行卷积操作,即获取prewitt算子与原图像卷积后的图像edges_x和edges_y
(3)magnitude 函数的主要用途是计算两个输入数组的逐元素平方和的平方根。在图像处理中,常常用于计算图像中每个像素点的梯度幅值。相位(Phase)在图像处理中通常指的是梯度的方向(边缘方向)。在梯度计算中,梯度向量的方向表示图像在该点上灰度变化最快的方向。在梯度计算中,通常使用 magnitude 函数计算梯度的幅值,使用 phase 函数计算梯度的方向。这两个信息一起构成了梯度向量,提供了有关图像局部变化的重要信息。
(4)最后归一化梯度幅值图像,因为64位图像显示范围为0-1。

最后效果如下(左边是原灰度图,右边是边缘检测出的图像):
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python

3、Roberts算子
常用来处理具有陡峭的低噪声图像,当图像边缘接近于正45度或负45度时,该算法处理效果更理想。其缺点是对边缘的定位不太准确,提取的边缘线条较粗。

下图左边为水平方向Roberts算子,也称正对角算子。右边为垂直方向Roberts算子,也称斜对角算子。
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python
下面是Roberts算子的使用案例:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;

int main() {
    // 读取图像
    Mat image = imread("1.jpg", IMREAD_GRAYSCALE);

    if (image.empty()) {
        std::cerr << "Error: Could not read the image." << std::endl;
        return -1;
    }

    // 初始化 Roberts 算子
    Mat robertsX = (Mat_<float>(2, 2) << -1, 0, 0, 1); //这边要写成float类型,不能是Int
    Mat robertsY = (Mat_<float>(2, 2) << 0, -1, 1, 0);

    // 应用 Roberts 算子进行边缘检测
    Mat gradientX, gradientY;
    filter2D(image, gradientX, CV_64F, robertsX); //应用CV_64F,不能用默认-1,不然magnitude会抛出异常
    filter2D(image, gradientY, CV_64F, robertsY);

    // 计算梯度幅值
    Mat gradientMagnitude, gradient_direction;
    magnitude(gradientX, gradientY, gradientMagnitude);
    cv::phase(gradientX, gradientY, gradient_direction, true);  // true 表示计算角度,false计算弧度

    // 归一化梯度方向到[0, 1]范围,因为64位显示范围为0-1
    cv::normalize(gradientMagnitude, gradientMagnitude, 0, 1, cv::NORM_MINMAX);

    // 显示原始图像和边缘检测结果
    namedWindow("Original Image", WINDOW_NORMAL);
    namedWindow("Roberts Edge Detection", WINDOW_NORMAL);

    imshow("Original Image", image);
    imshow("Roberts Edge Detection", gradientMagnitude);

    waitKey(0);
    destroyAllWindows();

    return 0;
}

最后效果如下(左边是原灰度图,右边是边缘检测出的图像):
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python

4、Sobel算子边缘检测
Sobel算子在Prewitt算子的基础上增加了权重的概念,认为相邻点的距离远近对当前像素点的影响是不同的,距离越近的像素点对应当前像素的影响越大,从而实现图像锐化并突出边缘轮廓。但Sobel算子并不是基于图像灰度进行处理的,因为Sobel算子并没有严格地模拟人的视觉生理特性,因此图像轮廓的提取有时并不能让人满意。当对精度要求不是很高时,Sobel算子是一种较为常用的边缘检测方法。

它的水平和垂直方向的卷积核如下:
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python
接口说明:

void cv::Sobel(
    InputArray src,
    OutputArray dst,
    int ddepth,
    int dx,
    int dy,
    int ksize = 3,
    double scale = 1,
    double delta = 0,
    int borderType = cv::BORDER_DEFAULT
);

src: 输入图像。可以是单通道(灰度图)或多通道图像。
dst: 输出图像,梯度的计算结果将存储在这里。
ddepth: 输出图像的深度,通常使用 CV_64F 或 CV_32F 表示。
dx: x方向上的导数阶数,设为1表示在水平方向上进行操作。
dy: y方向上的导数阶数,设为1表示在垂直方向上进行操作。
ksize: Sobel核的大小。默认为 3,表示一个 3x3 的核。通常使用奇数值。
scale: 可选的比例因子,用于调整梯度的幅值,也表示对比度。
delta: 可选的偏移值,用于调整输出图像的亮度。
borderType: 边界处理类型,可以使用 cv::BORDER_DEFAULT 或其他合适的边界处理标志。

Sobel算子边缘检测案例:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

int main() {
    // 读取图像
    cv::Mat image = cv::imread("1.jpg", cv::IMREAD_GRAYSCALE);

    if (image.empty()) {
        std::cerr << "Error: Could not read the image." << std::endl;
        return -1;
    }

    // 应用Sobel算子
    cv::Mat sobelX, sobelY;
    cv::Sobel(image, sobelX, CV_64F, 1, 0, 3); // 1表示在水平方向上进行操作
    cv::Sobel(image, sobelY, CV_64F, 0, 1, 3); // 1表示在垂直方向上进行操作

    // 转换为绝对值,防止负值影响计算
    sobelX = cv::abs(sobelX);
    sobelY = cv::abs(sobelY);

    // 合并水平和垂直梯度
    cv::Mat sobelResult;
    cv::addWeighted(sobelX, 0.5, sobelY, 0.5, 0, sobelResult);

    // 将16位深度图像转换为8位深度,以便显示
    cv::Mat sobel8U;
    sobelResult.convertTo(sobel8U, CV_8U);

    // 显示原始图像和Sobel边缘检测结果
    cv::imshow("Original Image", image);
    cv::imshow("Sobel Edge Detection", sobel8U);
    cv::waitKey(0);

    return 0;
}

《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测,opencv实用学习,opencv,计算机视觉,人工智能,图像处理,c++,python文章来源地址https://www.toymoban.com/news/detail-836362.html

到了这里,关于《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Python图像锐化及边缘检测(Roberts、Prewitt、Sobel、Lapllacian、Canny、LOG)

    目录 图像锐化概述 算法方法介绍  代码实现 效果展示 图像锐化 (image sharpening) 是补偿图像的轮廓,增强图像的边缘及灰度跳变的部分,使图像变得清晰,分为空间域处理和频域处理两类。图像锐化是为了突出图像上地物的边缘、轮廓,或某些线性目标要素的特征。这种滤波

    2023年04月17日
    浏览(34)
  • 边缘检测——Roberts算子

    采用对角线方向相邻两象素之差近似梯度幅值检测边缘,是一个 2x2 的模版,模板分为水平方向和垂直方向。 模板:  计算公式: 最终计算公式:   原理: [说明] 边缘检测的对象只能是灰度图片 为什么这样的公式可以计算灰度图片的边缘呢?其实该公式利用的是物体边缘处

    2024年02月04日
    浏览(32)
  • 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日
    浏览(28)
  • 《opencv实用探索·十二》opencv之laplacian(拉普拉斯)边缘检测,Scharr边缘检测,Log边缘检测

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

    2024年04月10日
    浏览(29)
  • OpenCV(7):边缘检测之Sobel算子,Scharr算子,Laplacian算子和Canny算子边缘检测

    Sobel算子、Scharr算子、Laplacian算子和Canny算子都是常用的图像边缘检测算法。它们可以用来识别图像中物体之间的边界,从而对物体进行定位、跟踪、分割、识别等处理。 Sobel算子和Scharr算子都是基于卷积运算实现的边缘检测算法。Sobel算子使用两个3×3的矩阵对原始图像进行卷

    2024年02月05日
    浏览(40)
  • 我在Vscode学OpenCV 图像处理三(图像梯度--边缘检测【图像梯度、Sobel 算子、 Scharr 算子、 Laplacian 算子、Canny 边缘检测】)

    这里需要区分开边缘检测和轮廓检测 边缘检测并非万能,边缘检测虽然能够检测出边缘,但边缘是不连续的,检测到的边缘并不是一个整体。图像轮廓是指将边缘连接起来形成的一个整体,用于后续的计算。 OpenCV 提供了查找图像轮廓的函数 cv2.findContours(),该函数能够查找图

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

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

    2024年02月05日
    浏览(33)
  • 【OpenCv • c++】基础边缘检测算子 —— Sobel

    🚀 个人简介:CSDN「 博客新星 」TOP 10 , C/C++ 领域新星创作者 💟 作    者: 锡兰_CC ❣️ 📝 专    栏: 【OpenCV • c++】计算机视觉 🌈 若有帮助,还请 关注➕点赞➕收藏 ,不行的话我再努努力💪💪💪

    2024年02月03日
    浏览(35)
  • opencv(23) Canny边缘检测流程(Canny算子)

    Canny 边缘检测算法 是 John F. Canny 于 1986年开发出来的一个多级边缘检测算法,也被很多人认为是边缘检测的 最优算法 , 最优边缘检测的三个主要评价标准是: 低错误率: 标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报。 高定位性: 标识出的边缘要与图像中的实

    2024年04月11日
    浏览(25)
  • OpenCV 笔记(12):常用的边缘检测算子—— Canny

    一阶导数、二阶导数的边缘算子虽然简单易用,但存在一些缺点。例如容易受噪声影响,容易产生虚假边缘。 John F. Canny 在 1986 年提出了 Canny 边缘检测算法。它是结合了梯度计算方法和非极大值抑制技术的一种边缘检测算法。该算法克服了之前的边缘检测算法在抑制噪声和保

    2024年02月03日
    浏览(43)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包