diff --git a/config/config.json b/config/config.json
index 54c7f98..f9be833 100644
--- a/config/config.json
+++ b/config/config.json
@@ -2,11 +2,75 @@
"datasets": [
{
"name": "NuScenes",
- "sequences": ["ONE"]
+ "sequences": [
+ "ONE"
+ ],
+ "classes": [
+ "human.pedestrian.adult",
+ "human.pedestrian.child",
+ "human.pedestrian.wheelchair",
+ "human.pedestrian.stroller",
+ "human.pedestrian.personal_mobility",
+ "human.pedestrian.police_officer",
+ "human.pedestrian.construction_worker",
+ "animal",
+ "vehicle.car",
+ "vehicle.motorcycle",
+ "vehicle.bicycle",
+ "vehicle.bus.bendy",
+ "vehicle.bus.rigid",
+ "vehicle.truck",
+ "vehicle.construction",
+ "vehicle.emergency.ambulance",
+ "vehicle.emergency.police",
+ "vehicle.trailer",
+ "movable_object.barrier",
+ "movable_object.trafficcone",
+ "movable_object.pushable_pullable",
+ "movable_object.debris",
+ "static_object.bicycle_rack"
+ ],
+ "class_colors": [
+ "#3ABB9D",
+ "#4DA664",
+ "#2F6CAD",
+ "#4590B6",
+ "#5CADCF",
+ "#3585C5",
+ "#2CA786",
+ "#6ABB72",
+ "#E66B5B",
+ "#A28F85",
+ "#F79E3D",
+ "#75706B",
+ "#EE7841",
+ "#D1D5D8",
+ "#CC4846",
+ "#DC5047",
+ "#28324E",
+ "#EFEFEF",
+ "#485675",
+ "#F2D46F",
+ "#533D7F",
+ "#9069B5",
+ "#F7C23E"
+ ]
},
{
"name": "providentia",
- "sequences": ["20201010_sequence1"]
+ "sequences": [
+ "20201010_sequence1"
+ ],
+ "classes": [
+ "car",
+ "trailer",
+ "motorcycle",
+ "bicycle",
+ "bus",
+ "van",
+ "pedestrian"
+ ],
+ "class_colors": ["#51C38C", "#EBCF36","#FF604B", "#F37CB2","#7d74f5", "#BC7C52","#74BAF5"]
}
]
}
\ No newline at end of file
diff --git a/js/base_label_tool.js b/js/base_label_tool.js
index a428515..9159d46 100755
--- a/js/base_label_tool.js
+++ b/js/base_label_tool.js
@@ -29,7 +29,7 @@ let labelTool = {
imageSizes: {},
originalAnnotations: [], // For checking modified or not
skipFrameCount: 1,
- targetClass: "vehicle",
+ targetClass: "",
// pageBox: document.getElementById('page_num'),
savedFrames: [],
cubeArray: [],
@@ -158,7 +158,8 @@ let labelTool = {
pointSize: 1,
pointMaterial: new THREE.PointsMaterial({size: 5, sizeAttenuation: false, vertexColors: THREE.VertexColors}),
views: {perspective: "perspective", orthographic: "orthographic"},
- maxTrackIds: [0, 0, 0, 0, 0],// vehicle, truck, motorcycle, bicycle, pedestrian
+ classes: [],
+ classColors: [],
/********** Externally defined functions **********
* Define these functions in the labeling tools.
**************************************************/
@@ -337,7 +338,7 @@ let labelTool = {
pointCloudFullURL = 'input/' + labelTool.currentDataset + '/' + labelTool.sequence + '/' + 'pointclouds/' + labelTool.fileNames[i] + '.pcd';
pcdLoader.load(pointCloudFullURL, function (mesh) {
mesh.name = 'pointcloud-scan-' + i;
- pointCloudScanList.push(mesh);
+ pointCloudScanMap[i] = mesh;
if (i === labelTool.currentFileIndex) {
scene.add(mesh);
}
@@ -349,7 +350,7 @@ let labelTool = {
}
labelTool.pointCloudLoaded = true;
} else {
- scene.add(pointCloudScanList[labelTool.currentFileIndex]);
+ scene.add(pointCloudScanMap[labelTool.currentFileIndex]);
}
@@ -383,14 +384,6 @@ let labelTool = {
});
}
},
-
- setTrackIds: function () {
- for (let annotationObj in annotationObjects.contents[labelTool.currentFileIndex]) {
- let annotation = annotationObjects.contents[labelTool.currentFileIndex][annotationObj];
- let label = annotation["class"];
- classesBoundingBox[label].nextTrackId++;
- }
- },
loadAnnotationsNuscenes: function (annotations, fileIndex) {
// Add new bounding boxes.
for (let i in annotations) {
@@ -409,14 +402,12 @@ let labelTool = {
params.original.rotationPitch = parseFloat(annotation.rotationPitch);
params.original.rotationRoll = parseFloat(annotation.rotationRoll);
if (labelTool.showOriginalNuScenesLabels === true && labelTool.currentDataset === labelTool.datasets.NuScenes) {
- classesBoundingBox.addNuSceneLabel(annotation.class);
- classesBoundingBox.__target = Object.keys(classesBoundingBox.content)[0];
- params.trackId = classesBoundingBox.content[annotation.class].nextTrackId;
- classesBoundingBox.content[annotation.class].nextTrackId++;
+ classesBoundingBox.currentClass = labelTool.classes[0];
+ params.trackId = classesBoundingBox[annotation.class].nextTrackId;
} else {
params.trackId = annotation.trackId;
- classesBoundingBox[annotation.class].nextTrackId++;
}
+ classesBoundingBox[annotation.class].nextTrackId++;
// Nuscenes labels are stored in global frame in the database
// Nuscenes: labels (3d positions) are transformed from global frame to point cloud (global -> ego, ego -> point cloud) before exporting them
@@ -449,7 +440,7 @@ let labelTool = {
// add new entry to contents array
annotationObjects.set(annotationObjects.__insertIndex, params);
annotationObjects.__insertIndex++;
- classesBoundingBox.target().nextTrackId++;
+ classesBoundingBox.getCurrentAnnotationClassObject().nextTrackId++;
}
}
},
@@ -469,11 +460,9 @@ let labelTool = {
params.original.rotationPitch = parseFloat(annotation.box3d.orientation.rotationPitch);
params.rotationRoll = parseFloat(annotation.box3d.orientation.rotationRoll);
params.original.rotationRoll = parseFloat(annotation.box3d.orientation.rotationRoll);
- let classIdx;
params.trackId = annotation.id;
- classIdx = classesBoundingBox[annotation.category].index;
- if (params.trackId > labelTool.maxTrackIds[classIdx]) {
- labelTool.maxTrackIds[classIdx] = params.id;
+ if (params.trackId > classesBoundingBox[annotation.category].maxTrackId) {
+ classesBoundingBox[annotation.category].maxTrackId = params.id;
}
// Nuscenes labels are stored in global frame in the database
// Nuscenes: labels (3d positions) are transformed from global frame to point cloud (global -> ego, ego -> point cloud) before exporting them
@@ -504,37 +493,22 @@ let labelTool = {
// add new entry to contents array
annotationObjects.set(annotationObjects.__insertIndex, params);
annotationObjects.__insertIndex++;
- if (labelTool.showOriginalNuScenesLabels === true) {
- classesBoundingBox.content[classesBoundingBox.targetName()].nextTrackId++;
- } else {
- if (isNaN(classesBoundingBox.target().nextTrackId)) {
- classesBoundingBox.target().nextTrackId = 1;
- }
- classesBoundingBox.target().nextTrackId++;
+ if (isNaN(classesBoundingBox.getCurrentAnnotationClassObject().nextTrackId)) {
+ classesBoundingBox.getCurrentAnnotationClassObject().nextTrackId = 0;
}
-
-
+ classesBoundingBox[classesBoundingBox.getCurrentClass()].nextTrackId++;
}
}//end for loop frame annotations
// reset track ids for next frame if nuscenes dataset and showLabels=true
if (labelTool.showOriginalNuScenesLabels === true && labelTool.currentDataset === labelTool.datasets.NuScenes) {
- for (let i = 0; i < classesBoundingBox.classNameArray.length; i++) {
- classesBoundingBox.content[classesBoundingBox.classNameArray[i]].nextTrackId = 0;
+ for (let i = 0; i < labelTool.classes.length; i++) {
+ classesBoundingBox[labelTool.classes[i]].nextTrackId = 0;
}
}
// reset insert index
annotationObjects.__insertIndex = 0;
-
- if (labelTool.showOriginalNuScenesLabels === true) {
- let keys = Object.keys(classesBoundingBox.content);
- for (let i = 0; i < labelTool.maxTrackIds.length; i++) {
- classesBoundingBox.content[keys[i]].nextTrackId = labelTool.maxTrackIds[i] + 1;
- }
- } else {
- let keys = Object.keys(classesBoundingBox);
- for (let i = 0; i < labelTool.maxTrackIds.length; i++) {
- classesBoundingBox[keys[i]].nextTrackId = labelTool.maxTrackIds[i] + 1;
- }
+ for (let i = 0; i < labelTool.classes.length; i++) {
+ classesBoundingBox[labelTool.classes[i]].nextTrackId = classesBoundingBox[labelTool.classes[i]].maxTrackId + 1;
}
// project 3D positions of current frame into 2D camera images
if (labelTool.pointCloudOnlyAnnotation === false) {
@@ -561,11 +535,10 @@ let labelTool = {
params.original.rotationPitch = parseFloat(annotation.box3d.orientation.rotationYaw);
params.rotationRoll = parseFloat(annotation.box3d.orientation.rotationPitch);
params.original.rotationRoll = parseFloat(annotation.box3d.orientation.rotationPitch);
- let classIdx;
params.trackId = annotation.id;
- classIdx = classesBoundingBox[annotation.category].index;
- if (params.trackId > labelTool.maxTrackIds[classIdx]) {
- labelTool.maxTrackIds[classIdx] = params.trackId;
+ // }
+ if (params.trackId > classesBoundingBox[annotation.category].maxTrackId) {
+ classesBoundingBox[annotation.category].maxTrackId = params.id;
}
params.x = parseFloat(annotation.box3d.location.x);
params.y = parseFloat(annotation.box3d.location.y);
@@ -595,17 +568,15 @@ let labelTool = {
annotationObjects.set(annotationObjects.__insertIndex, params);
annotationObjects.__insertIndex++;
if (isNaN(classesBoundingBox[params.class].nextTrackId)) {
- classesBoundingBox[params.class].nextTrackId = 1;
+ classesBoundingBox[params.class].nextTrackId = 0;
}
classesBoundingBox[params.class].nextTrackId++;
}
}
// reset insert index
annotationObjects.__insertIndex = 0;
-
- let keys = Object.keys(classesBoundingBox);
- for (let i = 0; i < labelTool.maxTrackIds.length; i++) {
- classesBoundingBox[keys[i]].nextTrackId = labelTool.maxTrackIds[i] + 1;
+ for (let i = 0; i < labelTool.classes.length; i++) {
+ classesBoundingBox[labelTool.classes[i]].nextTrackId = classesBoundingBox[labelTool.classes[i]].maxTrackId + 1;
}
},
@@ -655,7 +626,7 @@ let labelTool = {
return annotationFiles;
},
- initializePointCloudWindow: function () {
+ initPointCloudWindow: function () {
let pointCloudContainer;
if (labelTool.pointCloudOnlyAnnotation === true) {
pointCloudContainer = $("#label-tool-wrapper");
@@ -664,7 +635,18 @@ let labelTool = {
}
pointCloudContainer.append('
');
this.localOnInitialize["PCD"]();
- }, initializeClassPicker: function () {
+ }, initClasses: function () {
+ for (let i = 0; i < labelTool.classes.length; i++) {
+ classesBoundingBox[labelTool.classes[i]] = {
+ color: labelTool.classColors[i],
+ index: i,
+ nextTrackId: 0,
+ maxTrackId: -1
+ };
+ }
+
+ }, initClassPicker: function () {
+ classesBoundingBox.currentClass = labelTool.classes[0];
$(function () {
$('#class-picker>ul>li').hover(function () {
$(this).css('background-color', "#535353");
@@ -678,7 +660,6 @@ let labelTool = {
}
});
});
-
let toasts = $(".toasts")[0];
this.logger = new Toast(toasts);
}, setPanelSize: function (newFileIndex) {
@@ -734,7 +715,6 @@ let labelTool = {
let topElem = $("#layout_layout_panel_top")[0];
let newImagePanelHeight = topElem.offsetHeight;
let newWidth;
- let newWidthBackFront;
if (labelTool.currentDataset === labelTool.datasets.NuScenes) {
newWidth = newImagePanelHeight * labelTool.imageAspectRatioNuScenes;
}
@@ -809,7 +789,7 @@ let labelTool = {
w2ui['layout'].resizer = 10;
w2ui['layout'].resize();
w2ui['layout'].refresh();
- }, initializeCameraWindows: function () {
+ }, initCameraWindows: function () {
this.setImageSize();
this.initPanes();
let imageContainer = $("#layout_layout_panel_top .w2ui-panel-content");
@@ -935,7 +915,7 @@ let labelTool = {
this.currentFileIndex = 0;
this.fileNames = [];
this.originalAnnotations = [];
- this.targetClass = "vehicle";
+ this.targetClass = this.classes[0];
this.savedFrames = [];
this.cubeArray = [];
this.currentCameraChannelIndex = 0;
@@ -949,29 +929,32 @@ let labelTool = {
this.selectedMesh = undefined;
this.pointCloudLoaded = false;
- // classesBoundingBox
- classesBoundingBox.colorIdx = 0;
- classesBoundingBox.__target = Object.keys(classesBoundingBox)[0];
-
// pcd label tool
folderBoundingBox3DArray = [];
folderPositionArray = [];
folderRotationArray = [];
folderSizeArray = [];
- pointCloudScanList = [];
+ pointCloudScanMap = [];
let classPickerElem = $('#class-picker ul li');
classPickerElem.css('background-color', '#353535');
$(classPickerElem[0]).css('background-color', '#525252');
classPickerElem.css('border-bottom', '0px');
+ // classesBoundingBox
+ classesBoundingBox.colorIdx = 0;
+ classesBoundingBox.currentClass = labelTool.classes[0];
classPickerElem.each(function (i, item) {
- let propNamesArray = Object.getOwnPropertyNames(classesBoundingBox);
- let color = classesBoundingBox[propNamesArray[i]].color;
+ let color = labelTool.classColors[i];
let attribute = "20px solid" + ' ' + color;
$(item).css("border-left", attribute);
$(item).css('border-bottom', '0px');
});
+ for (let i = 0; i < labelTool.classes.length; i++) {
+ delete classesBoundingBox[labelTool.classes[i]];
+ }
+ // remove guiClassesBoundingBox
+ $("#class-picker").remove();
if (labelTool.pointCloudOnlyAnnotation === false) {
// image label tool
@@ -994,7 +977,6 @@ let labelTool = {
w2ui['layout'].resize();
}
- classesBoundingBox.content = [];
$(".frame-selector__frames").empty();
},
@@ -1038,14 +1020,14 @@ let labelTool = {
}, start() {
this.initTimer();
this.setFileNames();
- this.initTrackIDs();
- this.initializeClassPicker();
+ this.initClasses();
+ this.initClassPicker();
this.initFrameSelector();
if (labelTool.pointCloudOnlyAnnotation === false) {
- this.initializeCameraWindows();
+ this.initCameraWindows();
this.loadImageData();
}
- this.initializePointCloudWindow();
+ this.initPointCloudWindow();
this.loadPointCloudData();
this.loadAnnotations();
},
@@ -1060,13 +1042,10 @@ let labelTool = {
parameters.currentDataset = labelTool.datasetArray[0];
labelTool.currentDatasetIdx = 0;
labelTool.sequence = labelTool.dataStructure.datasets[0].sequences[0];
+ labelTool.classes = labelTool.dataStructure.datasets[0].classes;
+ labelTool.classColors = labelTool.dataStructure.datasets[0].class_colors;
+ labelTool.targetClass = labelTool.classes[0];
},
- initTrackIDs() {
- for (let i = 0; i < labelTool.maxTrackIds.length; i++) {
- labelTool.maxTrackIds[i] = 0;
- }
- },
-
setFileNames() {
let fileNameArray = [];
if (labelTool.currentDataset === labelTool.datasets.NuScenes) {
@@ -1284,8 +1263,6 @@ let labelTool = {
// if (objectIndexByTrackIdAndClass !== -1) {
// next frame contains a new object -> add tooltip for new object
let classTooltipElement = $("" + trackId + "
");
- // set background color
- let color = classesBoundingBox[className].color;
let imagePaneHeight = parseInt($("#layout_layout_resizer_top").css("top"), 10);
const vector = new THREE.Vector3(mesh.position.x, mesh.position.y, mesh.position.z + mesh.scale.z / 2);
const canvas = renderer.domElement;
@@ -1775,27 +1752,12 @@ function calculateAndDrawLineSegments(channelObj, className, horizontal, selecte
let lineArray = [];
let channelIdx = getChannelIndexByName(channel);
// temporary color bottom 4 lines in yellow to check if projection matrix is correct
- // let color = '#ffff00';
// uncomment line to use yellow to color bottom 4 lines
let color;
if (selected === true) {
color = "#ff0000";
} else {
- if (labelTool.showOriginalNuScenesLabels === true && labelTool.currentDataset === labelTool.datasets.NuScenes) {
- let classIdx = classesBoundingBox.classNameArray.indexOf(className);
- color = classesBoundingBox.colorArray[classIdx];
- } else {
- color = classesBoundingBox[className].color;
- }
- }
-
- // color objects that are selected in red
-
-
- let imageHeight = parseInt($("#layout_layout_resizer_top").css("top"), 10);
- let imageWidth;
- if (labelTool.currentDataset === labelTool.datasets.NuScenes) {
- imageWidth = imageHeight * labelTool.imageAspectRatioNuScenes;
+ color = classesBoundingBox[className].color;
}
// bottom four lines
@@ -1804,9 +1766,7 @@ function calculateAndDrawLineSegments(channelObj, className, horizontal, selecte
lineArray.push(drawLine(channelIdx, channelObj.projectedPoints[2], channelObj.projectedPoints[3], color));
lineArray.push(drawLine(channelIdx, channelObj.projectedPoints[3], channelObj.projectedPoints[0], color));
-
// draw line for orientation
-
let pointZero;
let pointOne;
let pointTwo;
diff --git a/js/pcd_label_tool.js b/js/pcd_label_tool.js
index 222ab85..bb9a6a6 100755
--- a/js/pcd_label_tool.js
+++ b/js/pcd_label_tool.js
@@ -52,8 +52,9 @@ let interpolationObjIndexNextFile = -1;
let interpolateBtn;
let pointSizeSlider;
-let guiAnnotationClasses = new dat.GUI({autoPlace: true, width: 90, resizable: false});
-let guiBoundingBoxAnnotationMap;
+let guiAnnotationClasses;
+let guiBoundingBoxAnnotationsInitialized = false;
+let guiBoundingBoxMenuInitialized = false;
let guiOptions = new dat.GUI({autoPlace: true, width: 350, resizable: false});
let guiOptionsOpened = true;
let numGUIOptions = 17;
@@ -87,7 +88,7 @@ let activeColorMap = 'colorMapJet.js';
let currentPoints3D = [];
let currentDistances = [];
let spriteBehindObject;
-let pointCloudScanList = [];
+let pointCloudScanMap = [];
let pointCloudScanNoGroundList = [];
let useTransformControls;
let dragControls = false;
@@ -97,34 +98,6 @@ let pointSizeMax = 1;
let defaultBoxHeight = 1.468628;
let gridSize = 200;
-let parametersBoundingBox = {
- "Vehicle": function () {
- classesBoundingBox.select("vehicle");
- $('#class-picker ul li').css('background-color', '#323232');
- $($('#class-picker ul li')[0]).css('background-color', '#525252');
- },
- "Truck": function () {
- classesBoundingBox.select("truck");
- $('#class-picker ul li').css('background-color', '#323232');
- $($('#class-picker ul li')[1]).css('background-color', '#525252');
- },
- "Motorcycle": function () {
- classesBoundingBox.select("motorcycle");
- $('#class-picker ul li').css('background-color', '#323232');
- $($('#class-picker ul li')[2]).css('background-color', '#525252');
- },
- "Bicycle": function () {
- classesBoundingBox.select("bicycle");
- $('#class-picker ul li').css('background-color', '#323232');
- $($('#class-picker ul li')[3]).css('background-color', '#525252');
- },
- "Pedestrian": function () {
- classesBoundingBox.select("pedestrian");
- $('#class-picker ul li').css('background-color', '#323232');
- $($('#class-picker ul li')[4]).css('background-color', '#525252');
- },
-};
-
let parameters = {
point_size: 0.05,
download_video: function () {
@@ -679,13 +652,9 @@ function get3DLabel(parameters) {
let cubeGeometry = new THREE.BoxBufferGeometry(1.0, 1.0, 1.0);//width, length, height
let color;
if (parameters.fromFile === true) {
- if (labelTool.showOriginalNuScenesLabels === true && labelTool.currentDataset === labelTool.datasets.NuScenes) {
- color = classesBoundingBox.content[parameters.class].color;
- } else {
- color = classesBoundingBox[parameters.class].color;
- }
+ color = classesBoundingBox[parameters.class].color;
} else {
- color = classesBoundingBox.target().color;
+ color = classesBoundingBox.getCurrentAnnotationClassObject().color;
}
let cubeMaterial = new THREE.MeshBasicMaterial({
@@ -771,7 +740,7 @@ function updateXPos(newFileIndex, value) {
* @param label
*/
function setHighestAvailableTrackId(label) {
- for (let newTrackId = 1; newTrackId <= annotationObjects.contents[labelTool.currentFileIndex].length; newTrackId++) {
+ for (let newTrackId = 0; newTrackId <= annotationObjects.contents[labelTool.currentFileIndex].length; newTrackId++) {
let exist = false;
for (let i = 0; i < annotationObjects.contents[labelTool.currentFileIndex].length; i++) {
if (label === annotationObjects.contents[labelTool.currentFileIndex][i]["class"] && newTrackId === annotationObjects.contents[labelTool.currentFileIndex][i]["trackId"]) {
@@ -781,18 +750,10 @@ function setHighestAvailableTrackId(label) {
}
if (exist === false) {
// track id was not used yet
- if (labelTool.showOriginalNuScenesLabels === true) {
- classesBoundingBox.content[label].nextTrackId = newTrackId;
- } else {
- classesBoundingBox[label].nextTrackId = newTrackId;
- }
+ classesBoundingBox[label].nextTrackId = newTrackId;
break;
}
- if (labelTool.showOriginalNuScenesLabels === true) {
- classesBoundingBox.content[label].nextTrackId = annotationObjects.contents[labelTool.currentFileIndex].length + 1;
- } else {
- classesBoundingBox[label].nextTrackId = annotationObjects.contents[labelTool.currentFileIndex].length + 1;
- }
+ classesBoundingBox[label].nextTrackId = annotationObjects.contents[labelTool.currentFileIndex].length + 1;
}
}
@@ -864,18 +825,8 @@ function deleteObject(bboxClass, trackId, labelIndex) {
// remove sprite from DOM tree
$("#tooltip-" + bboxClass.charAt(0) + trackId).remove();
labelTool.selectedMesh = undefined;
- // reduce track id by 1 for this class
- if (labelTool.showOriginalNuScenesLabels) {
- classesBoundingBox.content[bboxClass].nextTrackId--;
- } else {
- if (labelIndex === annotationObjects.contents[labelTool.currentFileIndex].length) {
- // decrement track id if the last object in the list was deleted
- classesBoundingBox[bboxClass].nextTrackId--;
- } else {
- // otherwise not last object was deleted -> find out the highest possible track id
- setHighestAvailableTrackId(bboxClass);
- }
- }
+
+ setHighestAvailableTrackId(bboxClass);
// if last object in current frame was deleted than disable interpolation mode
if (annotationObjects.contents[labelTool.currentFileIndex].length === 0) {
interpolationMode = false;
@@ -903,9 +854,9 @@ function deleteObject(bboxClass, trackId, labelIndex) {
function addBoundingBoxGui(bbox, bboxEndParams) {
let insertIndex = folderBoundingBox3DArray.length;
let bb;
- if (guiOptions.__folders[bbox.class + ' ' + bbox.trackId] === undefined){
+ if (guiOptions.__folders[bbox.class + ' ' + bbox.trackId] === undefined) {
bb = guiOptions.addFolder(bbox.class + ' ' + bbox.trackId);
- }else{
+ } else {
bb = guiOptions.__folders[bbox.class + ' ' + bbox.trackId];
}
@@ -2017,6 +1968,14 @@ function changeDataset(datasetName) {
labelTool.currentDataset = datasetName;
labelTool.currentDatasetIdx = labelTool.datasetArray.indexOf(datasetName);
labelTool.sequence = labelTool.dataStructure.datasets[labelTool.datasetArray.indexOf(datasetName)].sequences[0];
+ labelTool.classes = labelTool.dataStructure.datasets[labelTool.datasetArray.indexOf(datasetName)].classes;
+ labelTool.classColors = labelTool.dataStructure.datasets[labelTool.datasetArray.indexOf(datasetName)].class_colors;
+ labelTool.initClasses();
+ initGuiBoundingBoxAnnotations();
+ // move button to left
+ $("#left-btn").css("left", 0);
+ // move class picker to left
+ $("#class-picker").css("left", 10);
labelTool.start();
}
@@ -2184,33 +2143,6 @@ function onDocumentMouseMove(event) {
mousePos.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
-function increaseTrackId(label, dataset) {
- let classesBB;
- if (dataset === labelTool.datasets.NuScenes) {
- classesBB = classesBoundingBox.content;
- }
-
- // find out the lowest possible track id for a specific class
-
- for (let newTrackId = 1; newTrackId <= annotationObjects.contents[labelTool.currentFileIndex].length; newTrackId++) {
- let exist = false;
- for (let i = 0; i < annotationObjects.contents[labelTool.currentFileIndex].length; i++) {
- if (label !== annotationObjects.contents[labelTool.currentFileIndex]["class"]) {
- continue;
- }
- if (newTrackId === annotationObjects.contents[labelTool.currentFileIndex][i]["trackId"]) {
- exist = true;
- break;
- }
- }
- if (exist === false) {
- // track id was not used yet
- return newTrackId;
- }
- }
- return -1;
-}
-
function disableStartPose() {
// disable slider
folderPositionArray[interpolationObjIndexNextFile].domElement.style.opacity = 0.5;
@@ -2525,6 +2457,7 @@ function mouseUpLogic(ev) {
let classPickerElem = $('#class-picker ul li');
classPickerElem.css('background-color', '#353535');
$(classPickerElem[classesBoundingBox[obj["class"]].index]).css('background-color', '#525252');
+ classesBoundingBox.currentClass = obj["class"];
} else {
@@ -2588,11 +2521,11 @@ function mouseUpLogic(ev) {
let trackId = -1;
let insertIndex;
- setHighestAvailableTrackId(classesBoundingBox.targetName());
+ setHighestAvailableTrackId(classesBoundingBox.getCurrentClass());
if (labelTool.showOriginalNuScenesLabels === true && labelTool.currentDataset === labelTool.datasets.NuScenes) {
if (annotationObjects.__selectionIndexCurrentFrame === -1) {
// no object selected in 3d scene (new object was created)-> use selected class from class menu
- trackId = classesBoundingBox.content[classesBoundingBox.targetName()].nextTrackId;
+ trackId = classesBoundingBox.content[classesBoundingBox.getCurrentClass()].nextTrackId;
insertIndex = annotationObjects.contents[labelTool.currentFileIndex].length;
} else {
// object was selected in 3d scene
@@ -2602,7 +2535,7 @@ function mouseUpLogic(ev) {
}
} else {
if (annotationObjects.__selectionIndexCurrentFrame === -1) {
- trackId = classesBoundingBox[classesBoundingBox.targetName()].nextTrackId;
+ trackId = classesBoundingBox[classesBoundingBox.getCurrentClass()].nextTrackId;
insertIndex = annotationObjects.contents[labelTool.currentFileIndex].length;
clickedObjectIndexPrevious = annotationObjects.__selectionIndexCurrentFrame;
} else {
@@ -2620,7 +2553,7 @@ function mouseUpLogic(ev) {
// average car height in meters (ref: https://www.carfinderservice.com/car-advice/a-careful-look-at-different-sedan-dimensions)
let addBboxParameters = getDefaultObject();
- addBboxParameters.class = classesBoundingBox.targetName();
+ addBboxParameters.class = classesBoundingBox.getCurrentClass();
addBboxParameters.x = xPos;
addBboxParameters.y = yPos;
if (labelTool.currentDataset === labelTool.datasets.providentia) {
@@ -2635,7 +2568,7 @@ function mouseUpLogic(ev) {
addBboxParameters.rotationPitch = 0;
addBboxParameters.rotationRoll = 0;
addBboxParameters.original = {
- class: classesBoundingBox.targetName(),
+ class: classesBoundingBox.getCurrentClass(),
x: (groundPointMouseUp.x + groundPointMouseDown.x) / 2,
y: (groundPointMouseUp.y + groundPointMouseDown.y) / 2,
z: zPos + defaultBoxHeight / 2 - labelTool.positionLidarNuscenes[2],
@@ -2678,7 +2611,7 @@ function mouseUpLogic(ev) {
if (channelObj.channel !== undefined && channelObj.channel !== '') {
if (addBboxParameters.channels[i].projectedPoints !== undefined && addBboxParameters.channels[i].projectedPoints.length === 8) {
let horizontal = addBboxParameters.width > addBboxParameters.length;
- addBboxParameters.channels[i]["lines"] = calculateAndDrawLineSegments(channelObj, classesBoundingBox.targetName(), horizontal, true);
+ addBboxParameters.channels[i]["lines"] = calculateAndDrawLineSegments(channelObj, classesBoundingBox.getCurrentClass(), horizontal, true);
}
}
}
@@ -2693,12 +2626,12 @@ function mouseUpLogic(ev) {
}
$("#tooltip-" + annotationObjects.contents[labelTool.currentFileIndex][insertIndex]["class"].charAt(0) + annotationObjects.contents[labelTool.currentFileIndex][insertIndex]["trackId"]).hide();
// move left button to right
- $("#left-btn").css("left", window.innerWidth / 3 - 70);
+ $("#left-btn").css("left", window.innerWidth / 3);
showHelperViews(xPos, yPos, zPos);
annotationObjects.__insertIndex++;
- classesBoundingBox.target().nextTrackId++;
+ classesBoundingBox.getCurrentAnnotationClassObject().nextTrackId++;
for (let channelIdx in labelTool.camChannels) {
if (labelTool.camChannels.hasOwnProperty(channelIdx)) {
let camChannel = labelTool.camChannels[channelIdx].channel;
@@ -2767,7 +2700,7 @@ function mouseDownLogic(ev) {
if (birdsEyeViewFlag === true) {
groundPlane.position.x = clickedPoint.x;
groundPlane.position.y = clickedPoint.y;
- groundPlane.position.z = clickedPoint.z;
+ groundPlane.position.z = -10;//clickedPoint.z;
let normal = clickedObjects[0].face;
if ([normal.a, normal.b, normal.c].toString() == [6, 3, 2].toString() || [normal.a, normal.b, normal.c].toString() == [7, 6, 2].toString()) {
groundPlane.rotation.x = Math.PI / 2;
@@ -2796,19 +2729,18 @@ function mouseDownLogic(ev) {
let trackId = annotationObjects.contents[labelTool.currentFileIndex][clickedObjectIndex]["trackId"];
deleteObject(bboxClass, trackId, clickedObjectIndex);
// move button to left
- $("#left-btn").css("left", -70);
+ $("#left-btn").css("left", 0);
}//end right click
} else {
for (let i = 0; i < annotationObjects.contents[labelTool.currentFileIndex].length; i++) {
$("#tooltip-" + annotationObjects.contents[labelTool.currentFileIndex][i]["class"].charAt(0) + annotationObjects.contents[labelTool.currentFileIndex][i]["trackId"]).show();
}
if (birdsEyeViewFlag === true) {
- console.log("unselected");
clickedObjectIndex = -1;
groundPlaneArray = [];
groundPlane.position.x = 0;
groundPlane.position.y = 0;
- groundPlane.position.z = 0;
+ groundPlane.position.z = -10;
groundPlaneArray.push(groundPlane);
let groundObject = ray.intersectObjects(groundPlaneArray);
if (groundObject !== undefined && groundObject[0] !== undefined) {
@@ -2996,7 +2928,7 @@ function createGrid() {
translationX = 0;
} else {
posZLidar = labelTool.positionLidar[2];
- translationX = gridSize/2;
+ translationX = gridSize / 2;
}
grid.translateZ(-posZLidar);
grid.translateX(translationX);
@@ -3089,7 +3021,7 @@ function loadDetectedBoxes() {
}
params.fileIndex = frameNumber - 1;
annotationObjects.set(objectIndexWithinFrame, params);
- classesBoundingBox.target().nextTrackId++;
+ classesBoundingBox.getCurrentAnnotationClassObject().nextTrackId++;
}
}
}
@@ -3097,6 +3029,31 @@ function loadDetectedBoxes() {
rawFile.send(null);
}
+function initGuiBoundingBoxAnnotations() {
+ let parametersBoundingBox = {};
+ for (let i = 0; i < labelTool.classes.length; i++) {
+ parametersBoundingBox[labelTool.classes[i]] =
+ function () {
+ classesBoundingBox.select(labelTool.classes[i]);
+ $('#class-picker ul li').css('background-color', '#323232');
+ $($('#class-picker ul li')[i]).css('background-color', '#525252');
+ }
+ }
+ let guiAnnotationClassesWidth;
+ if (labelTool.currentDataset === labelTool.datasets.NuScenes) {
+ guiAnnotationClassesWidth = 220;
+ } else {
+ guiAnnotationClassesWidth = 90;
+ }
+ guiAnnotationClasses = new dat.GUI({autoPlace: true, width: guiAnnotationClassesWidth, resizable: false});
+
+ let guiBoundingBoxAnnotationMap = {};
+ for (let i = 0; i < labelTool.classes.length; i++) {
+ guiBoundingBoxAnnotationMap[labelTool.classes[i]] = guiAnnotationClasses.add(parametersBoundingBox, labelTool.classes[i]).name(labelTool.classes[i]);
+ }
+ guiAnnotationClasses.domElement.id = 'class-picker';
+}
+
function init() {
if (WEBGL.isWebGLAvailable() === false) {
document.body.appendChild(WEBGL.getWebGLErrorMessage());
@@ -3174,15 +3131,13 @@ function init() {
annotationObjects.contents.push([]);
}
- if (guiBoundingBoxAnnotationMap === undefined) {
- guiBoundingBoxAnnotationMap = {
- "Vehicle": guiAnnotationClasses.add(parametersBoundingBox, "Vehicle").name("Vehicle"),
- "Truck": guiAnnotationClasses.add(parametersBoundingBox, "Truck").name("Truck"),
- "Motorcycle": guiAnnotationClasses.add(parametersBoundingBox, "Motorcycle").name("Motorcycle"),
- "Bicycle": guiAnnotationClasses.add(parametersBoundingBox, "Bicycle").name("Bicycle"),
- "Pedestrian": guiAnnotationClasses.add(parametersBoundingBox, "Pedestrian").name("Pedestrian"),
- };
- guiAnnotationClasses.domElement.id = 'class-picker';
+ if (guiBoundingBoxAnnotationsInitialized === false) {
+ guiBoundingBoxAnnotationsInitialized = true;
+ initGuiBoundingBoxAnnotations();
+ }
+
+ if (guiBoundingBoxMenuInitialized === false) {
+ guiBoundingBoxMenuInitialized = true;
// 3D BB controls
guiOptions.add(parameters, 'download').name("Download Annotations");
guiOptions.add(parameters, 'download_video').name("Create and Download Video");
@@ -3209,7 +3164,7 @@ function init() {
labelTool.removeObject("planeObject");
});
pointSizeSlider = guiOptions.add(parameters, 'point_size').name("Point Size").min(0.001).max(pointSizeMax).step(0.001).onChange(function (value) {
- pointCloudScanList[labelTool.currentFileIndex].material.size = value;
+ pointCloudScanMap[labelTool.currentFileIndex].material.size = value;
});
disablePointSizeSlider();
let showOriginalNuScenesLabelsCheckbox = guiOptions.add(parameters, 'show_nuscenes_labels').name('NuScenes Labels').listen();
@@ -3300,7 +3255,7 @@ function init() {
addObject(pointCloudScanNoGroundList[labelTool.currentFileIndex], "pointcloud-scan-no-ground-" + labelTool.currentFileIndex);
} else {
labelTool.removeObject("pointcloud-scan-no-ground-" + labelTool.currentFileIndex);
- addObject(pointCloudScanList[labelTool.currentFileIndex], "pointcloud-scan-" + labelTool.currentFileIndex);
+ addObject(pointCloudScanMap[labelTool.currentFileIndex], "pointcloud-scan-" + labelTool.currentFileIndex);
}
});
@@ -3451,13 +3406,15 @@ function init() {
hideProjectedPoints();
}
}
- }
+ }// end if guiBoundingBoxMenuInitialized
+
let classPickerElem = $('#class-picker ul li');
classPickerElem.css('background-color', '#353535');
$(classPickerElem[0]).css('background-color', '#525252');
classPickerElem.css('border-bottom', '0px');
-
-
+ if (labelTool.currentDataset === labelTool.datasets.NuScenes) {
+ $("#class-picker").css("width", '220px');
+ }
$('#bounding-box-3d-menu').css('width', '480px');
$('#bounding-box-3d-menu ul li').css('background-color', '#353535');
$("#bounding-box-3d-menu .close-button").click(function () {
@@ -3468,16 +3425,12 @@ function init() {
$("#right-btn").css("right", 0);
}
});
-
guiOptions.open();
classPickerElem.each(function (i, item) {
- let propNamesArray = Object.getOwnPropertyNames(classesBoundingBox);
- let color = classesBoundingBox[propNamesArray[i]].color;
+ let color = labelTool.classColors[i];
let attribute = "20px solid" + ' ' + color;
$(item).css("border-left", attribute);
$(item).css('border-bottom', '0px');
});
-
initViews();
-
}
\ No newline at end of file
diff --git a/js/util/boundingbox.js b/js/util/boundingbox.js
index be8b1ba..c1e5db2 100644
--- a/js/util/boundingbox.js
+++ b/js/util/boundingbox.js
@@ -64,7 +64,7 @@ let annotationObjects = {
this.contents[params.fileIndex].insertIndex = insertIndex;
if (params.fromFile === false && this.__selectionIndexCurrentFrame === -1) {
if (labelTool.showOriginalNuScenesLabels === true && labelTool.currentDataset === labelTool.datasets.NuScenes) {
- this.contents[params.fileIndex][insertIndex]["trackId"] = classesBoundingBox.content[params.class].nextTrackId;
+ this.contents[params.fileIndex][insertIndex]["trackId"] = classesBoundingBox[params.class].nextTrackId;
} else {
this.contents[params.fileIndex][insertIndex]["trackId"] = classesBoundingBox[params.class].nextTrackId;
}
@@ -81,7 +81,7 @@ let annotationObjects = {
}
// return if same class was chosen again
- let currentClassLabel = classesBoundingBox.getCurrentClass();
+ let currentClassLabel = this.contents[labelTool.currentFileIndex][selectedObjectIndex]["class"];
if (currentClassLabel === newClassLabel) {
return false;
}
@@ -89,7 +89,7 @@ let annotationObjects = {
// update id of sprite
let currentTrackId = this.contents[labelTool.currentFileIndex][selectedObjectIndex]["trackId"];
- let spriteElem = $("#class-" + this.contents[labelTool.currentFileIndex][selectedObjectIndex]["class"].charAt(0) + currentTrackId);
+ let spriteElem = $("#class-" + currentClassLabel.charAt(0) + currentTrackId);
// use original track id if original class selected
let nextTrackIdNewClass;
if (newClassLabel === this.contents[labelTool.currentFileIndex][selectedObjectIndex]["original"]["class"]) {
@@ -108,8 +108,9 @@ let annotationObjects = {
// update track id
this.contents[labelTool.currentFileIndex][selectedObjectIndex]["trackId"] = nextTrackIdNewClass;
- // decrease track id of current (previous) class
- classesBoundingBox[currentClassLabel]["nextTrackId"] = classesBoundingBox[currentClassLabel]["nextTrackId"] - 1;
+ // set next highest track ID of current class
+
+ setHighestAvailableTrackId(currentClassLabel);
// increase track id of new class
classesBoundingBox[newClassLabel]["nextTrackId"] = classesBoundingBox[newClassLabel]["nextTrackId"] + 1;
@@ -123,6 +124,9 @@ let annotationObjects = {
// ul number div div[class c] input
folderBoundingBox3DArray[selectedObjectIndex].domElement.children[0].children[4].children[0].children[1].children[0].value = nextTrackIdNewClass;
+ guiOptions.__folders[newClassLabel + ' ' + nextTrackIdNewClass] = guiOptions.__folders[currentClassLabel + ' ' + currentTrackId];
+ delete guiOptions.__folders[currentClassLabel + ' ' + currentTrackId];
+
// open current folder
folderBoundingBox3DArray[selectedObjectIndex].open();
folderPositionArray[selectedObjectIndex].open();
diff --git a/js/util/classesBoundingBox.js b/js/util/classesBoundingBox.js
index d2381a7..1e81e19 100644
--- a/js/util/classesBoundingBox.js
+++ b/js/util/classesBoundingBox.js
@@ -1,76 +1,10 @@
let classesBoundingBox = {
- "vehicle": {
- color: '#51C38C',
- index: 0,
- nextTrackId: 1
- },
- "truck": {
- color: '#EBCF36',
- index: 1,
- nextTrackId: 1
- },
- "motorcycle": {
- color: '#FF604B',
- index: 2,
- nextTrackId: 1
- },
- "bicycle": {
- color: '#F37CB2',
- index: 3,
- nextTrackId: 1
-
- },
- "pedestrian": {
- color: '#74BAF5',
- index: 4,
- nextTrackId: 1
- },
- // nuscenes
- classNameArray: ["human.pedestrian.adult",
- "human.pedestrian.child",
- "human.pedestrian.wheelchair",
- "human.pedestrian.stroller",
- "human.pedestrian.personal_mobility",
- "human.pedestrian.police_officer",
- "human.pedestrian.construction_worker",
- "animal",
- "vehicle.car",
- "vehicle.motorcycle",
- "vehicle.bicycle",
- "vehicle.bus.bendy",
- "vehicle.bus.rigid",
- "vehicle.truck",
- "vehicle.construction",
- "vehicle.emergency.ambulance",
- "vehicle.emergency.police",
- "vehicle.trailer",
- "movable_object.barrier",
- "movable_object.trafficcone",
- "movable_object.pushable_pullable",
- "movable_object.debris",
- "static_object.bicycle_rack"],
- // nuscenes
- colorArray: ['#3ABB9D', '#4DA664', '#2F6CAD', '#4590B6', '#5CADCF', '#3585C5', '#2CA786', '#6ABB72', '#E66B5B', '#A28F85',
- '#F79E3D', '#75706B', '#EE7841', '#D1D5D8', '#CC4846', '#DC5047', '#28324E', '#EFEFEF', '#485675', '#F2D46F', '#533D7F',
- '#9069B5', '#F7C23E'],
colorIdx: 0,
- content: [],
- addNuSceneLabel: function (label) {
- if (this.content[label] === undefined) {
- this.content[label] = {color: this.colorArray[this.colorIdx], index: this.colorIdx, nextTrackId: 1};
- this.colorIdx++;
- }
- },
- target: function () {
- if (labelTool.showOriginalNuScenesLabels === true && labelTool.currentDataset === labelTool.datasets.NuScenes) {
- return this.content[this.__target];
- } else {
- return this[this.__target];
- }
-
+ getCurrentAnnotationClassObject: function () {
+ return this[this.currentClass];
},
select: function (label) {
- this.onChange(label);
+ this.onChangeAnnotationClass(label);
if (annotationObjects.getSelectedBoundingBox() !== undefined) {
annotationObjects.changeClass(annotationObjects.__selectionIndexCurrentFrame, label);
@@ -85,22 +19,16 @@ let classesBoundingBox = {
};
operationStack.push(changeClassOperation);
}
-
- this.__target = label;
this.currentClass = label;
},
- onChange: function (label) {
- this.__target = label;
+ onChangeAnnotationClass: function (currentClass) {
+ this.currentClass = currentClass;
},
- color: function (label) {
+ getColorByClass: function (label) {
return this[label].color;
},
- targetName: function () {
- return this.__target;
- },
getCurrentClass: function () {
return this.currentClass;
},
- __target: "vehicle",
- currentClass: "vehicle"
+ currentClass: ""
};
\ No newline at end of file