Spaces:
Running
on
Zero
Running
on
Zero
""" | |
Script for Creating Waymo Semantic Segmentation Submission | |
The Waymo dataset toolkit relies on an old version of Tensorflow | |
which share a conflicting dependency with the Pointcept environment, | |
therefore we detach the submission generation from the test process | |
and the script require the following environment: | |
```bash | |
conda create -n waymo python=3.8 -y | |
conda activate waymo | |
pip3 install waymo-open-dataset-tf-2-11-0 | |
``` | |
Author: Xiaoyang Wu (xiaoyang.wu.cs@gmail.com) | |
Please cite our work if the code is helpful to you. | |
""" | |
import os | |
import tqdm | |
import argparse | |
import numpy as np | |
import zlib | |
import waymo_open_dataset.dataset_pb2 as open_dataset | |
from waymo_open_dataset.protos import segmentation_metrics_pb2 | |
from waymo_open_dataset.protos import segmentation_submission_pb2 | |
def compress_array(array: np.ndarray, is_int32: bool = False): | |
"""Compress a numpy array to ZLIP compressed serialized MatrixFloat/Int32. | |
Args: | |
array: A numpy array. | |
is_int32: If true, use MatrixInt32, otherwise use MatrixFloat. | |
Returns: | |
The compressed bytes. | |
""" | |
if is_int32: | |
m = open_dataset.MatrixInt32() | |
else: | |
m = open_dataset.MatrixFloat() | |
m.shape.dims.extend(list(array.shape)) | |
m.data.extend(array.reshape([-1]).tolist()) | |
return zlib.compress(m.SerializeToString()) | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser() | |
parser.add_argument( | |
"--record_path", | |
required=True, | |
help="Path to the prediction result folder of Waymo dataset", | |
) | |
parser.add_argument( | |
"--dataset_path", | |
required=True, | |
help="Path to the processed Waymo dataset", | |
) | |
parser.add_argument( | |
"--split", | |
required=True, | |
choices=["validation", "testing"], | |
help="Split of the prediction ([training, validation, testing]).", | |
) | |
args = parser.parse_args() | |
file_list = [file for file in os.listdir(args.record_path) if file.endswith(".npy")] | |
submission = segmentation_submission_pb2.SemanticSegmentationSubmission() | |
frames = segmentation_metrics_pb2.SegmentationFrameList() | |
bar = tqdm.tqdm(file_list) | |
for file in bar: | |
bar.set_postfix(file=file) | |
context_name, frame_timestamp_micros = file.strip("segment-*_pred.npy").split( | |
"_with_camera_labels_" | |
) | |
# Load prediction. | |
# In Pointcept waymo dataset, we minus 1 to label to ignore UNLABELLED class (0 -> -1) | |
pred = np.load(os.path.join(args.record_path, file)) + 1 | |
masks = np.load( | |
os.path.join( | |
args.dataset_path, | |
args.split, | |
f"segment-{context_name}_with_camera_labels", | |
frame_timestamp_micros, | |
"mask.npy", | |
), | |
allow_pickle=True, | |
) | |
offset = np.cumsum([mask.sum() for mask in masks.reshape(-1)]) | |
pred = np.split(pred[: offset[-1]], offset[:-1]) | |
pred_ri1 = pred[0] | |
pred_ri2 = pred[5] | |
mask_ri1 = np.expand_dims(masks[0, 0], -1) | |
mask_ri2 = np.expand_dims(masks[1, 0], -1) | |
range_dummy = np.zeros_like(mask_ri1, dtype=np.int32) | |
range_pred_ri1 = np.zeros_like(mask_ri1, dtype=np.int32) | |
range_pred_ri1[mask_ri1] = pred_ri1 | |
range_pred_ri1 = np.concatenate([range_dummy, range_pred_ri1], axis=-1) | |
range_pred_ri2 = np.zeros_like(mask_ri2, dtype=np.int32) | |
range_pred_ri2[mask_ri2] = pred_ri2 | |
range_pred_ri2 = np.concatenate([range_dummy, range_pred_ri2], axis=-1) | |
# generate frame submission | |
segmentation_label = open_dataset.Laser() | |
segmentation_label.name = open_dataset.LaserName.TOP | |
segmentation_label.ri_return1.segmentation_label_compressed = compress_array( | |
range_pred_ri1, is_int32=True | |
) | |
segmentation_label.ri_return2.segmentation_label_compressed = compress_array( | |
range_pred_ri2, is_int32=True | |
) | |
frame = segmentation_metrics_pb2.SegmentationFrame() | |
frame.segmentation_labels.append(segmentation_label) | |
frame.context_name = context_name | |
frame.frame_timestamp_micros = int(frame_timestamp_micros) | |
frames.frames.append(frame) | |
submission.account_name = "***" | |
submission.unique_method_name = "***" | |
submission.authors.append("***") | |
submission.affiliation = "***" | |
submission.method_link = "***" | |
submission.sensor_type = ( | |
segmentation_submission_pb2.SemanticSegmentationSubmission.LIDAR_ALL | |
) | |
submission.number_past_frames_exclude_current = 0 | |
submission.number_future_frames_exclude_current = 0 | |
submission.inference_results.CopyFrom(frames) | |
output_filename = os.path.join(args.record_path, "submission.bin") | |
f = open(output_filename, "wb") | |
f.write(submission.SerializeToString()) | |
f.close() | |