车道线检测_Canny算子边缘检测_1
Canny算子边缘检测(原理)
Canny算子边缘检测是一种经典的图像处理算法,由John F. Canny于1986年提出,用于精确、可靠地检测数字图像中的边缘特征。该算法设计时考虑了三个关键目标:低错误率(即尽可能多地检测真实的边缘,同时避免误报)、边缘定位的准确性(确保检测到的边缘位置与实际边缘位置紧密对应)以及边缘的单响应性(确保图像中的每一个边缘只被检测一次,避免重复或断裂)。Canny算子通过以下五个核心步骤实现这些目标:
-
图像灰度化:
- 如果输入图像为彩色,首先将其转换为灰度图像,因为Canny算子适用于处理单通道灰度图像。
-
高斯滤波(高斯模糊):
- 应用高斯平滑滤波器对灰度图像进行滤波,以消除图像中的噪声。高斯滤波器通过卷积操作将每个像素值替换为周围像素值的加权平均,其中权重由二维高斯函数确定。这种滤波方式既能有效减弱噪声,又能较好地保留边缘细节,避免过度模糊导致边缘定位模糊。
-
计算梯度幅值和方向:
- 对经过高斯滤波的图像计算其梯度。梯度表示图像中像素灰度值的变化率,包含了边缘强度和方向的信息。通常使用一阶偏导数的近似算子(如Sobel算子、Prewitt算子或Roberts算子)来计算水平和垂直方向的梯度分量。然后根据这两个分量计算出梯度幅值(即边缘强度)和梯度方向。梯度方向通常用于后续的非极大值抑制步骤。
-
非极大值抑制:
- 该步骤旨在去除非边缘像素的响应,仅保留真正的边缘点。在梯度方向的直线上,检查每个像素的梯度幅值是否为其邻域内(在其梯度方向上)的最大值。如果不是,说明该像素可能不是真正的边缘点,将其梯度幅值置零或降低。这样可以消除边缘检测过程中的许多虚假响应,确保最终得到的边缘轮廓更为精确。
-
双阈值检测与边缘连接:
- 设置高低两个阈值,通常选择高阈值来确定强边缘,低阈值用于连接可能断开的弱边缘。具体操作如下:
- 首先,将梯度幅值大于高阈值的像素标记为边缘像素,形成初步的边缘集。
- 然后,对于幅值介于高低阈值之间的像素,如果它们与已标记为边缘的像素相邻(即位于已检测边缘的8邻域内),也被认为是边缘像素,以保证边缘的连续性。
- 最终,只有通过上述条件的像素才被认为是有效的边缘点,其余像素则被舍弃。这种方法有助于减少边缘断裂的同时,抑制噪声引起的伪边缘。
- 设置高低两个阈值,通常选择高阈值来确定强边缘,低阈值用于连接可能断开的弱边缘。具体操作如下:
Canny算子通过一系列精心设计的步骤,实现了对图像边缘的稳健、精确检测,即使在存在噪声干扰的情况下也能保持较高的性能。由于其出色的综合性能,Canny算子在计算机视觉、图像分析、机器视觉等领域中被广泛应用,特别是在需要精确边缘信息的应用场景中,如物体轮廓检测、运动目标跟踪、图像分割等。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
边缘检测是基于灰度突变来分割图像的常用方法,其实质是提取图像中不连续部分的特征。目前常见边缘检测算子有差分算子、 Roberts 算子、 Sobel 算子、 Prewitt 算子、 Log 算子以及 Canny 算子等。
其中, Canny 算子是由计算机科学家 John F. Canny 于 1986 年提出的一种边缘检测算子,是目前理论上相对最完善的一种边缘检测算法。
Canny 算子在 MATLAB 、 OpenCV 等常用图像处理工具中已有内置的 API。
在 OpenCV 中, Canny 算子使用的函数是 Canny() ,它的原函数如下:
def Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)
- image: 表示此操作的源(输入图像)。
- threshold1: 表示迟滞过程的第一个阈值。
- threshold2: 表示迟滞过程的第二个阈值。
接下来,接着操作我们之前的马里奥,对马里奥做一次边缘检测看下效果:
import cv2 as cv
from matplotlib import pyplot as plt# 图像读入
img = cv.imread('maliao.jpg', 0)
edges = cv.Canny(img, 100, 200)# 显示结果
titles = ['Original Img', 'Edge Img']
images = [img, edges]# matplotlib 绘图
for i in range(2):plt.subplot(1, 2, i+1), plt.imshow(images[i],'gray')plt.title(titles[i])plt.xticks([]),plt.yticks([])plt.show()
图像转化(彩->灰)
图像转化原因:边缘检测最关键的部分是计算梯度,颜色难以提供关键信息,并且颜色本身非常容易受到光照等因素的影响,所以只需要灰度图像中的信息就足够了。并且灰度化后,简化了矩阵,提高了运算速度。
原理:将彩色图像(Color Image)转换为灰度图(Gray Scale Image),即从三通道RGB图像转为单通道图像。
实现:我们实现彩图转化为灰度图需要用到opencv库中的cv.cvtColor函数,需要用到两个参数:src——输入图片,code——颜色转换代码,代码如下:
# 灰度图转换
def grayscale(num_img):for i in range(num_img):filename = 'img' + str(i) + '.jpg'img = cv2.imread(filename)img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)filename = 'img_gray' + str(i) + '.jpg'cv2.imwrite(filename, img_gray)
生成Mask掩膜,提取 ROI
代码如下:
# 生成感兴趣区域即Mask掩模
def region_of_interest(image, vertices):mask = np.zeros_like(image) # 生成图像大小一致的zeros矩# 填充顶点vertices中间区域if len(image.shape) > 2:channel_count = image.shape[2]ignore_mask_color = (255,) * channel_countelse:ignore_mask_color = 255# 填充函数cv2.fillPoly(mask, vertices, ignore_mask_color)masked_image = cv2.bitwise_and(image, mask)return masked_image
Hough变换的路沿检测
Hough变换(原理)
Hough变换是一种使用表决方式的参数估计技术,其原理是利用图像空间和Hough参数空间的线-点对偶性,把图像空间中的检测问题转换到参数空间中进行。
基于霍夫变换的直线检测
用到的是Opencv封装好的函数cv.HoughLinesP函数,使用到的参数如下:
image:输入图像,通常为canny边缘检测处理后的图像
rho:线段以像素为单位的距离精度
theta:像素以弧度为单位的角度精度(np.pi/180较为合适)
threshold:霍夫平面累加的阈值
minLineLength:线段最小长度(像素级)
maxLineGap:最大允许断裂长度
具体代码如下:
def hough_lines(img, rho, theta, threshold, min_line_len, max_line_gap):# rho:线段以像素为单位的距离精度# theta : 像素以弧度为单位的角度精度(np.pi/180较为合适)# threshold : 霍夫平面累加的阈值# minLineLength : 线段最小长度(像素级)# maxLineGap : 最大允许断裂长度lines = cv.HoughLinesP(img, rho, theta, threshold, np.array([]), minLineLength=min_line_len, maxLineGap=max_line_gap)return lines
高斯滤波
高斯滤波算法是一种去除高频噪声的常用方式,通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值都是由其本身和邻域内的其他像素值经过加权平均后得到的。高斯滤波的原理是根据待滤波的像素点及其邻域点的灰度值按照高斯公式生成的参数规则进行加权平均。
我们这一步需要用到opencv库中的cv.GaussianBlur函数,其中使用到的参数为:src——输入图像,kernel_size——高斯核的大小,sigma——高斯标准差(一般默认为0),具体代码如下:
# 高斯滤波
def gaussian_blur(image, kernel_size):return cv.GaussianBlur(image, (kernel_size, kernel_size), 0)
绘制高斯滤波后的效果图:
- 绘制车道线
图像融合
参考文章:python --opencv图像处理Canny算子边缘检测(Roberts算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr 算子、 LOG 算子)_分别用roberts算子、sobel算子、prewitt算子、拉普拉斯算子、log算子和canny算-CSDN博客
相关文章:
车道线检测_Canny算子边缘检测_1
Canny算子边缘检测(原理) Canny算子边缘检测是一种经典的图像处理算法,由John F. Canny于1986年提出,用于精确、可靠地检测数字图像中的边缘特征。该算法设计时考虑了三个关键目标:低错误率(即尽可能多地检…...
kubadm部署kubernetes
什么是kubernetes Kubernetes是一款应用于集群的,容器自动部署、扩展和管理的开源平台,提供了一种以容器为中心的基础架构。利用kubernetes,你可以快速高效地响应客户如下请求: 应用程序的动态、精准部署应用程序的动态扩展无缝推…...
Sqlite插入单引号和双引号,防止sql注入
1. 方法1 sqlite3_mprintf替换sprintf,%q替换%s. 1.1. 举例 修改前代码 //修改前, hello123写入失败char sql[1000]char* sql sprintf("UPDATE table SET name %s WHERE name_id %d","hello123", 1);rc sqlite3_exec(db, sql, NULL, NULL, &err…...
代码随想录算法训练营第二十九天(回溯5)|491. 非递减子序列、46. 全排列、47. 全排列 II(JAVA)
文章目录 491. 非递减子序列解题思路源码 46. 全排列解题思路源码 47. 全排列 II解题思路源码 总结 491. 非递减子序列 给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 …...
【CANN训练营笔记】AscendCL图片分类应用(C++实现)
样例介绍 基于PyTorch框架的ResNet50模型,对*.jpg图片分类,输出各图片所属分类的编号、名称。 环境介绍 华为云AI1s CPU:Intel Xeon Gold 6278C CPU 2.60GHz 内存:8G NPU:Ascend 310 环境准备 下载驱动 wget ht…...
从头开发一个RISC-V的操作系统(二)RISC-V 指令集架构介绍
文章目录 前提ISA的基本介绍ISA是什么CISC vs RISCISA的宽度 RISC-V指令集RISC-V ISA的命名规范模块化的ISA通用寄存器Hart特权级别内存管理与保护异常和中断 目标:通过这一个系列课程的学习,开发出一个简易的在RISC-V指令集架构上运行的操作系统。 前提…...
uniapp/设置桌面角标/发送系统通知/动态修改桌面应用图标/展示3d模型/仿淘宝二楼
uniapp的安卓apk图标角标设置消息数量 1、主要方法: 设置角标: plus.runtime.setBadgeNumber(999) 清除角标: //plus.runtime.setBadgeNumber(0)//没有效果 plus.runtime.setBadgeNumber(-1) //有效果 2、使用在具体的生命周期 1、打开app获取…...
【Java八股学习】Redis高可用 思维导图
说明 文章内容通过学习小林Coding内的优质文章后整理而来,整理成思维导图的方式是为了帮助自己理解、记忆和复习。如若侵权请联系删除,再次对小林Coding内的优质文章表示感谢。参考文章如下: 主从复制是怎么实现的?为什么要有哨…...
C++万物起源:类与对象(三)拷贝构造、赋值重载
目录 一、拷贝构造函数 1.1拷贝构造函数的概念与特征 1.2拷贝构造的实现 1.3默认构造函数 1.4拷贝构造函数典型调用场景 二、赋值运算符重载 2.1赋值运算符重载的格式 一、拷贝构造函数 1.1拷贝构造函数的概念与特征 在c语言语法中,我们可以将一个变量赋值给…...
JavaScript构造函数(new构造js对象与原型链prototype)
构造函数详解 铺垫:面向对象编程一、构造函数是什么?二、构造函数的作用?三、构造函数的执行过程?四、构造函数的返回值?五、构造函数为什么要用new关键字调用?六、构造函数的实例成员和静态成员࿱…...
【WPF应用31】WPF基本控件-ListView的详解与示例
WPF(Windows Presentation Foundation)是.NET框架的一个组成部分,它用于构建桌面应用程序的用户界面。ListView是WPF中一个非常强大的数据展示控件,它可以用来显示一系列的项,类似于Windows资源管理器中的文件列表。Li…...
【动态】江西省小型水库安全监测能力提升试点项目通过验收
近日,由北京国信华源科技有限公司和长江勘测规划设计研究有限责任公司联合承建的江西省小型水库安全监测能力提升试点项目圆满通过验收。 在项目业主单位的组织下,省项目部、特邀专家、县水利局二级项目部以及项目设计、监理、承建等单位的代表组成验收工…...
前视声呐目标识别定位(九)-声呐驱动
前视声呐目标识别定位(一)-基础知识 前视声呐目标识别定位(二)-目标识别定位模块 前视声呐目标识别定位(三)-部署至机器人 前视声呐目标识别定位(四)-代码解析之启动识别模块 …...
【详解】Windows系统安装Nginx及简单使用
【详解】Windows系统安装Nginx及简单使用 一、Nginx是什么? “Nginx 是一款轻量级的 HTTP 服务器,采用事件驱动的异步非阻塞处理方式框架,这让其具有极好的 IO 性能,时常用于服务端的反向代理和负载均衡。”Nginx 是一款 http 服…...
WebGPU vs. WebGL:前端图形技术的进化与数字孪生的崭新前景
在现代互联网时代,图形渲染在网页应用和数字孪生的开发中起着至关重要的作用。WebGL和WebGPU是两种前端图形技术,它们在处理图形和计算密集型任务时发挥着关键作用。本文将深入研究这两种技术,探讨它们的区别、WebGPU的优势,以及它…...
即刻体验 | 使用 Flutter 3.19 更高效地开发
我们已隆重推出全新的 Flutter 版本——Flutter 3.19。此版本引入了专为 Gemini 设计的新 Dart SDK、一个能让开发者对 Widget 动画实现精细化控制的全新 Widget,Impeller 更新带来的渲染性能提升、有助于实现深层链接的工具和对 Windows Arm64 的支持,以…...
Exchanger 怎么用J.U.C
Exchanger简介 Exchanger通常用来解决以下类似场景的问题,如下:两个线程间需要交换数据的问题,在多线程编程中,经常会有这样的场景:两个线程各自持有一些数据,并且需要在某个点上交换这些数据,…...
校园局域网钓鱼实例
Hello ! 我是"我是小恒不会java" 本文仅作为针对普通同学眼中的网络安全,设计的钓鱼案例也是怎么简陋怎么来 注:本文不会外传代码,后端已停止使用,仅作为学习使用 基本原理 内网主机扫描DNS劫持前端模拟后端…...
网络原理 - HTTP / HTTPS(3)——http响应
目录 一、认识 “状态码”(status code) 常见的状态码 (1)200 OK (2)404 Not Found (3)403 ForBidden (4)405 Method Not Allowed (5&…...
Flask Python:模糊查询filter和filter_by,数据库多条件查询
数据库(sqlalchemy)多条件查询 前言一、filter、filter_by实现过滤查询1、filter_by()基础查询并且查询(多条件查询) 2、filter()like:模糊查询and:并且查询or:或者查询 二、all(),first(),get(…...
leetcode 热题 100(部分)C/C++
leetcode 热题 100 双指针 盛最多水的容器 【mid】【双指针】 思路: 好久没写代码sb了,加上之前写的双指针并不多,以及有点思维定势了。我对双指针比较刻板的印象一直是两层for循环i,j,初始时i,j都位于左界附近&…...
梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码
源码简介 最新梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码下载 梨花带雨播放器基于thinkphp6开发的XPlayerHTML5网页播放器前台控制面板,支持多音乐平台音乐解析。二开内容:修复播放器接口问题,把接口本地化,但是集成外链播放器…...
如何通过Spring提供的EL表达式执行bean的属性或方法?
如何通过Spring提供的EL表达式执行bean的属性或方法? 关键两个bean: org.springframework.expression.Expression org.springframework.expression.spel.support.StandardEvaluationContext 实例: import cn.hutool.extra.spring.Spring…...
SSTI 服务器端模板注入(Server-Side Template Injection)
1.【攻防世界】Web_python_template_injection {{}}是变量包裹标识符,里面存放的是一个变量,当你输入 http://61.147.171.105:55121/{{8*8}} 执行成功,说明存在模版注入。接下来,开始想办法编代码拿到服务器的控制台权限 。 首先…...
Vue.js---------Vue基础
能够说出Vue的概念和作用能够使用vue/cli脚手架工程化开发能够熟练Vue指令 一.vue基本概念 1.学习vue Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 渐进…...
力扣经典150题第一题:合并两个有序数组
目录 合并两个有序数组问题详解与解决方法1. 介绍2. 问题描述3. 解题思路4. 算法实现5. 复杂度分析6. 测试和验证7. 扩展如何处理特殊情况和边界条件?如何处理数组中可能存在的重复元素?如何优化算法以减少内存使用或提高执行效率? 8. 总结9.…...
Git:日志修改
一、问题描述 有小伙伴提出一个需求,为了满足某种需要,需要在Git日志中增加一条提交记录,并且需要指定提交时间。 比如,以下面这个only-allow项目为例,想在它的Git日志2023/9/26 19:08:08前插入一条2023/9/28 19:08:0…...
【数据库】MySQL InnoDB存储引擎详解 - 读书笔记
MySQL InnoDB存储引擎详解 - 读书笔记 InnoDB 存储引擎概述InnoDB 存储引擎的版本InnoDB 体系架构内存缓冲池LRU List、Free List 和 Flush List重做日志缓冲(redo log buffer)额外的内存池 存储结构表空间系统表空间独立表空间通用表空间undo表空间临时…...
GPT-2原理-Language Models are Unsupervised Multitask Learners
文章目录 前言GPT-1优缺点回顾GPT-1实验结果分析GPT-1缺陷分析 GPT-2训练数据OpenAI的野心预训练/微调的训练范式训练数据选择 模型结构和参数(更大的GPT-1)模型预训练训练参数 输入数据编码 总结 前言 首先强调一下,在看这篇文章之前&#…...
逆向案例十二——看准网企业信息json格式的信息
网址:【全国公司排行|排名榜单|哪家好】-看准网 打开开发者工具——刷新——网络——XHR——下滑页面加载新的页面——找到数据包 发现参数加密,返回的数据也进行了加密 按关键字在下方搜索 kiv进入第一个js文件 ctrlf打开文件里面的搜索框继续搜kiv找到…...
我自己做的网站一直没有效果怎么办/seo网站推广目的
Zipkin 是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于 Google Dapper 的论文设计而来,由 Twitter公司开发贡献。其主要功能是聚集来自各个异构系统的实时监控数据,用来追踪微服务架构下的系统…...
合肥网络公司 网站建设/成功的软文推广
浅谈C语言中函数形参为地址类型定义形式和类型自动转换浅谈C语言中函数形参为地址类型定义形式和类型自动转换摘要:当函数参数为地址类型时,可以有多种定义形式,因而读者易产生迷惑,通过对各种实例的分析和证明,介绍了…...
注册网站页面跳转错误/怎样申请网站
最近在补CSS的基础,看到盒子觉得理解起来比较混乱和困难,于是在网上查了好多资料,然后自己整理之后写了下来。 这次写一下块级元素、块级盒子以及BFC,如果有错误,欢迎大家指正 :) 在页面中&…...
wordpress无法评论/seo网站优化方法
项目背景和意义 目的:本课题主要目标是设计并能够实现一个基于微信小程序运动场地预约系统,前台用户使用小程序,后台管理使用基PHPMySql的B/S架构;通过后台添加开放的场地类型(比如羽毛球、篮球、网球等)、…...
宜城营销型网站套餐/seo优化行业
现在大部分人家里都会养些宠物,比如猫猫狗狗的,狗子很可爱,拆家很上头, 养狗有三怕:拆家、乱拉屎、整夜叫。虽然狗狗的一些行为习惯跟与遗传有关, 但是主人后天的影响也会给狗狗带来改变,因此…...
网站开发设计资讯/企业网站制作与维护
每天一点点,记录工作中实操可行 hive json数组解析 hive中有字段A长这个样子,想把其中的name值全部解析出来 [{"itemRateId":"73288842","name":"东北有机大米饭","rating":4,"ratingContent&…...