搭配:基于OpenCV的边缘检测实战

news2024/9/22 1:37:56

引言

计算机中的目标检测与人类识别物体的方式相似。作为人类,我们可以分辨出狗的形象,因为狗的特征是独特的。尾巴、形状、鼻子、舌头等特征综合在一起,帮助我们把狗和牛区分开来。

同样,计算机能够通过检测与估计物体的结构和性质相关的特征来识别物体。其中一个特征就是边缘。

在数学上,边是两个角或面之间的一条线。边缘检测的关键思想是像素亮度差异极大的区域表示边缘。因此,边缘检测是对图像亮度不连续性的一种度量。

Sobel边缘检测

Sobel边缘检测器也称为Sobel–Feldman运算符或Sobel过滤器,它的工作原理是通过计算图像中每个像素的图像强度梯度。

它找到了从亮到暗的最大亮度增加方向以及该方向的变化率。使用该过滤器时,可以分别在X和Y方向上或一起处理图像。

1a1d7bff7d9c77a1ad49c8732e167cd0.png

Sobel检测器使用3X3核函数,这些核函数与原始图像进行卷积,计算出导数的近似值。

为了检测图像中的水平边缘(x方向) ,我们将使用x方向内核来扫描图像,用于检测垂直边缘。

import cv2
import numpy as np
import matplotlib.pyplot as plt
# Load the image
image_original = cv2.imread('building.jpg', cv2.IMREAD_COLOR)
# Convert image to gray scale
image_gray = cv2.cvtColor(image_original, cv2.COLOR_BGR2GRAY)
# 3x3 Y-direction  kernel
sobel_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
# 3 X 3 X-direction kernel
sobel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
# Filter the image using filter2D, which has inputs: (grayscale image, bit-depth, kernel)
filtered_image_y = cv2.filter2D(image_gray, -1, sobel_y)
filtered_image_x = cv2.filter2D(image_gray, -1, sobel_x)

现在,让我们绘制上面代码的输出。

(fig, (ax1, ax2, ax3)) = plt.subplots(1, 3, figsize=(25, 25))
ax1.title.set_text('Original Image')
ax1.imshow(image_original)
ax2.title.set_text('sobel_x')
ax2.imshow(filtered_image_y)
ax3.title.set_text('sobel_y filter')
ax3.imshow(filtered_image_x)
plt.show()

33c1fad402ed9d42ea870f85573e4dbd.png

不需要记住所有的过滤器内核。可以直接在 OpenCV 库中使用您选择的相应过滤器。

在OpenCV中,可以像如下所示应用Sobel边缘检测。

sobel_x_filtered_image = cv2.Sobel(image_gray, cv2.CV_64F, 1, 0, ksize=3)
sobel_x_filtered_image = cv2.Sobel(image_gray, cv2.CV_64F, 0, 1, ksize=3)
sobel_y_filtered_image = cv2.convertScaleAbs(sobel_x_filtered_image)
sobel_y_filtered_image = cv2.convertScaleAbs(sobel_y_filtered_image)

Laplacian边缘检测

拉普拉斯边缘检测器比较图像的二阶导数。它测量的是一阶导数在一次通过中的变化率。拉普拉斯边缘检测使用一个核心,包含负值的交叉模式,如下所示。

535b00be8f065ebe6b677b9c951666ea.png

拉普拉斯边缘检测器的一个缺点是对噪声敏感。也就是说,它可能最终检测噪声作为边缘。在应用拉普拉斯过滤器之前对图像进行平滑处理是一种常见的做法。

我们可以实现一个拉普拉斯边缘检测器如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt
image_original = cv2.imread('building.jpg', cv2.IMREAD_COLOR)
# remove noise
image_gray = cv2.cvtColor(image_original, cv2.COLOR_BGR2GRAY)
# Reduce noise in image
img = cv2.GaussianBlur(image_gray,(3,3),0)
# Filter the image using filter2D, which has inputs: (grayscale image, bit-depth, kernel)
filtered_image = cv2.Laplacian(img, ksize=3, ddepth=cv2.CV_16S)
# converting back to uint8
filtered_image = cv2.convertScaleAbs(filtered_image)
# Plot outputs
(fig, (ax1, ax2)) = plt.subplots(1, 2, figsize=(15, 15))
ax1.title.set_text('Original Image')
ax1.imshow(image_original)
ax2.title.set_text('Laplacian Filtered Image')
ax2.imshow(filtered_image, cmap='gray')

05f356387c2adf660bbb52af98d72f03.png

Canny边缘检测

Canny边缘检测可以分为如下四个步骤:

· 消除噪音

· 梯度计算

· 利用非最大值抑制提取图像边缘

· 滞后阈值法

因为Canny边缘检测对噪声很敏感,所以第一步就是去噪,通过首先应用高斯滤波器对图像进行平滑处理。

Canny边缘检测的第二步是梯度计算。它通过沿着梯度方向计算图像中灰度(梯度)的变化率来实现。

我们知道图像的亮度在边缘处最高,但实际上,亮度并不是在一个像素处达到峰值; 相反,邻近的像素具有很高的亮度。在每个像素位置,canny 边缘检测比较像素,并在沿梯度方向选择3X3邻域的局部最大值。这个过程被称为非最大值抑制。

这一步结束之后,会形成一些破碎的边缘。最后一步是使用一种叫做滞后阈值的方法来修复这些断裂的边缘。

对于滞后阈值,有两个阈值: 高阈值和低阈值。

任何梯度值高于高阈值的像素自动保持为边缘。对于梯度位于高阈值和低阈值之间的像素,有两种处理方式。检查像素是否可能连接到边缘; 如果连接,则保留像素,否则丢弃。低于低阈值的像素被自动丢弃。

现在,让我们通过OpenCV实现一个Canny边缘检测。

import cv2
import numpy as np
import matplotlib.pyplot as plt
image_original = cv2.imread('building.jpg', cv2.IMREAD_COLOR)
# remove noise
image_gray = cv2.cvtColor(image_original, cv2.COLOR_BGR2GRAY)
filtered_image = cv2.Canny(image_gray, threshold1=20, threshold2=200)
# Plot outputs
(fig, (ax1, ax2)) = plt.subplots(1, 2, figsize=(15, 15))
ax1.title.set_text('Original Image')
ax1.imshow(image_original)
ax2.title.set_text('Laplacian Filtered Image')
ax2.imshow(filtered_image, cmap='gray')

c161cf4c93f1fd5bc4ec9af3d08e64ec.png

·  END  ·

HAPPY LIFE

8cce092d8ed4e47d3e9c4f126c0aded0.png

觉得有趣就点亮在看吧

dbb4a6abd03b5fccdad69b3a883b5c5a.gif

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

掌握未来技术趋势,成为领先者——深度解析2023年技术热点

掌握未来技术趋势,成为领先者——深度解析2023年技术热点 摘要:本文探讨当前最热门的技术趋势。我们将介绍人工智能、大数据、区块链、5G等前沿技术,并阐述它们如何改变我们的生活。最后,我们将总结如何利用这些技术趋势&#xf…

罗拉ROLA分析亚马逊频繁扫号下的跨境电商,跨境电商卖家应该何去何从?

相信各位同行都知道,自2021年起,亚马逊的扫号活动就从未间断,直到如今2023年的亚马逊,仍然是隔2周-几个月就有大规模的审核扫号,大批卖家店铺被封,亚马逊卖家人人自危,面对时间间隔短频率高的扫…

【数据结构】树如何定义 | 如何存储 | 实际应用

前言 如上图,A中的孩子的个数是不固定的。我们无法精确的每个不同的根结点有多少个孩子。所以并不能精确知道需要定义多少个孩子节点。 struct TreeNode {int val;struct TreeNode* child1;struct TreeNode* child2;struct TreeNode* child3;//...//这样显然是不能…

C语言数组的距离(ZZULIOJ1200:数组的距离)

题目描述 已知元素从小到大排列的两个数组x[]和y[], 请写出一个程序算出两个数组彼此之间差的绝对值中最小的一个,这叫做数组的距离 。 输入:第一行为两个整数m, n(1≤m, n≤1000),分别代表数组f[], g[]的长度。第二行有m个元素&a…

2023年【四川省安全员B证】找解析及四川省安全员B证作业模拟考试

题库来源:安全生产模拟考试一点通公众号小程序 四川省安全员B证找解析是安全生产模拟考试一点通总题库中生成的一套四川省安全员B证作业模拟考试,安全生产模拟考试一点通上四川省安全员B证作业手机同步练习。2023年【四川省安全员B证】找解析及四川省安…

mac电脑系统活动监控:iStat Menus 中文 for Mac

iStat Menus是一款Mac操作系统上的系统监控工具,它提供了实时的系统状态和性能数据,让用户可以方便地监控和管理自己的电脑。iStat Menus以菜单栏图标的形式显示各种系统指标,用户可以轻松访问和查看这些信息。 以下是iStat Menus软件的一些…

AI实景无人直播源码开发揭秘--SaaS

AI实景无人直播系统是指由技术人员基于无人直播平台开发创建的源代码,核心功能设计包含:实景无人直播,评论实时互动,视频流处理,话术库,语音库等, 无人直播源码模块包含 以下常见模块&#xf…

跨境电商的微商业务:个人品牌的成功之路

随着互联网的发展,跨境电商行业迅猛崛起,微商业务作为其中的一种新型销售模式也逐渐崭露头角。微商业务以低成本、高灵活性的特点,为个人品牌的成功之路开辟了新的可能性。 本文将深入研究跨境电商微商业务,探讨在这个领域中个人…

GPT、GPT-2、GPT-3论文精读笔记

视频:GPT,GPT-2,GPT-3 论文精读【论文精读】_哔哩哔哩_bilibili MAE论文:把bert用回计算机视觉领域 CLIP论文:打通文本和图像 GPT 论文:Improving Language Understanding by Generative Pre-Training …

如何开启MySQL的慢查询日志

说明:如果需要查看某一条SQL查询速度慢,并对慢的SQL进行优化,那么开启MySQL慢查询日志是一定要做的事情,本文介绍如何开启MySQL的慢查询日志; 查看MySQL慢查询是否开启 首先,输入下面的命令,查…

Qt/QML编程学习之心得:一个Qt工程的学习笔记(九)

1、.pro文件 加CONFIG += c++11,才可以使用Lamda表达式(一般用于connect的内嵌槽函数) 2、QWidget 这是Qt新增加的一个类,基类,窗口类,QMainWindow和QDialog都继承与它。 3、Main函数 QApplication a应用程序对象,有且仅有一个 a.exec() 进行消息循环、阻塞 MyWi…

快速入门go语言学习笔记

文章目录 1、初识go1.1、go语言1.2 第一个Go程序 2、基础类型2.1、命名2.2、变量2.2.1 变量声明2.2.2 变量初始化2.2.3 变量赋值2.2.4 匿名变量 2.3、常量2.3.1 字面常量(常量值)2.3.2 常量定义2.3.3 iota枚举 2.4、基础数据类型2.4.1 分类2.4.2 布尔类型2.4.3 整型2.4.4 浮点型…

System-V共享内存和基于管道通信实现的进程池

文章目录 一.进程间通信:进程间通信的本质: 二.Linux管道通信匿名管道:关于管道通信的要点:基于匿名管道构建进程池: 三.System-V共享内存共享内存和命名管道协同通信 参考Linux内核源码版本------linux-2.4.3 一.进程间通信: 操作系统中,为了保证安全性,进程之间具有严格的独…

【linux】服务器CPU占用50%,top/htop/ps却看不到异常进程?使用unhide可以查看!

问题描述 htop发现前32个核全被占满了,但是却找不到对应进程号 查杀 安装unhide查看隐藏进程 apt-get install unhideunhide使用 unhide proc果然发现了隐藏进程 杀死隐藏进程 kill -9 [pid]这么多pid号,我这边杀了其中一个,发现CPU…

为IP地址申请SSL证书

SSL(Secure Sockets Layer)是一种网络协议,用于在浏览器与服务器之间建立安全、加密的连接。SSL证书是用于证明您的网站身份并启用HTTPS(超文本传输安全协议)的安全文件。这种协议可以确保用户与您的网站之间的所有通信…

PHP预约上门回收废品系统的代码披露

PHP预约上门回收废品系统的代码披露 <?phpnamespace app\admin\controller;class Code {public function getTopDomainhuo(){error_reporting(0);$host $_SERVER["HTTP_HOST"];$matchstr "[^\\.]\\.(?:(" . $host . ")|\\w{2}|((" . $ho…

程序环境和预处理(详解版)

我们已经学到这里&#xff0c;这就是关于C语言的最后一个集中的知识点了&#xff0c;虽然它比较抽象&#xff0c;但是了解这部分知识&#xff0c;可以让我们对C代码有更深层次的理解&#xff0c;知道代码在每一个阶段发生什么样的变化。让我们开始学习吧! 目录 1.程序的翻译环…

Excel使用VLOOKUP查询数据

VLOOKUP函数在百度百科中的解释是&#xff1a; 解释一下&#xff0c;函数需要4个参数&#xff1a; 参数1&#xff08;lookup_value&#xff09;&#xff1a;需要匹配的值参数2&#xff08;table_array&#xff09;&#xff1a;在哪个区域里进行匹配参数3&#xff08;col_index…

复费率电表和预付费电表有哪些区别?

随着科技的发展和能源管理的日益严格&#xff0c;电表技术也在不断更新换代。复费率电表和预付费电表作为两种主流的智能电表&#xff0c;各自具有独特的优势和应用场景。接下来&#xff0c;小编来为大家详细解析这两种电表的区别及其应用场景。 一、复费率电表 1.定义及工作原…

【LeetCode刷题】--67.二进制求和

67.二进制求和 方法&#xff1a;模拟计算 class Solution {public String addBinary(String a, String b) {StringBuilder ans new StringBuilder();int carry 0;for(int ia.length()-1,jb.length()-1;i>0||j>0;i--,j--){int sum carry;sum i >0 ? a.charAt(i) …