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

1、前言

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

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

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

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

下面左图是一张黑白相间的图,右图是左图的每个像素的灰度值
在这里插入图片描述
我们设定一个卷积核如下(关于卷积的介绍请看之前的文章):
在这里插入图片描述
原图在通过卷积核进行卷积计算后得到的图像如下:
可以看到原图在卷积运算后黑色向白色突变的边缘被很好的保留了下来,因此可以通过这个卷积核找到图像中垂直的边缘。
在这里插入图片描述
同理,如果我们用下面的卷积核也可以找到图像中水平的边缘。
在这里插入图片描述
卷积运算后:
在这里插入图片描述

2、Prewitt算子边缘检测
如果我们把上面两个卷积核组合起来再对图像进行卷积便可以同时找到图像中水平和垂直的边缘,这种卷积核就是prewitt算子。
在这里插入图片描述

标准的 Prewitt 边缘检测算子由以下两个卷积核组成。
在这里插入图片描述
下面是用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。

最后效果如下(左边是原灰度图,右边是边缘检测出的图像):
在这里插入图片描述

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

下图左边为水平方向Roberts算子,也称正对角算子。右边为垂直方向Roberts算子,也称斜对角算子。
在这里插入图片描述
下面是Roberts算子的使用案例:

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

int main() {
    // 生成一个简单的图像
    cv::Mat image = cv::Mat::zeros(100, 100, CV_8U);
    cv::rectangle(image, cv::Rect(20, 20, 60, 60), cv::Scalar(255), cv::FILLED);

    // 定义Sobel算子
    cv::Mat sobel_x = (cv::Mat_<float>(3, 3) << -1, 0, 1, -2, 0, 2, -1, 0, 1);
    cv::Mat sobel_y = (cv::Mat_<float>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);

    // 应用Sobel算子
    cv::Mat edges_x, edges_y;
    cv::filter2D(image, edges_x, CV_64F, sobel_x);
    cv::filter2D(image, edges_y, CV_64F, sobel_y);

    // 计算梯度幅值和方向
    cv::Mat gradient_magnitude, gradient_direction;
    cv::magnitude(edges_x, edges_y, gradient_magnitude);
    cv::phase(edges_x, edges_y, gradient_direction, true);  // true 表示计算角度的弧度值

    // 归一化梯度方向到[0, 1]范围
    cv::normalize(gradient_direction, gradient_direction, 0, 1, cv::NORM_MINMAX);

    // 显示结果
    cv::imshow("Original Image", image);
    cv::imshow("Gradient Magnitude", gradient_magnitude);
    cv::imshow("Gradient Direction", gradient_direction);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

最后效果如下(左边是原灰度图,右边是边缘检测出的图像):
在这里插入图片描述

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

它的水平和垂直方向的卷积核如下:
在这里插入图片描述
接口说明:

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("your_image.jpg", cv::IMREAD_GRAYSCALE);

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

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

    // 计算梯度幅值
    cv::Mat gradient_magnitude;
    cv::magnitude(edges_x, edges_y, gradient_magnitude);

	// 归一化梯度方向到[0, 1]范围
    cv::normalize(gradient_magnitude, gradient_magnitude, 0, 1, cv::NORM_MINMAX);

    // 显示结果
    cv::imshow("Original Image", image);
    cv::imshow("Sobel Edges X", edges_x);
    cv::imshow("Sobel Edges Y", edges_y);
    cv::imshow("Gradient Magnitude", gradient_magnitude);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/223351.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何在服务器上运行python文件

目录 前置准备 详细步骤 一&#xff0c;在服务器安装Anaconda 下载安装包 上传文件到服务器 安装环境 二&#xff0c;创建虚拟环境 创建环境 三&#xff0c;测试执行python文件 执行python文件 查看进程状态 总结 前置准备 如何在个人服务器上运行python文件&#x…

elk+kafka+filebeat

elk1 cd /opt 把filebeat投进去 tar -xf filebeat-6.7.2-linux-x86_64.tar.gz mv filebeat-6.7.2-linux-x86_64 filebeat cd filebeat/ yum -y install nginx systemctl restart nginx vim /usr/share/nginx/html/index.html this is nginx cp filebeat.yml filebeat.yml.…

Matlab之统计数据分布并绘制直方图函数histogram

一、功能 直方图是一种将数据分组到条柱中的条形图。该函数可以统计数据在划分区间内的数量分布&#xff0c;同时以直方图的形式展示统计结果。 二、语法 1、histogram&#xff08;X&#xff09; 创建直方图X的图。该函数使用 一种自动分箱算法&#xff0c;返回具有统一宽度…

数组解构、对象解构与forEach方法遍历数组

解构赋值 1. 数组解构 1.1 基本语法 1.2 变量多 单元值少的情况 1.3 变量少 单元值多的情况 1.4 防止undefined传值情况 使用默认值 1.5 按需导入 忽略某些值 1.6 支持多维数组的解构 2. 对象解构 2.1 基本语法 2.2 给新的变量名赋值 2.3 数组对象解构 2.4 多级对象解构 cons…

网络安全威胁——跨站脚本攻击

跨站脚本攻击 1. 定义2. 跨站脚本攻击如何工作3. 跨站脚本攻击类型4. 如何防止跨站脚本攻击 1. 定义 跨站脚本攻击&#xff08;Cross-site Scripting&#xff0c;通常称为XSS&#xff09;&#xff0c;是一种典型的Web程序漏洞利用攻击&#xff0c;在线论坛、博客、留言板等共享…

vscode插件离线下载

离线下载插件地址&#xff1a;https://marketplace.visualstudio.com/VSCode

win11 关闭快速启动,解决重启后部分应用没有关闭的问题

鼠标右击win11开始菜单选择windows终端&#xff08;管理员&#xff09;打开输入&#xff1a;powercfg /h off按下回车即可

AOC computer monitor

【窗口增亮】关闭就没掉了

近期Google paly再次卡审?需要开发者提供更多关于应用的信息以通过谷歌审查?

谷歌政策更新得越来越频繁&#xff0c;也越来越严格&#xff0c;加大了对应用的审核力度。 最近&#xff0c;不少开发者表示&#xff0c;谷歌卡审又出新花样了。与之前收到暂停审核电话验证邮件&#xff08;需要在48-72小时内&#xff0c;拨打你开发者账号的号码&#xff0c;应…

8、Broker进一步了解

1、Broker消息分发服务以及构建ConsumeQueue和IndexFile与消息清除 前面分析如何进行刷盘&#xff0c;本章分析Broker的消息分发以及构建ConsumerQueue和IndexFile&#xff0c;两者构建是为了能够提高效率&#xff0c;减少消息查找时间以及减少网络带宽与存储空间。 ConsumeQ…

逆向爬虫进阶实战:突破反爬虫机制,实现数据抓取

文章目录 一、引言二、逆向爬虫进阶技巧三、逆向爬虫进阶实战代码片段四、总结与展望好书推荐内容简介作者简介前言节选 一、引言 随着网络技术的发展&#xff0c;网站为了保护自己的数据和资源&#xff0c;纷纷采用了各种反爬虫机制。然而&#xff0c;逆向爬虫技术的出现&…

农业装备行业分析:中国市场规模增长到4500多亿元

农业装备是指用于农业生产过程的先进农业机械、设备和设施。主要包括&#xff1a;农业田间作业机械、设施农业装备、农产品加工装备、农业生物质利用装备、农田设施与装备、农业信息化装备等。 农业装备服务于大农业&#xff0c;包括种植业、养殖业、加工业、服务业等&#xff…

详解python 面向对象三大特征

文章目录 一、面向对象三大特征介绍1、封装&#xff08;隐藏&#xff09;2、继承3、多态 二、继承1、语法格式2、类成员的继承和重写3、super()获得父类定义4、设计模式\_工厂模式实现 5、设计模式\_单例模式实现关于Python技术储备一、Python所有方向的学习路线二、Python基础…

Jupyter Notebook工具

Jupyter Notebook 是一个交互式的笔记本环境&#xff0c;允许用户以网页形式编写和分享代码、文本、图像以及其它多媒体内容。它支持超过 40 种编程语言&#xff0c;最常用的是 Python。 以下是 Jupyter Notebook 工具的一些特点和用法&#xff1a; 1. 特点&#xff1a; 交互式…

HTML程序大全(2):通用注册模版

一、正常情况效果 二、某项没有填写的效果 三、没有勾选同意项的效果 四、代码 <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>注册</title><style>body {font-family: Arial, sans-serif;background-color…

STM32基础教程 p16 窗口看门狗(WWDG)

1 窗口看门狗工作原理 1.1 简介 WWDG简介 窗口看门狗通常被用来监测&#xff0c;由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运 行序列而产生的软件故障。除非递减计数器的值在T6位变成0前被刷新&#xff0c;看门狗电路在达到预置 的时间周期时&#xff0c;会产…

Win系统缺少xinput1_3.dll有什么处理办法?看看这几个快速解决方法

一、xinput1_3.dll文件介绍&#xff1a; 文件类型&#xff1a;xinput1_3.dll是一种动态链接库&#xff08;DLL&#xff09;文件&#xff0c;用于提供系统功能。 文件大小&#xff1a;xinput1_3.dll文件大小通常在几KB到几十KB之间&#xff0c;具体取决于操作系统版本和编译时…

全息图着色器插件:Hologram Shaders Pro for URP, HDRP Built-in

8个新的Unity全息图着色器,具有故障效果,扫描线,网格线,和更多其他效果!与所有渲染管线兼容。 软件包添加了一系列的全息图着色器到Unity。从基本的全息图与菲涅耳亮点,先进的全息图与两种故障效应,扫描线,文体点阵和网格线全息图! 特色全息效果 Basic-支持菲涅耳发光照…

AWS CodeWhisperer:基于机器学习的代码建议工具

#AWS CodeWhisperer&#xff1a;基于机器学习的代码建议工具 AWS CodeWhisper概述 Amazon CodeWhisperer 是一种基于机器学习&#xff08;ML&#xff09;的服务&#xff0c;它可以根据Amazon CodeWhisperer 是一种基于机器学习&#xff08;ML&#xff09;的服务&#xff0c;它…

单片机开发常用的软件构架

对于单片机程序来说&#xff0c;大家都不陌生&#xff0c;但是真正使用架构&#xff0c;考虑架构的恐怕并不多&#xff0c;随着程序开发的不断增多&#xff0c;架构是非常必要的。 一、时间片轮询法 介于前后台顺序执行法和操作系统之间的一种程序架构设计方案。该设计方案需能…