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

引言

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

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

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

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

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

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

相关文章

【Django使用】10大章31模块md文档,第5篇:Django模板和数据库使用

当你考虑开发现代化、高效且可扩展的网站和Web应用时,Django是一个强大的选择。Django是一个流行的开源Python Web框架,它提供了一个坚实的基础,帮助开发者快速构建功能丰富且高度定制的Web应用 全套Django笔记直接地址: 请移步这…

【Docker】从零开始:8.Docker命令:Commit提交命令

【Docker】从零开始:8.Docker命令:Commit命令 基本概念镜像镜像分层什么是镜像分层为什么 Docker 镜像要采用这种分层结构 本章要点commit 命令命令格式docker commit 操作参数实例演示1.下载一个新的ubuntu镜像2.运行容器3.查看并安装vim4.退出容器5提交自己的镜像…

51单片机应用从零开始(八)·循环语句(for循环、while 语句、do‐while 语句)

51单片机应用从零开始(七)循环语句(if语句,swtich语句)-CSDN博客 目录 1. 用for 语句控制蜂鸣器鸣笛次数 2. 用while 语句控制 LED 3. 用 do‐while 语句控制 P0 口 8 位 LED 流水点亮 1. 用for 语句控制蜂鸣器鸣笛…

009 OpenCV 二值化 threshold

一、环境 本文使用环境为: Windows10Python 3.9.17opencv-python 4.8.0.74 二、二值化算法 2.1、概述 在机器视觉应用中,OpenCV的二值化函数threshold具有不可忽视的作用。主要的功能是将一幅灰度图进行二值化处理,以此大幅降低图像的数…

Linux:文件系统初步理解

文章目录 文件的初步理解C语言中对文件的接口系统调用的接口位图的理解open调用接口 文件和进程的关系进程和文件的低耦合 如何理解一切皆文件? 本篇总结的是关于Linux中文件的各种知识 文件的初步理解 在前面的文章中有两个观点,1. 文件 内容 属性&…

手撕A*算法(详解A*算法)

A*算法原理 全局路径规划算法,根据给定的起点和终点在全局地图上进行总体路径规划。 导航中使用A*算法计算出机器人到目标位置的最优路线,一般作为规划的参考路线 // 定义地图上的点 struct Point {int x,y; // 栅格行列Point(int x, int y):x(x),y(y){…

51单片机利用I/O口高阻状态实现触摸控制LED灯

51单片机利用I/O口高阻状态实现触摸控制LED灯 1.概述 这篇文章介绍使用I/O口的高阻状态实现一个触摸控制LED灯亮灭的实验。该实验通过手触摸P3.7引脚,改变电平信号控制灯的亮灭。 2.实验过程 2.1.实验材料 名称型号数量单片机STC12C20521LED彩灯无1晶振12MHZ1电…

PDF 批量处理软件BatchOutput PDF mac中文版介绍

BatchOutput PDF mac是一款适用于 Mac 的 PDF 批量处理软件。它可以帮助用户将多个 PDF 文件进行异步处理,提高工作效率。 BatchOutput PDF 可以自动化执行许多任务,包括 PDF 文件的打印、转换、分割、压缩、加密、重命名等,而且它还可以将自…

开启数据库审计(db,extended级别或os级别),并将审计文件存放到/home/oracle/audit下

文章目录 开启数据库审计(db,extended级别或os级别),并将审计文件存放到/home/oracle/audit下一. 简介二. 配置2.1. 审计是否安装2.2. 审计表空间迁移2.3. 审计参数2.4. 审计级别2.5. 其他审计选项2.6. 审计相关视图 三. 使用3.1. 开启/关闭审…

案例023:基于微信小程序的童装商城的设计与实现

文末获取源码 开发语言:Java 框架:SSM JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder X 小程序…

wpf使用CefSharp.OffScreen模拟网页登录,并获取身份cookie,C#后台执行js

目录 框架信息&#xff1a;MainWindow.xamlMainWindow.xaml.cs爬取逻辑模拟登录拦截请求Cookie获取 CookieVisitorHandle 框架信息&#xff1a; CefSharp.OffScreen.NETCore 119.1.20 MainWindow.xaml <Window x:Class"Wpf_CHZC_Img_Identy_ApiDataGet.MainWindow&qu…

关于前端上传

类似于 上面的传参form-data形式&#xff0c;第一个参数为上传的文件&#xff0c;第二个参数为json格式

Centos部署GitLab-备份恢复

1. 下载rpm包 wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.8.4-ce.0.el7.x86_64.rpm2. 安装依赖 yum -y install policycoreutils openssh-server openssh-clients postfix policycoreutils-python3. rpm安装 rpm -ivh gitlab-ce-10.8.4-ce.…

OpenStack云计算平台

目录 一、OpenStack 1、简介 2、硬件需求 3、网络 二、环境搭建 1、安全 2、主机网络 3、网络时间协议(NTP) 4、OpenStack包 5、SQL数据库 6、消息队列 7、Memcached 一、OpenStack 1、简介 官网&#xff1a;https://docs.openstack.org/2023.2/ OpenStack系统由…

git查看某个commit属于哪个分支方法(如何查看commit属于哪个分支)

有时候&#xff0c;当我们由于业务需求很多时&#xff0c;基于同一个分支新建的项目分支也会很多。 在某个时间节点&#xff0c;我们需要合并部分功能点时&#xff0c;我们会忘了这个分支是否已经合入哪个功能点&#xff0c;我们就会查看所有的commit记录&#xff0c;当我们找到…

Jmeter快速入门

文章目录 1.安装Jmeter1.1.下载1.2.解压1.3.运行 2.快速入门2.1.设置中文语言2.2.基本用法 1.安装Jmeter Jmeter依赖于JDK&#xff0c;所以必须确保当前计算机上已经安装了JDK&#xff0c;并且配置了环境变量。 1.1.下载 可以Apache Jmeter官网下载&#xff0c;地址&#xf…

Word中如何实现 图片 | 表格 自动编号与文中引用编号对应

当我们在进行大篇幅word文档的编写时&#xff0c;为了节约修改文章中图片或表格所花费的大量时间&#xff0c;可以将图片自动编号&#xff0c;且让文中引用的顺序跟着图片顺序的变化而变化&#xff0c;具体操作如下&#xff1a; 1. 将鼠标定位在图片或者表格欲加编号的下方或上…

【SpringBoot3+Vue3】五【完】【实战篇】-前端(配合后端)

目录 一、环境准备 1、创建Vue工程 2、安装依赖 2.1 安装项目所需要的vue依赖 2.2 安装element-plus依赖 2.2.1 安装 2.2.2 项目导入element-plus 2.3 安装axios依赖 2.4 安装sass依赖 3、目录调整 3.1 删除部分默认目录下文件 3.1.1 src/components下自动生成的…

2.HTML入门

目录 一.HTML介绍 二.HTML常用标签 2.1 标题标签 2.2 段落标签 2.3 超链接标签 2.4 图片标签 2.5 换行与空格 2.6 布局标签 2.7 列表标签 2.8 表单标签 一.HTML介绍 定义&#xff1a;将内容显示在网页&#xff0c;用来描述网页的一种语言&#xff0c;负责网页的架构…

objdump反汇编文件解析

命令使用 objdump可以对可执行文件进行反汇编 其常用参数为: objdump -d <file(s)>: 将代码段反汇编&#xff1b;objdump -S <file(s)>: 将代码段反汇编的同时&#xff0c;将反汇编代码与源代码交替显示&#xff0c;编译时需要使用-g参数&#xff0c;即需要调试信…