-
Notifications
You must be signed in to change notification settings - Fork 4
/
image_converter.py
179 lines (150 loc) · 5.86 KB
/
image_converter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
Handy conversions for CARLA images.
The functions here are provided for real-time display, if you want to save the
converted images, save the images from Python without conversion and convert
them afterwards with the C++ implementation at "Util/ImageConverter" as it
provides considerably better performance.
"""
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
try:
import numpy as np
from numpy.matlib import repmat
except ImportError:
raise RuntimeError('cannot import numpy, make sure numpy package is installed')
def to_bgra_array(image):
"""Convert a CARLA raw image to a BGRA numpy array."""
'''
if not isinstance(image, sensor.Image):
raise ValueError("Argument must be a carla.sensor.Image")
'''
array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
array = np.reshape(array, (image.height, image.width, 4))
return array
def to_rgb_array(image):
"""Convert a CARLA raw image to a RGB numpy array."""
array = to_bgra_array(image)
# Convert BGRA to RGB.
array = array[:, :, :3]
#array = array[:, :, ::-1]
return array
def labels_to_array(image):
"""
Convert an image containing CARLA semantic segmentation labels to a 2D array
containing the label of each pixel.
"""
return to_bgra_array(image)[:, :, 2]
def labels_to_cityscapes_palette(image):
"""
Convert an image containing CARLA semantic segmentation labels to
Cityscapes palette.
"""
classes = {
0: [0, 0, 0], # None
1: [70, 70, 70], # Buildings
2: [190, 153, 153], # Fences
3: [72, 0, 90], # Other
4: [220, 20, 60], # Pedestrians
5: [153, 153, 153], # Poles
6: [157, 234, 50], # RoadLines
7: [128, 64, 128], # Roads
8: [244, 35, 232], # Sidewalks
9: [107, 142, 35], # Vegetation
10: [0, 0, 255], # Vehicles
11: [102, 102, 156], # Walls
12: [220, 220, 0] # TrafficSigns
}
array = labels_to_array(image)
result = np.zeros((array.shape[0], array.shape[1], 3))
for key, value in classes.items():
result[np.where(array == key)] = value
return result
def depth_to_array(image):
"""
Convert an image containing CARLA encoded depth-map to a 2D array containing
the depth value of each pixel normalized between [0.0, 1.0].
"""
array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
array = np.reshape(array, (image.height, image.width, 4)) # RGBA format
array = array[:, :, :3] # Take only RGB
array = array[:, :, ::-1] # BGR
array = array.astype(np.float32) # 2ms
gray_depth = ((array[:, :, 0] + array[:, :, 1] * 256.0 + array[:, :, 2] * 256.0 * 256.0) / (
(256.0 * 256.0 * 256.0) - 1)) # 2.5ms
gray_depth = 1000 * gray_depth
return gray_depth
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 = depth_to_array(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
# Expand to three colors.
return np.repeat(logdepth[:, :, np.newaxis], 3, axis=2)
"""
def depth_to_local_point_cloud(image, color=None, max_depth=0.9):
#Convert an image containing CARLA encoded depth-map to a 2D array containing
#the 3D position (relative to the camera) of each pixel and its corresponding
#RGB color of an array.
#"max_depth" is used to omit the points that are far enough.
far = 1000.0 # max depth in meters.
normalized_depth = depth_to_array(image)
# (Intrinsic) K Matrix
k = np.identity(3)
k[0, 2] = image.width / 2.0
k[1, 2] = image.height / 2.0
k[0, 0] = k[1, 1] = image.width / \
(2.0 * np.tan(image.fov * np.pi / 360.0))
# 2d pixel coordinates
pixel_length = image.width * image.height
u_coord = repmat(np.r_[image.width-1:-1:-1],
image.height, 1).reshape(pixel_length)
v_coord = repmat(np.c_[image.height-1:-1:-1],
1, image.width).reshape(pixel_length)
if color is not None:
color = color.reshape(pixel_length, 3)
normalized_depth = np.reshape(normalized_depth, pixel_length)
# Search for pixels where the depth is greater than max_depth to
# delete them
max_depth_indexes = np.where(normalized_depth > max_depth)
normalized_depth = np.delete(normalized_depth, max_depth_indexes)
u_coord = np.delete(u_coord, max_depth_indexes)
v_coord = np.delete(v_coord, max_depth_indexes)
if color is not None:
color = np.delete(color, max_depth_indexes, axis=0)
# pd2 = [u,v,1]
p2d = np.array([u_coord, v_coord, np.ones_like(u_coord)])
# P = [X,Y,Z]
p3d = np.dot(np.linalg.inv(k), p2d)
p3d *= normalized_depth * far
# Formating the output to:
# [[X1,Y1,Z1,R1,G1,B1],[X2,Y2,Z2,R2,G2,B2], ... [Xn,Yn,Zn,Rn,Gn,Bn]]
if color is not None:
# numpy.concatenate((numpy.transpose(p3d), color), axis=1)
return sensor.PointCloud(
image.frame_number,
np.transpose(p3d),
color_array=color)
# [[X1,Y1,Z1],[X2,Y2,Z2], ... [Xn,Yn,Zn]]
return sensor.PointCloud(image.frame_number, np.transpose(p3d))
"""