Carla自动驾驶仿真五:opencv绘制运动车辆的boudingbox(代码详解)

这篇具有很好参考价值的文章主要介绍了Carla自动驾驶仿真五:opencv绘制运动车辆的boudingbox(代码详解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。



提示:以下是本篇文章正文内容,下面案例可供参考

一、安装opencv

1、opencv安装可以参照我上一篇文章:opencv安装教程 ,这一篇文章即将讲述如果在carla仿真中,将仿真世界中的车辆通过opencv将boudingbox绘制出来。

二、opencv绘制车辆的boudingbox

1、构造相机投影矩阵函数

def build_projection_matrix(w, h, fov):
    focal = w / (2.0 * np.tan(fov * np.pi / 360.0))
    K = np.identity(3)
    K[0, 0] = K[1, 1] = focal
    K[0, 2] = w / 2.0
    K[1, 2] = h / 2.0
    return K

1)该函数用于构建相机的投影矩阵:

  • w:相机视图的宽度(单位:像素)

  • h:相机视图的高度(单位:像素)

  • fov:相机的视野角度(单位:度)

  • 函数首先计算焦距(focal),使用公式 focal = w / (2.0 * np.tan(fov * np.pi / 360.0))。这里使用了 numpy 库中的 np.tan 函数来计算视角的正切值。

  • 然后,函数创建一个 3x3 的单位矩阵 K,作为投影矩阵。投影矩阵的主要作用是将三维空间中的点投影到二维图像平面上。在这里,投影矩阵的第一行和第二行的对角元素设置为焦距值,即 K[0, 0] = K[1, 1] = focal。投影矩阵的第一行和第二行的第三列元素设置为视图宽度和高度的一半,即 K[0, 2] = w / 2.0K[1, 2] = h / 2.0

  • 最后,函数返回构建的投影矩阵 K。

2)关于投影矩阵

  • 对于相机投影矩阵,一个常见的3x3矩阵表示方式是使用齐次坐标(homogeneous coordinates):

    | fx 0 cx |
    | 0 fy cy |
    | 0 0 1 |

其中,fx和fy表示焦距在x和y方向上的缩放因子,cx和cy表示图像中心的偏移量。这个矩阵描述了从相机坐标系到图像坐标系的投影变换。


2、定义将Carla世界坐标转换成相机坐标的函数

def get_image_point(loc, K, w2c):
    # 计算三维坐标的二维投影

    # 格式化输入坐标(loc 是一个 carla.Position 对象)
    point = np.array([loc.x, loc.y, loc.z, 1])

    # 转换到相机坐标系
    point_camera = np.dot(w2c, point)

    # 将坐标系从 UE4 的坐标系转换为标准坐标系(y, -z, x),同时移除第四个分量
    point_camera = [point_camera[1], -point_camera[2], point_camera[0]]

    # 使用相机矩阵进行三维到二维投影
    point_img = np.dot(K, point_camera)

    # 归一化
    point_img[0] /= point_img[2]
    point_img[1] /= point_img[2]

    return point_img[0:2]

1)该函数用于计算三维坐标的二维投影。下面是函数的解释:

  • loc:一个 carla.Position 对象,表示三维坐标点的位置。

  • K:相机的投影矩阵。

  • w2c:世界坐标系到相机坐标系的转换矩阵。

  • 格式化输入坐标:将 loc 转换为一个包含 [x, y, z, 1] 的数组。

  • 将坐标转换到相机坐标系:使用矩阵乘法将坐标点 point 与世界坐标到相机坐标的转换矩阵 w2c 相乘,得到 point_camera

  • 转换坐标系:将坐标点从 UE4 的坐标系转换为标准坐标系 (y, -z, x),同时移除第四个分量。

  • 使用相机投影矩阵进行三维到二维投影:将 point_camera 与相机投影矩阵 K 相乘,得到投影后的二维坐标点 point_img

  • 归一化:将投影坐标点的 x 和 y 分量除以其 z 分量,以进行归一化。

  • 返回归一化后的二维投影坐标点的前两个分量,即 point_img[0:2]

  • 通过调用这个函数,并传入相应的参数,您可以将三维坐标点投影到相机视图中的二维坐标点,并进行归一化处理。


3、设置Carla并生成主车和相机

这部分在前几篇文章都讲过,不细讲了

#连接Carla并获取世界
client = carla.Client('localhost', 2000)
world  = client.get_world()
bp_lib = world.get_blueprint_library()

# 生成车辆
vehicle_bp =bp_lib.find('vehicle.lincoln.mkz_2020')
spawn_points = world.get_map().get_spawn_points()
vehicle = world.try_spawn_actor(vehicle_bp, random.choice(spawn_points))

# 生成相机
camera_bp = bp_lib.find('sensor.camera.rgb')
camera_init_trans = carla.Transform(carla.Location(z=2))
camera = world.spawn_actor(camera_bp, camera_init_trans, attach_to=vehicle)
vehicle.set_autopilot(True)

#生成目标车辆
for i in range(50):
    vehicle_bp = random.choice(bp_lib.filter('vehicle'))
    npc = world.try_spawn_actor(vehicle_bp, random.choice(spawn_points))
    if npc:
        npc.set_autopilot(True)

# 设置仿真模式为同步模式
settings = world.get_settings()
settings.synchronous_mode = True # 启用同步模式
settings.fixed_delta_seconds = 0.05
world.apply_settings(settings)

4、使用队列接收相机的数据

# 创建对接接收相机数据
image_queue = queue.Queue()
camera.listen(image_queue.put)

1)这段代码使用了队列(Queue)来接收图像数据。

  • 首先,创建了一个名为 image_queue 的队列对象,用于存储图像数据。

  • 然后,使用 camera.listen(image_queue.put) 将 camera 对象设置为监听模式,并将接收到的图像数据放入 image_queue 队列中,在后续中使用。


5、计算相机投影矩阵

计算相机投影矩阵,用于从三维坐标投影到二维坐标

# 从相机获取属性
image_w = camera_bp.get_attribute("image_size_x").as_int()  # 图像宽度
image_h = camera_bp.get_attribute("image_size_y").as_int()  # 图像高度
fov = camera_bp.get_attribute("fov").as_float()  # 视场角

# 计算相机投影矩阵,用于从三维坐标投影到二维坐标
K = build_projection_matrix(image_w, image_h, fov)

6、定义顶点创建边的列表

为了在相机图像上绘制边界框,我们需要以适当的顺序连接顶点以创建边。为此,我们需要以下边缘对列表:

edges = [[0,1], [1,3], [3,2], [2,0], [0,4], [4,5], [5,1], [5,7], [7,6], [6,4], [6,2], [7,3]]

7、通过opencv显示相机的画面

# 获取第一张图像
world.tick()
image = image_queue.get()

# 将原始数据重新整形为 RGB 数组
img = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4))

# 在 OpenCV 的显示窗口中显示图像
cv2.namedWindow('ImageWindowName', cv2.WINDOW_AUTOSIZE)
cv2.imshow('ImageWindowName', img)
cv2.waitKey(1)

1)通过以上代码,您可以完成以下操作:

  • 调用 world.tick() 更新世界状态,确保获取到最新的图像数据。
  • 使用 image_queue.get() 从图像队列中获取一张图像。
  • 将图像的原始数据重新整形为 RGB 数组,并存储在 img 中。
  • 使用 OpenCV 创建一个窗口,命名为 ‘ImageWindowName’,并将图像 img 显示在该窗口中。
  • 调用 cv2.waitKey(1) 等待用户按下键盘上的任意键来关闭图像窗口。

8、通过opencv绘制boudingbox

while True:
    # 更新世界状态并获取图像
    world.tick()
    image = image_queue.get()

    img = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4))

    # 获取相机投影矩阵
    world_2_camera = np.array(camera.get_transform().get_inverse_matrix())

    for npc in world.get_actors().filter('*vehicle*'):
        # 过滤掉自车
        if npc.id != vehicle.id:
            bb = npc.bounding_box
            dist = npc.get_transform().location.distance(vehicle.get_transform().location)

            # 筛选距离在50米以内的车辆
            if dist < 50:
                forward_vec = vehicle.get_transform().get_forward_vector()
                ray = npc.get_transform().location - vehicle.get_transform().location

                # 计算车辆前进方向与车辆之间的向量的点积,
                # 通过阈值判断是否在相机前方绘制边界框
                if forward_vec.dot(ray) > 1:
                    p1 = get_image_point(bb.location, K, world_2_camera)
                    verts = [v for v in bb.get_world_vertices(npc.get_transform())]

                    for edge in edges:
                        p1 = get_image_point(verts[edge[0]], K, world_2_camera)
                        p2 = get_image_point(verts[edge[1]], K, world_2_camera)
                        cv2.line(img, (int(p1[0]), int(p1[1])), (int(p2[0]), int(p2[1])), (255, 0, 0, 255), 1)

    cv2.imshow('ImageWindowName', img)
    if cv2.waitKey(1) == ord('q'):
        break

cv2.destroyAllWindows()

通过以上代码,实现了以下功能:

  • 循环获取图像并进行处理。
  • 将图像的原始数据重新整形为 RGB 数组,并存储在 img 中。
  • 获取世界到相机的矩阵。
  • 遍历世界中的车辆角色。
  • 过滤掉自车,并筛选出距离在 50 米内的车辆。
  • 计算车辆前向向量和车辆与其他车辆之间向量的点积,以判断是否在摄像头前方。
  • 将车辆的顶点投影到图像平面,并绘制边界框的线段。
  • 使用 OpenCV 显示处理后的图像。
  • 按下键盘上的 ‘q’ 键时,结束循环。

二、运行Carla与Python

1、打开Carla客户端

  • 运行carla客户端./CarlaUE4.sh -prefernvidia

Carla自动驾驶仿真五:opencv绘制运动车辆的boudingbox(代码详解)

2、运行Python程序

import carla
import random
import queue
import numpy as np
import cv2

#构造相机投影矩阵函数
def build_projection_matrix(w, h, fov):
    focal = w / (2.0 * np.tan(fov * np.pi / 360.0))
    K = np.identity(3)
    K[0, 0] = K[1, 1] = focal
    K[0, 2] = w / 2.0
    K[1, 2] = h / 2.0
    return K

def get_image_point(loc, K, w2c):
    # 计算三维坐标的二维投影

    # 格式化输入坐标(loc 是一个 carla.Position 对象)
    point = np.array([loc.x, loc.y, loc.z, 1])

    # 转换到相机坐标系
    point_camera = np.dot(w2c, point)

    # 将坐标系从 UE4 的坐标系转换为标准坐标系(y, -z, x),同时移除第四个分量
    point_camera = [point_camera[1], -point_camera[2], point_camera[0]]

    # 使用相机矩阵进行三维到二维投影
    point_img = np.dot(K, point_camera)

    # 归一化
    point_img[0] /= point_img[2]
    point_img[1] /= point_img[2]

    return point_img[0:2]

#连接Carla并获取世界
client = carla.Client('localhost', 2000)
world  = client.get_world()
bp_lib = world.get_blueprint_library()

# 生成车辆
vehicle_bp =bp_lib.find('vehicle.lincoln.mkz_2020')
spawn_points = world.get_map().get_spawn_points()
vehicle = world.try_spawn_actor(vehicle_bp, random.choice(spawn_points))

# 生成相机
camera_bp = bp_lib.find('sensor.camera.rgb')
camera_init_trans = carla.Transform(carla.Location(z=2))
camera = world.spawn_actor(camera_bp, camera_init_trans, attach_to=vehicle)
vehicle.set_autopilot(True)

#生成目标车辆
for i in range(20):
    vehicle_bp = random.choice(bp_lib.filter('vehicle'))
    npc = world.try_spawn_actor(vehicle_bp, random.choice(spawn_points))
    if npc:
        npc.set_autopilot(True)

# 设置仿真模式为同步模式
settings = world.get_settings()
settings.synchronous_mode = True # 启用同步模式
settings.fixed_delta_seconds = 0.05
world.apply_settings(settings)

# 创建对接接收相机数据
image_queue = queue.Queue()
camera.listen(image_queue.put)

# 从相机获取属性
image_w = camera_bp.get_attribute("image_size_x").as_int()  # 图像宽度
image_h = camera_bp.get_attribute("image_size_y").as_int()  # 图像高度
fov = camera_bp.get_attribute("fov").as_float()  # 视场角

# 计算相机投影矩阵,用于从三维坐标投影到二维坐标
K = build_projection_matrix(image_w, image_h, fov)

edges = [[0,1], [1,3], [3,2], [2,0], [0,4], [4,5], [5,1], [5,7], [7,6], [6,4], [6,2], [7,3]]

# 获取第一张图像
world.tick()
image = image_queue.get()

# 将原始数据重新整形为 RGB 数组
img = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4))

# 在 OpenCV 的显示窗口中显示图像
cv2.namedWindow('ImageWindowName', cv2.WINDOW_AUTOSIZE)
cv2.imshow('ImageWindowName', img)
cv2.waitKey(1)

while True:
    # 更新世界状态并获取图像
    world.tick()
    image = image_queue.get()

    img = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4))

    # 获取相机投影矩阵
    world_2_camera = np.array(camera.get_transform().get_inverse_matrix())

    for npc in world.get_actors().filter('*vehicle*'):
        # 过滤掉自车
        if npc.id != vehicle.id:
            bb = npc.bounding_box
            dist = npc.get_transform().location.distance(vehicle.get_transform().location)

            # 筛选距离在50米以内的车辆
            if dist < 50:
                forward_vec = vehicle.get_transform().get_forward_vector()
                ray = npc.get_transform().location - vehicle.get_transform().location

                # 计算车辆前进方向与车辆之间的向量的点积,
                # 通过阈值判断是否在相机前方绘制边界框
                if forward_vec.dot(ray) > 1:
                    p1 = get_image_point(bb.location, K, world_2_camera)
                    verts = [v for v in bb.get_world_vertices(npc.get_transform())]

                    for edge in edges:
                        p1 = get_image_point(verts[edge[0]], K, world_2_camera)
                        p2 = get_image_point(verts[edge[1]], K, world_2_camera)
                        cv2.line(img, (int(p1[0]), int(p1[1])), (int(p2[0]), int(p2[1])), (255, 0, 0, 255), 1)

    cv2.imshow('ImageWindowName', img)
    if cv2.waitKey(1) == ord('q'):
        break

cv2.destroyAllWindows()

3、boudingbox效果展示

Carla自动驾驶仿真五:opencv绘制运动车辆的boudingbox(代码详解)文章来源地址https://www.toymoban.com/news/detail-459489.html

到了这里,关于Carla自动驾驶仿真五:opencv绘制运动车辆的boudingbox(代码详解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • carla与ros2的自动驾驶算法-planning与control算法开发与仿真

    carla与ros2的自动驾驶算法-planning与control算法开发与仿真 欢迎大家来到自动驾驶Player(L5Player)的自动驾驶算法与仿真空间,在这个空间我们将一起完成这些事情: 控制算法构建基础模块并仿真调试:PID、LQR、Stanley 、MPC、滑膜控制、模糊控制、横向控制、纵向控制 运动规划算法

    2024年02月12日
    浏览(37)
  • OpenCV在工业自动化领域的运动控制与仿真

    作者:禅与计算机程序设计艺术 ​ OpenCV(Open Source Computer Vision Library)是一个开源跨平台计算机视觉库。它为程序员提供了很多基础性的图像处理、机器学习和计算机视觉方面的功能,可以用于开发各种应用场景,包括基于移动设备的视觉分析、工业自动化等。它的跨平台特性

    2024年02月11日
    浏览(31)
  • 车辆行驶控制运动学模型的matlab建模与仿真,仿真输出车辆动态行驶过程

    目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 基本假设 4.2 运动学方程 5.完整工程文件 车辆行驶控制运动学模型的matlab建模与仿真,仿真输出车辆动态行驶过程. 版本:MATLAB2022a        车辆运动学模型从几何学的角度研究车辆的运动规律。包括车辆的空

    2024年01月20日
    浏览(38)
  • 【OpenCV】 车辆识别 运动目标检测

    目录 一:车辆识别 运动目标检测 二:车辆识别实现 超详细步骤解析 步骤一:灰度化处理 步骤二:帧差处理 步骤三:二值化处理 步骤四:图像降噪 4-1 腐蚀处理 目的 去除白色噪点 4-2 膨胀处理 目的 把白色区域变大 步骤五:提取关键点 框选运动目标检测 三:车辆识别 完

    2024年02月04日
    浏览(42)
  • 车辆驾驶自动化分级

    由人类驾驶员全权操作车辆,车辆在行驶中可以得到预警和保护系统的辅助作用 在系统作用范围内,通过系统对转向、制动、驱动等系统中的一项进行短时间连续控制,其他的驾驶动作都由人类驾驶员进行操作 在系统作用范围内,通过系统对转向、制动、驱动等系统中的多

    2024年02月16日
    浏览(35)
  • 自动驾驶——车辆动力学模型

    A矩阵离散化 B矩阵离散化 反馈计算 前馈计算: 超前滞后反馈:steer_angle_feedback_augment 参考【运动控制】Apollo6.0的leadlag_controller解析 控制误差计算 横向距离误差计算 横向误差变化率计算 航向角误差计算 航向角误差变化率计算 参考:Apollo代码学习(三)—车辆动力学模型

    2024年02月12日
    浏览(49)
  • 自动驾驶TPM技术杂谈 ———— 车辆分类

    机动车规格分类 分类 说明 汽车 载客汽车 大型 车长大于或等于 6000mm 或者乘坐人数大于或等于20 人的载客汽车。 中型 车长小于 6000mm 且乘坐人数为10~19 人的载客汽车。 小型 车长小于 6000mm 且乘坐人数小于或等于9 人的载客汽车,但不包括微型载客汽车。 微型 车长小于或等

    2024年02月09日
    浏览(35)
  • 自动驾驶控制算法——车辆动力学模型

    考虑车辆 y 方向和绕 z 轴的旋转,可以得到车辆2自由度模型,如下图: m a y = F y f + F y r (2.1) ma_y = F_{yf} + F_{yr} tag{2.1} m a y ​ = F y f ​ + F yr ​ ( 2.1 ) I z ψ ¨ = l f F y f − l r F y r (2.2) I_zddotpsi = l_fF_{yf} - l_rF_{yr} tag{2.2} I z ​ ψ ¨ ​ = l f ​ F y f ​ − l r ​ F yr ​ ( 2.2 ) 经验公

    2024年01月18日
    浏览(49)
  • 自动驾驶港口车辆故障及事故处理机制

    (1)单一传感器数据异常处理。自动驾驶电动平板传感方案为冗余设置,有其他传感器能够覆盖故障传感器观测区域,感知/定位模块将数据异常情况发给到规划决策模块,由“大脑”向中控平台上报故障,同时继续进行当前任务,任务完成后自主前往预设维修地点,或根据

    2024年02月12日
    浏览(44)
  • 【自动驾驶】二自由度车辆动力学模型

    车辆数学模型 车辆模型-动力学模型(Dynamics Model) 我们作如下假设: 车辆所受的空气的力只会对车身坐标系x轴方向上的运动有影响,y轴方向和沿着z轴的旋转不会受到空气力的影响; 车辆运行在二维平面中,也就是z轴无速度。 车辆轮胎力运行在线性区间。 在运动学模型中,

    2023年04月12日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包