此文章主要介绍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倍数的分辨率设置,还是说我的方法不严谨,欢迎交流。

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: