Carla之语义分割及BoundingBox验证模型

参考:
Carla系列——4.Cara模拟器添加语义分割相机(Semantic segmentation camera)
Carla自动驾驶仿真五:opencv绘制运动车辆的boudingbox(代码详解)
Carla官网Bounding Boxes
Carla官网创建自定义语义标签

一、模型导入

将建好的模型导入Carla中,放入D:\carla\Unreal\CarlaUE4\Content\Carla\Static\ [TagName]文件夹下,可以自定义标签(后面会写操作),也可以直接放入已有文件夹中(即标签)。
在Carla的这个文件夹中,每个文件夹代表一个标签,一个标签对应语义分割图像中的一个颜色。
在这里插入图片描述
例如:我将我的模型放在了D:\carla\Unreal\CarlaUE4\Content\Carla\Static\Building\Oil _\下面:
在这里插入图片描述
在这里插入图片描述

二、将模型加入PropFactory蓝图

在D:\carla\Unreal\CarlaUE4\Content\Carla\Blueprints\Props\中打开PropFactory蓝图,找到DefinitionMaps数组,在该数组中添加新的条目,填入导入的模型所在的路径位置和相关信息。
在这里插入图片描述
在D:\carla\Unreal\CarlaUE4\Content\Carla\Config\Default.Package.json中,填入新模型的信息。
在这里插入图片描述

三、添加自定义的语义标签类别

1.创建新的语义ID

打开 D:\carla\LibCarla\source\carla\rpc\ObjectLabel.h 文件,在枚举末尾添加新标记,使用与其他标记相同的格式。

2.为资源创建 UE 文件夹

打开虚幻引擎编辑器,然后转到 D:\carla\Unreal\CarlaUE4\Content\Carla\Static。创建一个名为您的标签的新文件夹。
在这里插入图片描述

3.在UE和代码标签之间创建双向对应关系

在 D:\carla\Unreal\CarlaUE4\Plugins\Carla\Source\Carla\Game 中打开 Tagger.cpp。
(1)转到 GetLabelByFolderName,在列表末尾添加您的标记。要比较的字符串中使用的 UE 文件夹的名称,因此此处使用完全相同的名称。

在这里插入图片描述(2)转到 GetTagAsString 中。在交换机末尾添加新标记。
在这里插入图片描述

4.定义颜色代码

打开 D:\carla\LibCarla\source\carla\image\CityScapesPalette.h ,在数组末尾添加新标记的颜色代码。
上面一行的末尾记得加逗号,在这里我将颜色定义为了大红色
在这里插入图片描述

新的语义标记已准备就绪,可供使用。只有存储在标签的 UE 文件夹中的网格才会被标记为这样。将相应的网格移动或导入到新文件夹,以便正确标记。

5.向 carla 添加标签

此步骤与语义分割没有直接关系。但是,这些标记可用于筛选 carla 中的边界框查询。为此,必须将标签添加到 carla PythonAPI 中的 CityObjectLabel 枚举。打开 D:\carla\PythonAPI\carla\source\libcarla\World.cpp
在这里插入图片描述
如果你使用的了自定义的文件夹,记得修改上面有关该模型位置的路径信息!

四、语义分割相机&BoundingBox检测模型是否正确

将模型拖入到场景中之后,运行以下代码:

语义分割代码:

import glob
import os
import sys
import time
import random
import time
import numpy as np
import cv2

try:
    sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
        sys.version_info.major,
        sys.version_info.minor,
        'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
    pass

import carla
from carla import Transform, Location, Rotation

IM_WIDTH = 640
IM_HEIIGHT = 480


def process_semantic(image):
    image.convert(carla.ColorConverter.CityScapesPalette)
    array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
    array = np.reshape(array, (image.height, image.width, 4))
    array = array[:, :, :3]
    cv2.imshow("", array)
    cv2.waitKey(20)
    return array / 255.0


actor_list = []
try:
    # 连接master
    client = carla.Client('localhost', 2000)
    client.set_timeout(5.0)
    world = client.get_world()
    blueprint_library = world.get_blueprint_library()
    bp = blueprint_library.filter("model3")[0]
    spawn_point = Transform(Location(x=54.469772, y=-64.348633, z=0.600000), Rotation(pitch=0.000000, yaw=179.976562, roll=0.000000))
    vehicle = world.spawn_actor(bp, spawn_point)

    vehicle.set_autopilot(enabled=True)
    actor_list.append(vehicle)
    # 添加一个语义分割相机
    sem_cam = None
    sem_bp = world.get_blueprint_library().find('sensor.camera.semantic_segmentation')
    sem_bp.set_attribute("image_size_x", f"{IM_WIDTH}")
    sem_bp.set_attribute("image_size_y", f"{IM_HEIIGHT}")
    sem_bp.set_attribute("fov", str(105))
    sem_location = carla.Location(-5, 0, 2.5)
    sem_rotation = carla.Rotation(0, 0, 0)
    sem_transform = carla.Transform(sem_location, sem_rotation)
    sem_cam = world.spawn_actor(sem_bp, sem_transform, attach_to=vehicle, attachment_type=carla.AttachmentType.Rigid)
    actor_list.append(sem_cam)
    # 监听相机,并显示图像
    sem_cam.listen(lambda image: process_semantic(image))
    time.sleep(50)

finally:
    for actor in actor_list:
        actor.destroy()
    print("All cleaned up!")

运行效果:
在这里插入图片描述
使用自定义语义标签运行效果:
在这里插入图片描述
我去失败了!先去吃饭回来再看

BoundingBox代码:

import glob
import os
import sys

try:
    sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
        sys.version_info.major,
        sys.version_info.minor,
        'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
    pass

import carla
from carla import Transform, Location, Rotation
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]



# 生成的对象列表
actor_list=[]


try:
    #连接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 = random.choice(world.get_map().get_spawn_points())
    print(spawn_points)
    spawn_point = Transform(Location(x = 27.142294, y = 66.283257, z = 0.600000), Rotation(pitch=0.000000, yaw=-179.926727, roll=0.000000))
    vehicle = world.try_spawn_actor(vehicle_bp, spawn_points)
    actor_list.append(vehicle)

    # 生成相机
    camera_bp = bp_lib.find('sensor.camera.rgb')
    camera_bp.set_attribute('image_size_x','960')
    camera_bp.set_attribute('image_size_y','540')
    camera_init_trans = carla.Transform(carla.Location(z=2))
    camera = world.spawn_actor(camera_bp, camera_init_trans, attach_to=vehicle)
    actor_list.append(camera)
    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(world.get_map().get_spawn_points()))
        if npc:
            npc.set_autopilot(True)
            actor_list.append(npc)


    # 设置仿真模式为同步模式
    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()


finally:
    for actor in actor_list:
        actor.destroy()
    print("All cleaned up!")

 

运行效果:
在这里插入图片描述

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

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

相关文章

【离散数学必刷题】谓词逻辑(第二章 左孝凌版)刷完包过!

专栏&#xff1a;离散数学必刷题 本章需要掌握的重要知识&#xff1a; 1.利用谓词表达式表示命题 2.变元的约束 3.谓词公式的定义、谓词公式的赋值 4.谓词公式的翻译&#xff08;注意在全总个体域时使用特性谓词&#xff09; 5.有限论域上量词的消去 6.谓词公式中关于量词的等价…

软件工程——名词解释

适用多种类型的软件工程教材&#xff0c;有关名词释义的总结较为齐全~ 目录 1. 软件 2. 软件危机 3. 软件工程 4. 软件生存周期 5. 软件复用 6. 质量 7. 质量策划 8. 质量改进 9. 质量控制 10. 质量保证 11. 软件质量 12. 正式技术复审 13. ISO 14. ISO9000 15.…

思维模型 暗示效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。无形中引导他人的思想和行为。 1 暗示效应的应用 1.1 暗示效应在商业品牌树立中的应用 可口可乐的品牌形象&#xff1a;可口可乐通过广告、包装和营销活动&#xff0c;向消费者传递了一种…

macOS使用conda初体会

最近在扫盲测序的一些知识 其中需要安装一些软件进行练习&#xff0c;如质控的fastqc&#xff0c;然后需要用conda来配置环境变量和安装软件。记录一下方便后续查阅学习 1.安装miniconda 由于我的电脑之前已经安装了brew&#xff0c;所以我就直接用brew安装了 brew install …

基于STC12C5A60S2系列1T 8051单片机定时器/计数器应用

基于STC12C5A60S2系列1T 8051单片机定时器/计数器应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍STC12C5A60S2系列1T 8051单片机定时器/计数器介绍STC12C5A60S2系…

BGP基本配置实验

目录 一、实验拓扑 二、实验需求 三、实验步骤 1、IP地址配置 2、内部OSPF互通&#xff0c;配置OSPF协议 3、BGP建立邻居关系 4、R1和R5上把业务网段宣告进BGP 5、消除路由黑洞&#xff0c;在R2、R4上做路由引入 6、业务网段互通 一、实验拓扑 二、实验需求 1、按照图…

Gold-YOLO:基于收集-分配机制的高效目标检测器

文章目录 摘要1、简介2、相关工作2.1、实时目标检测器2.2、基于Transformer的目标检测2.3、用于目标检测的多尺度特征 3、方法3.1、预备知识3.2、低级收集和分发分支3.3、高阶段收集和分发分支3.4、增强的跨层信息流3.5、遮罩图像建模预训练 4、实验4.1、设置4.2、比较4.3.2、 …

Android14前台服务适配指南

Android14前台服务适配指南 Android 10引入了android:foregroundServiceType属性&#xff0c;用于帮助开发者更有目的地定义前台服务。这个属性在Android 14中被强制要求&#xff0c;必须指定适当的前台服务类型。以下是可选择的前台服务类型&#xff1a; camera: 相机应用。…

Git之分支与版本

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 1.开发测试上线git的使用 1.1. 环境讲述 当软件从开发到正式环境部署的过程中&#xff0c;不同环境的作用…

docker搭建etcd集群

最近用到etcd&#xff0c;就打算用docker搭建一套&#xff0c;学习整理了一下。记录在此&#xff0c;抛砖引玉。 文中的配置、代码见于https://gitee.com/bbjg001/darcy_common/tree/master/docker_compose_etcd 搭建一个单节点 docker run -d --name etcdx \-p 2379:2379 \…

matlab Silink PID 手动调参

&#xff08;业余&#xff09;PID即比例积分微分&#xff0c;它将给定值r(t)与实际输出值y(t)的偏差的比例(P)、积分(I)、微分(D)通过线性组合形成控制量&#xff0c;对被控对象进行控制。我们先用matlab Silink弄一个简易的PID例子&#xff1a; 中间三条就是比例&#xff0c;积…

Django中简单的增删改查

用户列表展示 建立列表 views.py def userlist(request):return render(request,userlist.html) urls.py urlpatterns [path(admin/, admin.site.urls),path(userlist/, views.userlist), ]templates----userlist.html <!DOCTYPE html> <html lang"en">…

大数据可视化数据大屏可视化模板【可视化项目案例-05】

🎉🎊🎉 你的技术旅程将在这里启航! 🚀🚀 本文选自专栏:可视化技术专栏100例 可视化技术专栏100例,包括但不限于大屏可视化、图表可视化等等。订阅专栏用户在文章底部可下载对应案例源码以供大家深入的学习研究。 🎓 每一个案例都会提供完整代码和详细的讲解,不…

matlab直线一级倒立摆lqr控制

1、内容简介 略 16-可以交流、咨询、答疑 matlab直线一级倒立摆lqr控制 2、内容说明 倒立摆是一个开环不稳定的强非线性系统&#xff0c;其控制策略与杂技运动员顶杆平衡表演的技巧有异曲同工之处&#xff0c;目的在于使得摆杆处于临界稳定状态&#xff0c;是进行控制理论研…

MYSQL字符串函数详解和实战(字符串函数大全,内含示例)

MySQL提供了许多字符串函数&#xff0c;用于处理和操作字符串数据。以下是一些常用的MYSQL字符串函数。 建议收藏以备后续用到查阅参考。 目录 一、CONCAT 拼接字符串 二、CONCAT_WS 拼接字符串 三、SUBSTR 取子字符串 四、SUBSTRING 取子字符串 五、SUBSTRING_INDEX 取子…

Linux 程序开发流程 / 基本开发工具 / Vim / GCC工具链 / Make 工具 / Makefile 模板

编辑整理 by Staok。 本文部分内容摘自 “100ask imx6ull” 开发板的配套资料&#xff08;如 百问网的《嵌入式Linux应用开发完全手册》&#xff0c;在 百问网 imx6ull pro 开发板 页面 中的《2.1 100ASK_IMX6ULL_PRO&#xff1a;开发板资料》或《2.2 全系列Linux教程&#xf…

文生图模型测评之HPS v2

文章目录 1. 简介2. HPD v22.1 相关数据集介绍2.2 HPD v2 的构建2.2.1 prompt collection2.2.2 image collection2.2.3 preference annotation3. Human Preference Score v23.1 构建模型3.2 实验结果4. 结论及局限性论文链接:Human Preference Score v2: A Solid Benchmark fo…

Java通过JNI技术调用C++动态链接库的helloword测试

JNI调用原理 原理就不细说了&#xff0c;其实就是写个库给Java调&#xff0c;可以百度一下Java JNI&#xff0c;下面是HelloWorld代码测试 编写一个本地测试类 package com.my.study.cpp_jni;/*** 测试Java调用C库* <p>使用命令javac -h . NativeTest.java自动生成C头…

Technology Strategy Patterns 学习笔记8- Communicating the Strategy-Decks(ppt模板)

1 Ghost Deck/Blank Deck 1.1 It’s a special way of making an initial deck that has a certain purpose 1.2 you’re making sure you have figured out what all the important shots are before incurring the major expense of shooting them 1.3 需要从技术、战略、产…

每天一点python——day66

#每天一点Python——66 #字符串的分隔 #如图&#xff1a; #方法①split()从左开始分隔&#xff0c;默认空格为分割字符&#xff0c;返回值是一个列表 shello world jisuanji#首先创建一个字符串 list1s.split() print(list1)#输出结果是&#xff1a;[hello, world, jisuanji]注…