I tried to change a generated depth map in CARLA to BEV. But it didn't work correctly and doesn't have a correct top-down view. Here is my code:
import numpy as np
import cv2
import math
from numpy.lib.type_check import imag
from PIL import Image, ImageDraw
from matplotlib import cm
import matplotlib.pyplot as plt
import os
def get_depth(data):
"""
Computes the normalized depth
"""
data = data.astype(np.float32)
data = data[:, :, :3]
# normalized = full_lidar[:,1] *=-1np.dot(data, [65536.0, 256.0, 1.0])
normalized = np.dot(data, [1.0, 256.0, 65536.0])
normalized /= (256 * 256 * 256 - 1)
# in_meters = 1000 * normalized
return normalized
def depth_to_logarithmic_grayscale(image):
"""
Convert an image containing CARLA encoded depth-map to a logarithmic
grayscale image array.
"max_depth" is used to omit the points that are far enough.
"""
normalized_depth = get_depth(image)
# Convert to logarithmic depth.
logdepth = np.ones(normalized_depth.shape) + \
(np.log(normalized_depth) / 5.70378)
logdepth = np.clip(logdepth, 0.0, 1.0)
logdepth *= 255.0
return logdeth
def lidar_projection(lidar, crop=256):
"""
Convert LiDAR point cloud into a histogram over 256x256 grid, better suited for visualization
"""
def splat_points(point_cloud):
# 256 x 256 grid
pixels_per_meter = 8
hist_max_per_pixel = 5
x_meters_max = 16
y_meters_max = 32
xbins = np.linspace(-2*x_meters_max, 2*x_meters_max+1, 2*x_meters_max*pixels_per_meter+1)
ybins = np.linspace(-y_meters_max, 0, y_meters_max*pixels_per_meter+1)
hist = np.histogramdd(point_cloud[...,:2], bins=(xbins, ybins))[0]
hist[hist>hist_max_per_pixel] = hist_max_per_pixel
overhead_splat = hist/hist_max_per_pixel
return overhead_splat
projection = np.expand_dims(splat_points(lidar), 2)
features = np.transpose(projection, (2, 0, 1)).astype(np.float32)
return features
camera_width = 300
camera_height = 400
img_width = 300
img_height = 400
fov_width = 60
cx = camera_width / 2.0
cy = camera_height / 2.0
fov_height = 2.0 * np.arctan((img_height / img_width) * np.tan(0.5 * np.radians(fov_width)))
fov_height = np.rad2deg(fov_height)
fx = img_width / (2.0 * np.tan(np.deg2rad(fov_width) / 2.0))
fy = img_height / (2.0 * np.tan(np.deg2rad(fov_height) / 2.0))
img = np.asarray(Image.open(r'C:\Users\Documents\carla_sem_depth_test\depth.png'))
img = depth_to_logarithmic_grayscale(img)
Image.fromarray(img.astype(np.uint8)).save("depth_c2.png")
pcd = []
height, width = img.shape
for i in range(height):
for j in range(width):
z = img[i][j]
x = (j - cx) * z / fx
y = (i - cy) * z / fy
pcd.append([x, y, z])
pcd_arr = np.array(pcd)
pcd_arr[:,0] *=-1
depth_bev = lidar_projection(pcd_arr)
depth_bev = (depth_bev.squeeze(0)*255).astype(np.uint8)
img_path = r'C:\Users\Documents\carla_sem_depth_test'
Image.fromarray(np.rot90(depth_bev, 1, (1,0))).save(os.path.join(img_path, 'BEV.png'))
Here is the depth image: depth.png
Here is my BEV-Depth: BEV.png
I also checked the method like this link point_cloud_birdseye, which unfortunately didn't work as well. I think what I need is to change the view angle but I have no clue how I can do it.