Carla自动驾驶仿真六:pygame多个车辆摄像头画面拼接

news2024/11/19 19:27:06

此文章主要介绍carla前后左右摄像头画面拼接到pygame上

文章目录

  • 前言
  • 一、要点分析
  • 二、完整代码
  • 三、拼接效果
  • 四、总结


前言

1、使用carla做仿真测试或者开发时,如果能够将车辆周边的画面拼接并渲染,可以直观地查看周围地环境,便于调试。本文将介绍使用carla中的camera传感器监控自车周边的画面,并通过pygame可视化。

一、要点分析

1、如果摄像头的横向分辨率image_x如果不为192的倍数,可能会导致内存对齐问题,拼接效果则会出现闪屏;调试了很久才发现这个规律,知道具体原因的大佬可以交流下,猜测是显卡解析相关导致。即:Image_x = 192 * N (N为正整数),下图为分辨率不为192倍数的拼接情况。

在这里插入图片描述

2、camera.listen(lambda data : callback(data)),listen方法是carla中用于设置摄像头传感器的回调函数的。当摄像头传感器捕获到新的图像数据image时,它会调用这个回调函数,并将图像数据image作为参数传递给它。下图中的cala.SensorData就是carla.Image,具体更多内容可以到carla官网查看。

在这里插入图片描述
在这里插入图片描述

3、使用np.concatenate拼接不同摄像头的数据。
1)numpy.concatenate是一个用于将多个数组沿指定轴连接在一起的函数。它的基本语法如下:

numpy.concatenate((a1, a2, ...), axis=0)

2)其中,a1, a2, …是你想要连接的数组,axis参数指定了连接的轴。默认情况下,axis是0,这意味着数组将在垂直方向上(即行方向)连接,当axis=1时,数组将在水平方向上(即列方向)连接。

import numpy as np

a = np.array([1, 2])
b = np.array([3, 4])
c = np.concatenate((a, b), axis=0)

print(c)  # 输出:[1 2 3 4]

==============================

a1 = np.array([[1, 2], [3, 4]])
a2 = np.array([[5, 6], [7, 8]])

c = np.concatenate((a1, a2), axis=1)

print(c)
#输出
[[1 2 5 6]
 [3 4 7 8]]

二、完整代码

import carla
import random
import pygame
import numpy as np

# 渲染对象来保持和传递 PyGame 表面
class RenderObject(object):
    def __init__(self, width, height):
        init_image = np.random.randint(0, 255, (height, width, 3), dtype='uint8')
        self.surface = pygame.surfarray.make_surface(init_image.swapaxes(0, 1))

# 相机传感器回调,将相机的原始数据重塑为 2D RGB,并应用于 PyGame 表面
def pygame_callback(image, side):
    img = np.reshape(np.copy(image.raw_data), (image.height, image.width, 4))
    img = img[:, :, :3]
    img = img[:, :, ::-1]
    if side == 'Front':
        global Front
        Front = img
    elif side == 'Rear':
        global Rear
        Rear = img
    elif side == 'Left':
        global Left
        Left = img
    elif side == 'Right':
        global Right
        Right = img

    if ('Front' in globals() and 'Rear' in globals()
        and "Left" in globals()and 'Right' in globals()):
        # 横向拼接(前后)(左右)摄像头的画面
        img_combined_front = np.concatenate((Front, Rear), axis=1)
        img_combined_rear = np.concatenate((Left, Right), axis=1)
        # 纵向拼接(前后)(左右)摄像头的画面
        img_combined = np.concatenate((img_combined_front, img_combined_rear), axis=0)
        renderObject.surface = pygame.surfarray.make_surface(img_combined.swapaxes(0, 1))

class cameraManage():
    def __init__(self, world, ego_vehicle, pygame_size):
        self.world = world
        self.cameras = {}
        self.ego_vehicle = ego_vehicle
        self.image_size_x = int(pygame_size.get("image_x") / 2)  # 横向放置两个摄像头的画面
        self.image_size_y = int(pygame_size.get("image_y") / 2)  # 纵向放置两个摄像头的画面

    def camaraGenarate(self):
        cameras_transform = [
            (carla.Transform(carla.Location(x=2.0, y=0.0, z=1.3),  # 前侧摄像头安装位置
                             carla.Rotation(pitch=0, yaw=0, roll=0)), "Front"),
            (carla.Transform(carla.Location(x=-2.0, y=0.0, z=1.3),  # 后侧摄像头安装位置
                             carla.Rotation(pitch=0, yaw=180, roll=0)), "Rear"),
            (carla.Transform(carla.Location(x=0.0, y=2.0, z=1.3),  # 左侧摄像头安装位置
                             carla.Rotation(pitch=0, yaw=90, roll=0)), "Left"),
            (carla.Transform(carla.Location(x=0.0, y=-2.0, z=1.3),  # 右侧的摄像头安装位置
                             carla.Rotation(pitch=0, yaw=-90, roll=0)), "Right")
        ]
        # 查找RGB相机蓝图
        camera_bp = self.world.get_blueprint_library().find('sensor.camera.rgb')
        # 设置摄像头的fov为90°
        camera_bp.set_attribute('fov', "90")
        # 设置摄像头的分辨率
        camera_bp.set_attribute('image_size_x', str(self.image_size_x))
        camera_bp.set_attribute('image_size_y', str(self.image_size_y))
        # 生成摄像头
        for index, (camera_ts, camera_sd) in enumerate(cameras_transform):
            camera = self.world.spawn_actor(camera_bp, camera_ts, attach_to=self.ego_vehicle)
            self.cameras[camera_sd] = camera
        return self.cameras


if __name__ == "__main__":
    # 连接到客户端并检索世界对象
    client = carla.Client('localhost', 2000)
    world = client.get_world()

    # 获取地图的刷出点
    spawn_point = random.choice(world.get_map().get_spawn_points())

    # 生成车辆并设置自动驾驶
    vehicle_bp = world.get_blueprint_library().filter('*vehicle*').filter('vehicle.tesla.*')[0]
    ego_vehicle = world.spawn_actor(vehicle_bp, spawn_point)
    # ego_vehicle.set_autopilot(True)

    #设置pygame窗口size,image_x为192的整数倍,用其他分辨率会闪屏,可能是显卡解析原因导致。
    pygame_size = {
        "image_x": 1152,
        "image_y": 600
    }

    #调用cameraManage类,生成摄像头
    cameras = cameraManage(world, ego_vehicle, pygame_size).camaraGenarate()

    #采集carla世界中camera的图像
    cameras.get("Front").listen(lambda image: pygame_callback(image, 'Front'))
    cameras.get("Rear").listen(lambda image: pygame_callback(image, 'Rear'))
    cameras.get("Left").listen(lambda image: pygame_callback(image, 'Left'))
    cameras.get("Right").listen(lambda image: pygame_callback(image, 'Right'))

    # 为渲染实例化对象
    renderObject = RenderObject(pygame_size.get("image_x"), pygame_size.get("image_y"))

    # 初始化pygame显示
    pygame.init()
    gameDisplay = pygame.display.set_mode((pygame_size.get("image_x"), pygame_size.get("image_y")),
                                          pygame.HWSURFACE | pygame.DOUBLEBUF)
    # 循环执行
    crashed = False
    while not crashed:
        # 等待同步
        world.tick()

        # 按帧更新渲染的 Camera 画面
        gameDisplay.blit(renderObject.surface, (0, 0))
        pygame.display.flip()

        # 获取 pygame 事件
        for event in pygame.event.get():
            # If the window is closed, break the while loop
            if event.type == pygame.QUIT:
                crashed = True

    # 结束
    ego_vehicle.destroy()
    camera = cameras.values()
    for cam in camera:
        cam.stop
    pygame.quit()

三、拼接效果

在这里插入图片描述


四、总结

欢迎各位大佬来交流,特别是为什么只支持192倍数的分辨率设置,还是说我的方法不严谨,欢迎交流。

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

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

相关文章

SpringBoot 自动装配原理详解

什么是 SpringBoot 自动装配? 我们现在提到自动装配的时候,一般会和 Spring Boot 联系在一起。但是,实际上 Spring Framework 早就实现了这个功能。Spring Boot 只是在其基础上,通过 SPI 的方式,做了进一步优化。 Spr…

社区分享|简米Ping++基于MeterSphere开展异地测试协作

上海简米网络科技有限公司(以下简称为“简米”)是国内开放银行服务商,高新技术企业,中国支付清算协会会员单位。自2014年成立至今,简米长年聚焦金融科技领域,通过与银行、清算组织等金融机构合作&#xff0…

python爬虫学习-批量爬取图片

python爬虫学习-批量爬取图片 爬虫步骤爬取前十页图片到本地根据页码获取网络源码使用xpath解析网页解析网页并下载图片主函数如下 爬取的网站为站长素材(仅做学习使用) 爬取的目标网站为 https://sc.chinaz.com/tupian/qinglvtupian.html如果爬取多页&…

【ArcGIS Pro微课1000例】0051:创建数据最小几何边界范围(点、线、面数据均可)

本实例为专栏系统文章:创建点数据最小几何边界(范围),配套案例数据,持续同步更新! 文章目录 一、工具介绍二、实战演练三、注意事项一、工具介绍 创建包含若干面的要素类,用以表示封闭单个输入要素或成组的输入要素指定的最小边界几何。 工具界面及参数如下所示: 核心…

Python Reflex框架全攻略:手把手教你打造个性化全栈应用!

更多资料获取 📚 个人网站:ipengtao.com Reflex框架是一款专注于全栈开发的现代 JavaScript 框架,它强调响应式编程和简化复杂性,为开发者提供了构建动态且高效的全栈应用的工具。 Reflex框架是为了解决传统全栈开发中的一些挑战…

在python中安装库,会有conda安装,也会有pip安装,conda与pip的区别是什么?

文章目录 一、Conda是什么?二、pip是什么?三、pip与conda的区别:总结 一、Conda是什么? Conda是一个开源的包管理系统,它是Anaconda公司为Python和其他编程语言开发的。它主要用于数据科学和机器学习领域,…

通过Mock玩转Golang单元测试!

1.单元测试中的困难 如果项目中没有单元测试,对于刚刚开始或者说是规模还小的项目来说,效率可能还不错。但是一旦项目变得复杂起来,每次新增功能或对旧功能的改动都要重新手动测试一遍所有场景,费时费力,而且还有可能…

windows的cmd/PowerShell修改中文字符编码

1.简介 由于编程的时候经常会用到不同的编码,但是由于cmd/bat脚本和命令行默认的编码不一致,就导致了输出的中文乱码,使用chcp命令可以修改当前命令行的编码方式 2.查看与修改 2.1.查看 chcp 常用编码编号 65001:UTF-8936&am…

Python-pdf工具自制(合并、拆分、删除)

pdf工具,之前写的合并工具有点麻烦,使用PyQt5库重写合并拆分和删除指定页面的程序 实现如图: 代码: import sysimport osfrom PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QFileDia…

P10 Linux进程编程 fork创建子进程

目录 前言 01 fork()创建子进程 示例 1使用 fork()创建子进程。 02 fork创建新进程时发生了什么事? 2.1 父、子进程中对应的文件描述符指向了相同的文件表 前言 🎬 个人主页:ChenPi 🐻推荐专栏1: 《Linux C应用编程&#xf…

SystemVerilog学习(0)——目录与传送门

一、验证导论 SystemVerilog学习(1)——验证导论-CSDN博客文章浏览阅读403次。SystemVerilog自学,验证系统概述,什么是SVhttps://blog.csdn.net/apple_53311083/article/details/133953016 二、数据类型 SystemVerilog学习&…

hive自定义函数及案例

一.自定义函数 1.Hive自带了一些函数,比如:max/min等,但是数量有限,自己可以通过自定义UDF来方便的扩展。 2.当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数。 3.根据用户自定义…

文献速递:多模态影像组学文献分享:多模态图注意力网络用于COVID-19预后预测

文献速递:多模态影像组学文献分享:多模态图注意力网络用于COVID-19预后预测 01 文献速递介绍 在处理像 COVID-19 这样的新出现的疾病时,患者和疾病特定因素(例如,体重或已知共病)对疾病的即时进展的影响…

python数据分析总结(pandas)

目录 前言 df导入数据 df基本增删改查 数据清洗 ​编辑 索引操作 数据统计 行列操作 ​编辑 df->types 数据格式化 ​编辑 日期数据处理 前言 此篇文章为个人python数据分析学习总结,总结内容大都为表格和结构图方式,仅供参考。 df导入数…

Python 从入门到精通 学习笔记 Day03

Python 从入门到精通 第三天 今日目标 流程控制语句、退出循环、练习学习的内容 一、流程控制语句 流程控制的三种方式:顺序语句、双分支语句、循环语句 双分支语句 Python 的双分支语句使用if-else语句实现。 其语法结构如下: if条件:#如果条作为真&#xff…

stm32 使用18B20 测试温度

用18b20 测试温度是非常常用的,不过18B20的调试不是这么容易的,有些内容网上很多的,不再重复说了,我先把波形说一下,再说程序部分: 整个都温度数据的顺序是: 1.700uS的低电平复位并测试18B20的…

使用MetaMask + Ganache搭建本地私有网络并实现合约部署与互动

我使用Remix编写合约,MetaMask钱包工具和Ganache搭建了一个私有网络,并且实现了合约的部署和互动。 在前面的博客中提到了 Remix在线环境及钱包申请 以及 Solidity的基本语法 ,没看过的小伙伴可以点击链接查看一下,都是在本专栏下…

Swift 如何实现自定义 Tab Bar

前言 每个 UI 设计师都喜欢美丽而有动画效果的 Tab Bar。然而,对于开发人员来说,实现这种设计可能是一场噩梦。当然,使用 Apple 的原生 Tab Bar 组件并专注于更有趣的事情,比如业务逻辑的实现,会更容易。但如果我们必…

CPU、MCU、MPU、DSP、FPGA各是什么?有什么区别?

1、CPU 中央处理器,简称 CPU(Central Processing Unit),中央处理器主要包括两个部分,即控制器、运算器,其中还包括高速缓冲存储器及实现它们之间联系的数据、控制的总线。 电子计算机三大核心部件就是CPU…

了解c++11中的新增

一,统一的初始化列表 在引入c11后,我们得出计划都可以用初始化列表进行初始化。 C11 扩大了用大括号括起的列表 ( 初始化列表 ) 的使用范围,使其可用于所有的内置类型和用户自 定义的类型, 使用初始化列表时,可添加等…