Python----计算机视觉处理(Opencv:道路检测之车道线显示)

完整版:Python----计算机视觉处理(Opencv:道路检测完整版:透视变换,提取车道线,车道线拟合,车道线显示)

一、透视变换 

        将透视变换之后的图像再继续透视变换为原图像

可参考Python----计算机视觉处理(Opencv:道路检测之道路透视变换)

 导入模块

import numpy as np
import cv2

输入图像 

img=cv2.imread('img_to_wrp.png')

 获得透视变换矩阵

height, width, _ = img.shape
src = np.float32([[width // 2 - 75, height // 2],[width // 2 + 100, height // 2],[0, height],[width, height]])
dst = np.float32([[0, 0],[width, 0],[0, height],[width, height]])
M = cv2.getPerspectiveTransform(dst,src )

 创建一个三通道背景图

wrp_zero=np.zeros_like(img_road1).astype(np.uint8)
color_wrp=np.dstack((wrp_zero,wrp_zero,wrp_zero))

组合车道线坐标

pts_left = np.transpose(np.vstack([left_fitx, ploty]))
pts_right = np.transpose(np.vstack([right_fitx, ploty]))
pts_middle = np.transpose(np.vstack([middle_fitx, ploty]))

绘制车道线

cv2.polylines(color_wrp, np.int32([pts_left]), isClosed=False, color=(202, 124, 0), thickness=15)
cv2.polylines(color_wrp, np.int32([pts_right]), isClosed=False, color=(202, 124, 0), thickness=15)
cv2.polylines(color_wrp, np.int32([pts_middle]), isClosed=False, color=(202, 124, 0), thickness=15)

将得到的车道线的像素点根据逆透视变换映射到原始图像中

newwarp = cv2.warpPerspective(color_wrp, M, (img.shape[1], img.shape[0]))

二、图像融合 

 将逆透视变换后的结果和原始图像进行融合

result1 = cv2.addWeighted(img, 1, newwarp, 1, 0)

创建一个灰色背景三通道图像

background_zero = np.zeros_like(img).astype(np.uint8) + 127

将原始图像和灰色背景融合 

result = cv2.addWeighted(background_zero, 1, newwarp, 1, 0)

图像合并 

concatenate_image1 = np.concatenate((img, img_wrp), axis=1)
concatenate_image2 = np.concatenate((result1, result), axis=1)
concatenate_image = np.concatenate((concatenate_image1,concatenate_image2), axis=0)

输出图像 

cv2.imshow('concatenate_image', concatenate_image) 
cv2.waitKey(0)

三、完整代码

# 读取图像  
img = cv2.imread('road_polyfit.png')  
height, width, _ = img.shape  # 获取图像的高度和宽度  # 定义源点(src)和目标点(dst)进行透视变换  
src = np.float32(  [  [width // 2 - 75, height // 2],  # 左侧车道线的源点  [width // 2 + 100, height // 2],  # 右侧车道线的源点  [0, height],  # 底部左侧点  [width, height]  # 底部右侧点  ]  
)  
dst = np.float32(  [  [0, 0],  # 目标左上角  [width, 0],  # 目标右上角  [0, height],  # 目标左下角  [width, height]  # 目标右下角  ]  
)  # 计算透视变换矩阵  
M = cv2.getPerspectiveTransform(dst, src)  # 创建一个与原图像同样大小的全黑图像用于保存透视变换后的车道线  
wrp_zero = np.zeros_like(img).astype(np.uint8)  # 创建一个颜色图像,用于绘制车道线  
color_wrp = np.dstack((wrp_zero, wrp_zero, wrp_zero))  # 将黑色图像复制成三个通道  # 组合车道线坐标  
pts_left = np.transpose(np.vstack([left_fitx, ploty]))  # 左侧车道线的坐标  
pts_right = np.transpose(np.vstack([right_fitx, ploty]))  # 右侧车道线的坐标  
pts_middle = np.transpose(np.vstack([middle_fitx, ploty]))  # 中间车道线的坐标  # 绘制车道线,使用指定的颜色和线宽  
cv2.polylines(color_wrp, np.int32([pts_left]), isClosed=False, color=(202, 124, 0), thickness=15)  
cv2.polylines(color_wrp, np.int32([pts_right]), isClosed=False, color=(202, 124, 0), thickness=15)  
cv2.polylines(color_wrp, np.int32([pts_middle]), isClosed=False, color=(202, 124, 0), thickness=15)  # 将得到的车道线的像素点根据逆透视变换映射到原始图像中  
newwarp = cv2.warpPerspective(color_wrp, M, (img.shape[1], img.shape[0]))  # 将逆透视变换后的结果和原始图像进行加权融合,显示最终效果  
result1 = cv2.addWeighted(img, 1, newwarp, 1, 0)  # 创建一个灰色背景图像,用于显示结果  
background_zero = np.zeros_like(img).astype(np.uint8) + 127  # 创建一幅灰色图像  # 经过加权融合得到结果  
result = cv2.addWeighted(background_zero, 1, newwarp, 1, 0)  # 拼接图像以便进行可视化  
concatenate_image1 = np.concatenate((img, img_wrp), axis=1)  # 拼接原始图像和变换后的图像  
concatenate_image2 = np.concatenate((result1, result), axis=1)  # 拼接加权融合的结果  
concatenate_image = np.concatenate((concatenate_image1, concatenate_image2), axis=0)  # 纵向拼接完整图像  cv2.imshow('concatenate_image', concatenate_image)  # 所有结果拼接的图像  
cv2.waitKey(0)  # 等待按键以结束  

四、库函数 

4.1、transpose()

返回轴转d 的数组。

对于一维数组,这将返回原始数组的未更改视图,因为转置d 向量只是相同的向量。 要将一维数组转换为二维列向量,需要一个额外的维度 必须添加,例如,实现此目的,就像 . 对于 2-D 数组,这是标准矩阵转置。 对于 n-D 数组,如果给定了轴,则它们的顺序表示 轴被置换(参见 Examples)。如果未提供 axes,则 。np.atleast_2d(a).Ta[:, np.newaxis]transpose(a).shape == a.shape[::-1]

numpy.transpose(a, axes=None)
方法描述
aInput 数组。
axes如果指定,则它必须是包含排列的 Tuples 或 List 的 [0, 1, ..., N-1] 其中 N 是 a 的轴数。阴性 indices 还可用于指定轴。返回的 数组将对应于输入的轴编号。 如果未指定,则默认为 ,这将反转 轴的顺序。axes[i]range(a.ndim)[::-1]

4.2、concatenate()

        沿现有轴连接数组序列。

numpy.concatenate((a1, a2, ...), axis=0, out=None, dtype=None, casting="same_kind")
方法描述
a1, a2, …数组必须具有相同的形状,但维度 对应于 axis (默认情况下是第一个)。
axis数组将沿其连接的轴。如果 axis 为 None,则 数组在使用前被展平。默认值为 0。
out如果提供,则为放置结果的目标。形状必须为 correct,匹配 concatenate 在 no out 参数。
dtype如果提供,目标数组将具有此 dtype。不能 与 out 一起提供。
casting控制可能发生的数据类型转换。默认为 'same_kind'。 有关选项的描述,请参阅铸造。

4.3、polylines()

        绘制多条多边形曲线。

cv.polylines(	img, pts, isClosed, color[, thickness[, lineType[, shift]]]	) ->	img
方法描述
img图像。
pts多边形曲线数组。
isClosed指示绘制的多段线是否闭合的标志。如果它们是闭合的,则该函数将从每条曲线的最后一个顶点到其第一个顶点绘制一条线。
color多段线颜色。
thickness多段线边线的粗细。
lineType线段的类型。请参阅线型
shift顶点坐标中的小数位数。

4.4、addWeighted()

cv.addWeighted(	src1, alpha, src2, beta, gamma[, dst[, dtype]]	) ->	dst
方法描述
src1first input 数组。
alpha第一个数组元素的权重。
src2第二个输入数组的大小和通道号与 src1 相同。
beta第二个数组元素的权重。
gamma添加到每个 sum 的标量。
dstoutput 数组,该数组具有与 input 数组相同的大小和通道数。
dtype输出数组的可选深度;当两个输入数组具有相同的深度时,可以将 dtype 设置为 -1,这相当于 src1.depth()。

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

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

相关文章

26届Java暑期实习面经,腾讯视频一面

短链接的生成原理 如何解决短链接生成的哈希冲突问题 如何加快从短链接到原链接的重定向过程 TCP 和 UDP 协议 如何理解 TCP 是面向连接的 为什么 TCP 的握手是 3 次 IO 模式 是否有真正写过一个底层的 Socket 通信 MySQL 的事务隔离级别 MVCC 机制 什么叫服务的并行 为什么能基…

Windows注册鼠标钩子,获取用户选中的文本

注册鼠标钩子 // 注册鼠标钩子 HHOOK hMouseHook; hMouseHook SetWindowsHookEx(WH_MOUSE_LL, MouseProc, GetModuleHandle(NULL), 0);// 取消鼠标钩子 UnhookWindowsHookEx(hMouseHook); hMouseHook nullptr; 上述代码中MouseProc方法用于处理系统的鼠标消息 处理鼠标消息…

flink cdc的source数据流如何配置事件时间,如何设置时间语义,分配时间戳并生成水位线

在 Flink CDC 中为 Source 数据流配置事件时间需要结合时间语义设置、时间戳分配和水位线生成三个核心步骤。以下是具体配置方法及注意事项: 1. 设置时间语义 Flink 默认使用处理时间(Processing Time),需显式指定事件时间语义&a…

C++ 指针类型转换全面解析与最佳实践

文章目录 C 指针类型转换全面解析与最佳实践1. 隐式转换基类和派生类指针 2. 显式转换(1) static_cast(2) dynamic_cast(3) reinterpret_cast(4) const_cast 3. C 风格转换4. 常见问题与注意事项5. 总结最佳实践 C 指针类型转换全面解析与最佳实践 在 C 中,指针类型…

批量将 txt/html/json/xml/csv 等文本拆分成多个文件

我们的文本文件太大的时候,我们通常需要对文本文件进行拆分,比如按多少行一个文件将一个大的文本文件拆分成多个小的文本文件。这样我们在打开或者传输的时候都比较方便。今天就给大家介绍一种同时对多个文本文件进行批量拆分的方法,可以快速…

ARM 汇编启动代码详解:从中断向量表到中断处理

ARM 汇编启动代码详解:从中断向量表到中断处理 引言 在嵌入式系统开发中,ARM 处理器(如 Cortex-A 系列)的启动代码是系统初始化和运行的基础。启动代码通常包括中断向量表的创建、初始化硬件状态(如关闭缓存和 MMU&a…

4.7学习总结 可变参数+集合工具类Collections+不可变集合

可变参数: 示例: public class test {public static void main(String[] args) {int sumgetSum(1,2,3,4,5,6,7,8,9,10);System.out.println(sum);}public static int getSum(int...arr){int sum0;for(int i:arr){sumi;}return sum;} } 细节&#xff1a…

2023年蓝桥杯第十四届CC++大学B组真题及代码

目录 1A:日期统计 解析代码_暴力_正解 2B:01串的熵 解析代码_暴力_正解 3C:冶炼金属 解析代码_暴力_正解 4D:飞机降落 解析代码_暴力dfs_正解 5E:接龙数列 解析代码_dp_正解 6F:岛屿个数 解析代…

rom定制系列------小米10pro机型定制解锁固件 原生安卓15批量线刷固件 操作解析与界面预览

注意;固件用于自己机型忘记密码或者手机号注销等出现设备锁 过保修期 售后无视的机型,勿用于非法途径 目前有粉丝联系,自己的机型由于手机号注销导致手机更新系统后出现设备锁界面。另外也没有解锁bl。目前无法使用手机。经过询问是小米10pro机型。根据…

信息学奥赛一本通 1861:【10NOIP提高组】关押罪犯 | 洛谷 P1525 [NOIP 2010 提高组] 关押罪犯

【题目链接】 ybt 1861:【10NOIP提高组】关押罪犯 洛谷 P1525 [NOIP 2010 提高组] 关押罪犯 【题目考点】 1. 图论:二分图 2. 二分答案 3. 种类并查集 【解题思路】 解法1:种类并查集 一个囚犯是一个顶点,一个囚犯对可以看…

我的NISP二级之路-01

目录 一.SSE-CMM系统安全工程-能力成熟度模型(Systems Security Engineering - Capability Maturity Model) 二.ISMS 即信息安全管理体系(Information Security Management System),是一种基于风险管理的、系统化的管理体系 三.Kerberos协议 1. 用户登录与 AS 请求 2…

WEB安全--内网渗透--利用Net-NTLMv2 Hash

一、前言 在前两篇文章中分析了NTLM协议中Net-NTLMv2 Hash的生成、如何捕获Net-NTLMv2 Hash,现在就来探讨一下在内网环境中,如何利用Net-NTLMv2 Hash进行渗透。 二、Net-NTLM Hash的破解 工具:hashcat 原理:利用其内部的字典对…

如何正确使用 `apiStore` 进行 API 管理

在现代前端开发中,API 管理是一个非常重要的环节。apiStore 是一个基于 Pinia 的状态管理工具,它可以帮助我们更高效地管理和调用 API。本文将详细介绍如何正确使用 apiStore,包括如何创建 API 配置文件、在组件中使用 apiStore 以及如何配置…

瓦片数据合并方法

影像数据 假如有两份影像数据 1.全球底层影像0-5级别如下: 2.局部高清影像数据级别9-14如下: 合并方法 将9-14文件夹复制到全球底层0-5的目录下 如下: 然后合并xml文件 使得Tileset设置到最高级(包含所有级别)&…

C++中的类和对象(上)

1 类的定义 1.1 类定义的格式 1 class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省 略》。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数…

【Tauri2】013——前端Window Event与创建Window

前言 【Tauri2】012——on_window_event函数-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146909801?spm1001.2014.3001.5501 前面介绍了on_window_event,这个在Builder中的方法,里面有许多事件,比如Moved,Res…

【问题处理】webpack4升webpack5,报错Uncaught ReferrnceError: process is not defined

问题 正在做webpack4升webpack5,项目构建项目成功后在浏览器打开时报错 Uncaught ReferrnceError: process is not defined。 原因 webpack 5 不再自动 polyfill Node.js 的核心模块。 如果你在浏览器运行的代码中使用它,需要从 NPM 中安装兼容模块…

软件工程师减肥计划

一、目标设定 在 3 个月内减轻体重 5-7kg,改善身体代谢水平和体脂率,增强身体活力和精神状态,以更好地适应工作强度。 二、饮食调整 (一)基本原则 控制热量摄入,保证每天摄入热量低于消耗热量 500-800 …

即时访问成为降低风险的关键

云计算和软件即服务 (SaaS) 解决方案的广泛采用从根本上重塑了企业的数字格局。 不同行业的组织越来越多地利用云固有的可扩展性和成本效益来推动创新和简化运营。 这种向基于云的环境的转变也带来了一系列新的复杂安全挑战,需要仔细考虑并制定强有力的缓解策略。…

[环境配置] 1. 开发环境搭建

开发环境搭建 本文档将详细介绍如何搭建深度学习开发环境,包括 Python 环境配置、IDE 选择与配置以及虚拟环境管理。 也会介绍一下最近比较流行的 uv 工具。它是一个用 Rust 编写的极其快速的 Python 包和项目管理工具。 uv 是一个非常强大的工具,它可…