def test_element_data_nested_same_name(self): vcd = core.VCD() uid1 = vcd.add_object('mike', '#Pedestrian') body = types.bbox('body', (0, 0, 100, 150)) body.add_attribute(types.boolean('visible', True)) body.add_attribute(types.boolean('occluded', False)) body.add_attribute(types.boolean('visible', False)) # this is repeated, so it is substituted vcd.add_object_data(uid1, body, (0, 5)) #self.assertEqual(vcd.stringify(False), '{"vcd":{"frames":{"0":{"objects":{"0":{"object_data":{"bbox":[{"name":"body","val":[0,0,100,150],"attributes":{"boolean":[{"name":"visible","val":false},{"name":"occluded","val":false}]}}]}}}},"1":{"objects":{"0":{"object_data":{"bbox":[{"name":"body","val":[0,0,100,150],"attributes":{"boolean":[{"name":"visible","val":false},{"name":"occluded","val":false}]}}]}}}},"2":{"objects":{"0":{"object_data":{"bbox":[{"name":"body","val":[0,0,100,150],"attributes":{"boolean":[{"name":"visible","val":false},{"name":"occluded","val":false}]}}]}}}},"3":{"objects":{"0":{"object_data":{"bbox":[{"name":"body","val":[0,0,100,150],"attributes":{"boolean":[{"name":"visible","val":false},{"name":"occluded","val":false}]}}]}}}},"4":{"objects":{"0":{"object_data":{"bbox":[{"name":"body","val":[0,0,100,150],"attributes":{"boolean":[{"name":"visible","val":false},{"name":"occluded","val":false}]}}]}}}},"5":{"objects":{"0":{"object_data":{"bbox":[{"name":"body","val":[0,0,100,150],"attributes":{"boolean":[{"name":"visible","val":false},{"name":"occluded","val":false}]}}]}}}}},"schema_version":"4.3.0","frame_intervals":[{"frame_start":0,"frame_end":5}],"objects":{"0":{"name":"mike","type":"#Pedestrian","frame_intervals":[{"frame_start":0,"frame_end":5}],"object_data_pointers":{"body":{"type":"bbox","frame_intervals":[{"frame_start":0,"frame_end":5}],"attributes":{"visible":"boolean","occluded":"boolean"}}}}}}}') if not os.path.isfile('./etc/' + vcd_version_name + '_test_element_data_nested_same_name.json'): vcd.save('./etc/' + vcd_version_name + '_test_element_data_nested_same_name.json')
def test_element_data_same_name(self): vcd = core.VCD() uid1 = vcd.add_action('', '#Walking') vcd.add_action_data(uid1, types.boolean('validated', True), (0, 5)) vcd.add_action_data(uid1, types.boolean('occluded', False), (0, 5)) vcd.add_action_data(uid1, types.text('label', 'manual'), (0, 5)) # Now try to add an Action Data with the same name vcd.add_action_data(uid1, types.boolean('validated', False), (0, 5)) # The initial 'validated' Boolean, with value true is substituted by false, instead of added #self.assertEqual(vcd.stringify(False), '{"vcd":{"frames":{"0":{"actions":{"0":{"action_data":{"boolean":[{"name":"validated","val":false},{"name":"occluded","val":false}],"text":[{"name":"label","val":"manual"}]}}}},"1":{"actions":{"0":{"action_data":{"boolean":[{"name":"validated","val":false},{"name":"occluded","val":false}],"text":[{"name":"label","val":"manual"}]}}}},"2":{"actions":{"0":{"action_data":{"boolean":[{"name":"validated","val":false},{"name":"occluded","val":false}],"text":[{"name":"label","val":"manual"}]}}}},"3":{"actions":{"0":{"action_data":{"boolean":[{"name":"validated","val":false},{"name":"occluded","val":false}],"text":[{"name":"label","val":"manual"}]}}}},"4":{"actions":{"0":{"action_data":{"boolean":[{"name":"validated","val":false},{"name":"occluded","val":false}],"text":[{"name":"label","val":"manual"}]}}}},"5":{"actions":{"0":{"action_data":{"boolean":[{"name":"validated","val":false},{"name":"occluded","val":false}],"text":[{"name":"label","val":"manual"}]}}}}},"schema_version":"4.3.0","frame_intervals":[{"frame_start":0,"frame_end":5}],"actions":{"0":{"name":"","type":"#Walking","frame_intervals":[{"frame_start":0,"frame_end":5}],"action_data_pointers":{"validated":{"type":"boolean","frame_intervals":[{"frame_start":0,"frame_end":5}]},"occluded":{"type":"boolean","frame_intervals":[{"frame_start":0,"frame_end":5}]},"label":{"type":"text","frame_intervals":[{"frame_start":0,"frame_end":5}]}}}}}}') if not os.path.isfile('./etc/' + vcd_version_name + '_test_element_data_same_name.json'): vcd.save('./etc/' + vcd_version_name + '_test_element_data_same_name.json')
def test_action_properties(self): # 1.- Create a VCD instance vcd = core.VCD() # 2.- Create the Object uid_action1 = vcd.add_action(name="", semantic_type="#Running", frame_value=(0, 10)) vcd.add_action_data(uid=uid_action1, action_data=types.num(name="confidence", val=0.98), frame_value=0) vcd.add_action_data(uid=uid_action1, action_data=types.vec(name="confidence_vec", val=[0.98, 0.97]), frame_value=0) vcd.add_action_data(uid=uid_action1, action_data=types.text(name="annotation", val="Manual"), frame_value=0) vcd.add_action_data(uid=uid_action1, action_data=types.boolean(name="validated", val=True), frame_value=1) # Same can be done with events and event_data, and contexts and context_data # And can be done as dynamic or static info uid_object1 = vcd.add_object(name="Marcos", semantic_type="#Person") vcd.add_object_data(uid=uid_object1, object_data=types.text(name="Position", val="#Researcher")) uid_context1 = vcd.add_context(name="", semantic_type="#Sunny") vcd.add_context_data(uid=uid_context1, context_data=types.text(name="category", val="#Weather")) vcd.add_context_data(uid=uid_context1, context_data=types.text(name="annotation", val="Manual")) uid_context2 = vcd.add_context(name="", semantic_type="#Highway", frame_value=(0, 5)) vcd.add_context_data(uid=uid_context2, context_data=types.num(name="risk", val=0.7), frame_value=4) vcd.add_context_data(uid=uid_context2, context_data=types.num(name="weight", val=0.5), frame_value=4) if not os.path.isfile('./etc/vcd430_test_actions_with_action_data.json'): vcd.save('./etc/vcd430_test_actions_with_action_data.json', True) vcd_read = core.VCD('./etc/vcd430_test_actions_with_action_data.json', validation=True) vcd_read_stringified = vcd_read.stringify() vcd_stringified = vcd.stringify() # print(vcd_stringified) self.assertEqual(vcd_read_stringified, vcd_stringified)
def test_nested_object_data_attributes(self): vcd = core.VCD() uid_obj1 = vcd.add_object('someName1', '#Some') box1 = types.bbox('head', (0, 0, 10, 10)) box1.add_attribute(types.boolean('visible', True)) self.assertEqual('attributes' in box1.data, True) self.assertEqual('boolean' in box1.data['attributes'], True) self.assertEqual( type(box1.data['attributes']['boolean']) is list, True) self.assertEqual(box1.data['attributes']['boolean'][0]['name'], "visible") self.assertEqual(box1.data['attributes']['boolean'][0]['val'], True) vcd.add_object_data(uid_obj1, box1, 0) if not os.path.isfile('./etc/vcd430_test_nested_object_data.json'): vcd.save('./etc/vcd430_test_nested_object_data.json', True) vcd_read = core.VCD('./etc/vcd430_test_nested_object_data.json', validation=True) vcd_read_stringified = vcd_read.stringify() vcd_stringified = vcd.stringify() # print(vcd_stringified) self.assertEqual(vcd_read_stringified, vcd_stringified)
def test_uid_types(self): # 1.- Create a VCD instance vcd = core.VCD() # We can add elements and get UIDs as strings uid0 = vcd.add_object("Mike", "Person") self.assertEqual(isinstance(uid0, str), True) self.assertEqual(uid0, "0") # We can also specify which UID we will like our elements to have # We can use integers and stringified integers # Response is always string uid1 = vcd.add_object(name="George", semantic_type="Person", uid=1) # integer uid2 = vcd.add_object(name="Susan", semantic_type="Person", uid="2") # stringified integer self.assertEqual(vcd.has(core.ElementType.object, uid1), True) self.assertEqual(vcd.has(core.ElementType.object, uid2), True) self.assertEqual(uid1, "1") self.assertEqual(uid2, "2") # In general, the user can use integers or stringified integers for all public functions vcd.add_object_data(2, types.boolean("checked", True)) vcd.add_object_data("2", types.boolean("double-checked", True)) # Same happens with ontology uids ont_uid_0 = vcd.add_ontology( ontology_name="http://www.vicomtech.org/viulib/ontology") self.assertEqual(isinstance(ont_uid_0, str), True) uid3 = vcd.add_object(name="Mark", semantic_type="#Pedestrian", ont_uid=ont_uid_0) uid4 = vcd.add_object(name="Rose", semantic_type="#Pedestrian", ont_uid=0) self.assertEqual(vcd.get_object(uid3)['ontology_uid'], '0') self.assertEqual(vcd.get_object(uid4)['ontology_uid'], '0') # All returned UIDs are strings, and when written into JSON as well #print(vcd.stringify(False)) self.assertEqual( vcd.stringify(False), '{"vcd":{"metadata":{"schema_version":"4.3.1"},"objects":{"0":{"name":"Mike","type":"Person"},"1":{"name":"George","type":"Person"},"2":{"name":"Susan","type":"Person","object_data":{"boolean":[{"name":"checked","val":true},{"name":"double-checked","val":true}]},"object_data_pointers":{"checked":{"type":"boolean","frame_intervals":[]},"double-checked":{"type":"boolean","frame_intervals":[]}}},"3":{"name":"Mark","type":"#Pedestrian","ontology_uid":"0"},"4":{"name":"Rose","type":"#Pedestrian","ontology_uid":"0"}},"ontologies":{"0":"http://www.vicomtech.org/viulib/ontology"}}}' )
def test_remove_simple(self): # 1.- Create VCD vcd = core.VCD() # 2.- Create some objects car1_uid = vcd.add_object(name='BMW', semantic_type='#Car') car2_uid = vcd.add_object(name='Seat', semantic_type='#Car') person1_uid = vcd.add_object(name='John', semantic_type='#Pedestrian') trafficSign1UID = vcd.add_object(name='', semantic_type='#StopSign') # 3.- Add some content # Same FrameInterval (0, 5) vcd.add_object_data(uid=person1_uid, object_data=types.bbox('face', (0, 0, 100, 100)), frame_value=(0, 5)) vcd.add_object_data(uid=person1_uid, object_data=types.bbox('mouth', (0, 0, 10, 10)), frame_value=(0, 5)) vcd.add_object_data(uid=person1_uid, object_data=types.bbox('hand', (0, 0, 30, 30)), frame_value=(0, 5)) vcd.add_object_data(uid=person1_uid, object_data=types.bbox('eyeL', (0, 0, 10, 10)), frame_value=(0, 5)) vcd.add_object_data(uid=person1_uid, object_data=types.bbox('eyeR', (0, 0, 10, 10)), frame_value=(0, 5)) # A different FrameInterval (0, 10) vcd.add_object_data(uid=person1_uid, object_data=types.num('age', 35.0), frame_value=(0, 10)) # Data for the other objects vcd.add_object_data(uid=car1_uid, object_data=types.bbox('position', (100, 100, 200, 400)), frame_value=(0, 10)) vcd.add_object_data(uid=car1_uid, object_data=types.text('color', 'red'), frame_value=(6, 10)) vcd.add_object_data(uid=car2_uid, object_data=types.bbox('position', (300, 1000, 200, 400)), frame_value=(0, 10)) vcd.add_object_data(uid=trafficSign1UID, object_data=types.boolean('visible', True), frame_value=(0, 4)) # print("Frame 5, dynamic only message: ", vcd.stringify_frame(5, dynamic_only=True)) # print("Frame 5, full message: ", vcd.stringify_frame(5, dynamic_only=False)) if not os.path.isfile('./etc/' + vcd_version_name + '_test_remove_simple.json'): vcd.save('./etc/' + vcd_version_name + '_test_remove_simple.json') self.assertEqual(vcd.get_num_objects(), 4, "Should be 4") # 4.- Delete some content vcd.rm_object(uid=car2_uid) self.assertEqual(vcd.get_num_objects(), 3, "Should be 3") vcd.rm_object_by_type(semantic_type='#StopSign') self.assertEqual(vcd.get_num_objects(), 2, "Should be 2") # 5.- Remove all content sequentially vcd.rm_object(uid=person1_uid) self.assertEqual(vcd.get_num_objects(), 1, "Should be 1") vcd.rm_object(uid=car1_uid) self.assertEqual(vcd.get_num_objects(), 0, "Should be 0") self.assertEqual(vcd.get_frame_intervals().empty(), True)
def __add_attributes(self, src330, object_data430): # Add any attributes if 'attributes' in src330: attributes = src330['attributes'] for k, v in attributes.items(): if k == "bool": for od in v: object_data430.add_attribute(types.boolean(od['name'], od['val'])) elif k == "num": for od in v: if len(od['val']) == 1: object_data430.add_attribute(types.num(od['name'], od['val'][0])) else: object_data430.add_attribute(types.vec(od['name'], od['val'])) elif k == "text": for od in v: object_data430.add_attribute(types.text(od['name'], od['val']))
def prueba(): with open('config.json') as f: data = json.load(f) labels = data['labels'] path = 'labels' pr = cProfile.Profile() for img_name in os.listdir(path): pr.enable() vcd = core.VCD() img_label = cv.imread('labels/' + img_name) img_instance = cv.imread('instances/' + img_name, cv.IMREAD_GRAYSCALE) imgPIL_instance = Image.open('instances/' + img_name) imgPIL_instance = np.array(imgPIL_instance, dtype=np.uint16) label_path = 'labels/' + img_name instance_path = 'instances/' + img_name instance_image = Image.open(instance_path) # convert labeled data to numpy arrays for better handling instance_array = np.array(instance_image, dtype=np.uint16) classes_colors = {} for x in labels: classes_colors[x['name']] = x['color'] # prepare arrays for instance and class retrieval instance_ids_array = np.array(imgPIL_instance % 256, dtype=np.uint8) instance_label_array = np.array(imgPIL_instance / 256, dtype=np.uint8) img_instance_out = np.zeros( (img_instance.shape[0], img_instance.shape[1], 3), np.uint8) img_instance_out[np.where( (img_instance_out == [0, 0, 0]).all(axis=2))] = [0, 255, 0] img_class_out = np.zeros( (img_instance.shape[0], img_instance.shape[1], 3), np.uint8) instance_bgr = cv.cvtColor(instance_ids_array, cv.COLOR_GRAY2BGR) final = np.zeros(img_label.shape, np.uint8) cont = 0 cv.namedWindow('image', cv.WINDOW_NORMAL) cv.resizeWindow('image', img_instance.shape[0], img_instance.shape[1]) # Get contours of each instance and retrieve it's class to write in vcd as instance -> True for i in range(1, np.max(instance_ids_array) + 1): seg = cv.inRange(instance_bgr, (i, i, i), (i, i, i)) if cv.countNonZero(seg) != 0: contours, hierarchy = cv.findContours(seg, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) cnt_id = 0 # Reverse point_color from bgr to rgb to get class # Write class in vcd for c in contours: extLeft = tuple(c[c[:, :, 0].argmin()][0]) color = img_label[extLeft[1]][extLeft[0]] color = tuple([int(x) for x in color]) color = list(color) instance_class = utils.get_key(classes_colors, color[::-1]) if cnt_id == 0: uid = vcd.add_object("object " + str(cont), instance_class) vcd.add_object_data(uid, types.boolean('isInstance', True)) c = c.flatten() hierarchy_list = hierarchy[0][cnt_id].tolist() # Write poly, hierarchy and instance polygon = types.poly2d( 'contour', c.tolist(), types.Poly2DType.MODE_POLY2D_SRF6DCC, closed=True, hierarchy=hierarchy_list) vcd.add_object_data(uid, polygon) cnt_id += 1 cont += 1 # Get contours of each CLASS and write it in VCD as instance -> False for class_val in labels: # check all posible classes of mapillary seg = cv.inRange(img_label, tuple(class_val['color'][::-1]), tuple(class_val['color'][::-1])) if cv.countNonZero(seg) != 0: contours, hierarchy = cv.findContours(seg, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) cv.drawContours(final, contours, -1, tuple(class_val['color'][::-1]), thickness=-1) cnt_id = 0 instance_class = utils.get_key(classes_colors, class_val['color']) uid = vcd.add_object("object " + str(cont), instance_class) vcd.add_object_data(uid, types.boolean('isInstance', False)) for c in contours: c = c.flatten() hierarchy_list = hierarchy[0][cnt_id].tolist() polygon = types.poly2d( 'contour', c.tolist(), types.Poly2DType.MODE_POLY2D_SRF6DCC, closed=True, hierarchy=hierarchy_list) vcd.add_object_data(uid, polygon) cont += 1 cnt_id += 1 vcd.save('vcd_files/' + img_name[0:len(img_name) - 4] + '.json', True) # Change to True to use json prettifier # 3.- Reconstruct the image from the VCD poly2d and hierarchies (using OpenCV) contours_dict_instance = { } # A dictionary of contours. Each key is one class type, each value, a contours array hierarchy_dict_instance = {} contours_dict_class = { } # A dictionary of contours. Each key is one class type, each value, a contours array hierarchy_dict_class = {} for object_key, object_val in vcd.data['vcd']['objects'].items(): # Assuming this is static (no frame info) contours_dict_instance.setdefault(object_val['type'], []) contours_dict_class.setdefault(object_val['type'], []) hierarchy_dict_instance.setdefault(object_val['type'], []) hierarchy_dict_class.setdefault(object_val['type'], []) if 'object_data' in object_val: if 'boolean' in object_val['object_data']: if 'poly2d' in object_val['object_data']: for idx_pol, poly2d in enumerate( object_val['object_data']['poly2d']): val = poly2d['val'] # (x, y, rest, chain) mode = poly2d['mode'] # closed = poly2d['closed'] # Not used in OpenCV hierarchy = poly2d['hierarchy'] instance = object_val['object_data']['boolean'][0][ 'val'] if mode == types.Poly2DType.MODE_POLY2D_SRF6DCC.name: vec = poly.getVecFromEncodedSRF6( int(val[0]), int(val[1]), int(val[2]), val[3]) else: vec = val # Then, create contours, format as OpenCV expects num_coords = len(vec) num_points = int(num_coords / 2) contour = np.asarray(vec).reshape( (num_points, 1, 2)) if instance: contours_dict_instance[ object_val['type']].append(contour) hierarchy_dict_instance[ object_val['type']].append(hierarchy) else: contours_dict_class[object_val['type']].append( contour) hierarchy_dict_class[ object_val['type']].append(hierarchy) # Retrieve class img from VCD for class_name, contours in contours_dict_class.items(): hierarchy_list = hierarchy_dict_class[class_name] num_contours = len(contours) hierarchy_array = np.asarray(hierarchy_list).reshape( num_contours, 1, 4) color = classes_colors[class_name] cv.drawContours(img_class_out, contours, -1, color[::-1], hierarchy=np.asarray([hierarchy_list]), thickness=-1) # Retrieve instance img from VCD for class_name, contours in contours_dict_instance.items(): hierarchy_list = hierarchy_dict_instance[class_name] num_contours = len(contours) hierarchy_array = np.asarray(hierarchy_list).reshape( num_contours, 1, 4) color = classes_colors[class_name] for c in contours: cv.drawContours(img_instance_out, [c], -1, (0, 0, 0), thickness=-1) #cv.drawContours(img_instance_out, [c], -1, color[::-1], thickness=-1) #cv.drawContours(img_instance_out, [c], -1, (0, 255, 0), thickness=3) x = cv.cvtColor(instance_ids_array, cv.COLOR_GRAY2BGR) x[np.where((x == [0, 0, 0]).all(axis=2))] = [0, 255, 0] img_instance = cv.cvtColor(img_instance, cv.COLOR_GRAY2BGR) difference_instance = cv.subtract(img_instance_out, x) difference_class = cv.subtract(img_label, img_class_out) stack = np.hstack( (img_instance, img_instance_out, difference_instance)) stack2 = np.hstack((img_label, img_class_out, difference_class)) vstack = np.vstack((stack, stack2)) pr.disable() pr.print_stats(sort='time') cv.imshow('image', vstack) cv.waitKey(0)
def __copy_elements(self, vcd_430, root, frame_num=None): if 'objects' in root: for object in root['objects']: uid = str(object['uid']) # Let's convert to string here name = object['name'] ontologyUID = None if 'ontologyUID' in object: ontologyUID = str(object['ontologyUID']) # Let's convert to string here typeSemantic = object.get('type', '') # In VCD 4.3.0 type is required, but it VCD 3.3.0 seems to be not if not vcd_430.has(core.ElementType.object, uid): vcd_430.add_object(name, typeSemantic, frame_num, uid, ontologyUID) if 'objectDataContainer' in object: objectDataContainer = object['objectDataContainer'] for key, value in objectDataContainer.items(): for object_data in value: inStream = None if 'inStream' in object_data: inStream = object_data['inStream'] if 'val' in object_data: val = object_data['val'] currentObjectData = None # Create main object_data body # NOTE: in the following calls, I am using direct access to dictionary for required fields, e.g. # object_data['name'], etc. # For optional fields, I am using get() function, e.g. object_data.get('mode') which defaults to # None if key == 'num': if len(val) == 1: # Single value, this is a num currentObjectData = types.num(object_data['name'], val[0], inStream) else: # Multiple values, this is a vec currentObjectData = types.vec(object_data['name'], val, inStream) elif key == 'bool': currentObjectData = types.boolean(object_data['name'], val, inStream) elif key == 'text': currentObjectData = types.text(object_data['name'], val, inStream) elif key == 'image': currentObjectData = types.image( object_data['name'], val, object_data['mimeType'], object_data['encoding'], inStream ) elif key == 'binary': currentObjectData = types.binary( object_data['name'], val, object_data['dataType'], object_data['encoding'], inStream ) elif key == 'vec': currentObjectData = types.vec(object_data['name'], val, inStream) elif key == 'bbox': currentObjectData = types.bbox(object_data['name'], val, inStream) elif key == 'cuboid': currentObjectData = types.cuboid(object_data['name'], val, inStream) elif key == 'mat': currentObjectData = types.mat( object_data['name'], val, object_data['channels'], object_data['width'], object_data['height'], object_data['dataType'], inStream ) elif key == 'point2D': currentObjectData = types.point2d(object_data['name'], val, object_data.get('id'), inStream) elif key == 'point3D': currentObjectData = types.point3d(object_data['name'], val, object_data.get('id'), inStream) elif key == "poly2D": mode_int = object_data['mode'] currentObjectData = types.poly2d( object_data['name'], val, types.Poly2DType(mode_int), object_data['closed'], inStream ) elif key == "poly3D": currentObjectData = types.poly3d(object_data['name'], val, object_data['closed'], inStream) elif key == "mesh": currentObjectData = types.mesh(object_data['name']) if 'point3D' in object_data: for p3d_330 in object_data['point3D']: # Create a types.point3d object and add it to the mesh id = p3d_330['id'] name = p3d_330['name'] val = p3d_330['val'] p3d_430 = types.point3d(name, val) self.__add_attributes(p3d_330, p3d_430) currentObjectData.add_vertex(p3d_430, id) if 'lineReference' in object_data: for lref_330 in object_data['lineReference']: # Create a types.line_reference object and add it to the mesh id = lref_330['id'] name = lref_330['name'] referenceType = lref_330['referenceType'] assert(referenceType == "point3D") val = lref_330.get('val') # defaults to None, needed for the constructor lref_430 = types.lineReference(name, val, types.ObjectDataType.point3d) self.__add_attributes(lref_330, lref_430) currentObjectData.add_edge(lref_430, id) if 'areaReference' in object_data: for aref_330 in object_data['areaReference']: # Create a types.area_reference object and add it to the mesh id = aref_330['id'] name = aref_330['name'] referenceType = aref_330['referenceType'] assert (referenceType == "point3D" or referenceType == "lineReference") val = aref_330.get('val') # defaults to None, needed for the constructor if referenceType == "point3D": aref_430 = types.areaReference(name, val, types.ObjectDataType.point3d) else: aref_430 = types.areaReference(name, val, types.ObjectDataType.line_reference) self.__add_attributes(aref_330, aref_430) currentObjectData.add_area(aref_430, id) # Add any attributes self.__add_attributes(object_data, currentObjectData) # Add the object_data to the object vcd_430.add_object_data(uid, currentObjectData, frame_num) if 'actions' in root: for action in root['actions']: uid = str(action['uid']) name = action['name'] ontologyUID = None if 'ontologyUID' in action: ontologyUID = str(action['ontologyUID']) typeSemantic = action.get('type', '') # required in VCD 4.0, not in VCD 3.3.0 vcd_430.add_action(name, typeSemantic, frame_num, uid, ontologyUID) if 'events' in root: for event in root['events']: uid = str(event['uid']) name = event['name'] ontologyUID = None if 'ontologyUID' in event: ontologyUID = str(event['ontologyUID']) typeSemantic = event.get('type', '') vcd_430.add_event(name, typeSemantic, frame_num, uid, ontologyUID) if 'contexts' in root: for context in root['contexts']: uid = str(context['uid']) name = context['name'] ontologyUID = None if 'ontologyUID' in context: ontologyUID = str(context['ontologyUID']) typeSemantic = context.get('type', '') vcd_430.add_context(name, typeSemantic, frame_num, uid, ontologyUID) if 'relations' in root: for relation in root['relations']: uid = str(relation['uid']) name = relation['name'] ontologyUID = None if 'ontologyUID' in relation: ontologyUID = str(relation['ontologyUID']) predicate = relation.get('predicate', '') rdf_objects = relation.get('rdf_objects', None) rdf_subjects = relation.get('rdf_subjects', None) vcd_430.add_relation(name, predicate, frame_value=frame_num, uid=uid, ont_uid=ontologyUID) relation = vcd_430.get_element(core.ElementType.relation, uid) if not 'rdf_objects' in relation or len(relation['rdf_objects']) == 0: # just add once for rdf_object in rdf_objects: element_type = None rdf_object_type_str = rdf_object['type'] if rdf_object_type_str == "Object": element_type = core.ElementType.object elif rdf_object_type_str == "Action": element_type = core.ElementType.action elif rdf_object_type_str == "Event": element_type = core.ElementType.event elif rdf_object_type_str == "Context": element_type = core.ElementType.context else: warnings.warn("ERROR: Unrecognized Element type. Must be Object, Action, Event or Context.") vcd_430.add_rdf(uid, core.RDF.object, str(rdf_object['uid']), element_type) if not 'rdf_subjects' in relation or len(relation['rdf_subjects']) == 0: # just add once for rdf_subject in rdf_subjects: element_type = None rdf_object_type_str = rdf_subject['type'] if rdf_object_type_str == "Object": element_type = core.ElementType.object elif rdf_object_type_str == "Action": element_type = core.ElementType.action elif rdf_object_type_str == "Event": element_type = core.ElementType.event elif rdf_object_type_str == "Context": element_type = core.ElementType.context else: warnings.warn("ERROR: Unrecognized Element type. Must be Object, Action, Event or Context.") vcd_430.add_rdf(uid, core.RDF.subject, str(rdf_subject['uid']), element_type)
contours, hierarchy = cv.findContours(seg, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) cnt_id = 0 # Reverse point_color from bgr to rgb to get class # Write class in vcd for c in contours: extLeft = tuple(c[c[:, :, 0].argmin()][0]) color = img_label[extLeft[1]][extLeft[0]] color = tuple([int(x) for x in color]) color = list(color) instance_class = utils.get_key(classes_colors, color[::-1]) if cnt_id == 0: uid = vcd.add_object("Instance " + str(i), instance_class) vcd.add_object_data(uid, types.boolean('isInstance', True)) c = c.flatten() hierarchy_list = hierarchy[0][cnt_id].tolist() # Write poly, hierarchy and instance polygon = types.poly2d('contour', c.tolist(), types.Poly2DType.MODE_POLY2D_RS6FCC, closed=True, hierarchy=hierarchy_list) vcd.add_object_data(uid, polygon) cnt_id += 1 # Get contours of each CLASS and write it in VCD as instance -> False for class_val in labels: # check all posible classes of mapillary
def update_vcd(self, annotations, validations, statics=None, metadata=None): """ Convert annotations into VCD4 format """ # But, if there are already static annotations in vcd, take and keep # them for the next vcd areStatics = bool(statics) isMetadata = bool(metadata) if isMetadata: # @metadata: [face_meta, body_meta,hands_meta] # @face_meta (5): [rgb_video_frames,mat] # @body_meta (6): [date_time,rgb_video_frames,mat] # @hands_meta (7): [rgb_video_frames,mat] self._f_frames = int(metadata[0][0]) self._f_intrinsics = metadata[0][1] self.timeStamp = str(metadata[1][0]) # Change ":" symbol to ";" for windows correct visualization self.timeStamp.replace(":", ";") self._b_frames = int(metadata[1][1]) self._b_intrinsics = metadata[1][2] self._h_frames = int(metadata[2][0]) self._h_intrinsics = metadata[2][1] if areStatics: # Driver Data age = int(statics[0]["val"]) gender = statics[1]["val"] glasses = bool(statics[2]["val"]) drive_freq = statics[3]["val"] experience = statics[4]["val"] # Context Data weather = statics[5]["val"] setup = statics[6]["val"] # Annotator annotatorID = str(statics[7]["val"]) if self._bf_shift is None or self._hb_shift is None or \ self._hf_shift is None: raise RuntimeError( "Shift values have not been set. Run set_shifts() function " "before") body_face_shift = self._bf_shift # hands_body_shift = self.__hb_shift hands_face_shift = self._hf_shift # Get total number of lines which is equivalent to total number of # frames of mosaic assert (len(annotations) == len(validations)) total_frames = len(annotations) # 1.- Create a VCD instance vcd = core.VCD() # 2.- Add Object for Subject self.uid_driver = vcd.add_object(self.subject, "driver", ont_uid=0, frame_value=(0, total_frames - 1)) # 3.- VCD Name vcd.add_name(self.group + '_' + self.subject + '_' + self.session + '_' + self.date + '_' + self._annotation_mode) # 4.- Annotator if areStatics: vcd.add_annotator(annotatorID) # 5- Ontology vcd.add_ontology('http://dmd.vicomtech.org/ontology') # 6.- Cameras # Build Uri to video files if self._setUpManager._external_struct: video_root_path = Path() / self.group / self.subject / self.session face_uri = video_root_path / (self.group + '_' + self.subject + '_' + self.session + '_' + self.date + '_rgb_face.mp4') body_uri = video_root_path / (self.group + '_' + self.subject + '_' + self.session + '_' + self.date + '_rgb_body.mp4') hands_uri = video_root_path / (self.group + '_' + self.subject + '_' + self.session + '_' + self.date + '_rgb_hands.mp4') else: video_root_path = Path() / self.group / self.date / self.subject face_uri = video_root_path / (self.subject + '_' + self.session + '_' + 'face' + '_' + self.date + '.mp4') body_uri = video_root_path / (self.subject + '_' + self.session + '_' + 'body' + '_' + self.date + '.mp4') hands_uri = video_root_path / (self.subject + '_' + self.session + '_' + 'hands' + '_' + self.date + '.mp4') face_video_descr = 'Frontal face looking camera' body_video_descr = 'Side body looking camera' hands_video_descr = 'Hands and wheel looking camera' vcd.add_stream('face_camera', str(face_uri), face_video_descr, core.StreamType.camera) vcd.add_stream('body_camera', str(body_uri), body_video_descr, core.StreamType.camera) vcd.add_stream('hands_camera', str(hands_uri), hands_video_descr, core.StreamType.camera) # 7.- Stream Properties # Real Intrinsics of cameras vcd.add_stream_properties(stream_name='face_camera', properties={ 'cam_module': 'Intel RealSense D415', 'total_frames': self._f_frames, }, stream_sync=types.StreamSync(frame_shift=0), intrinsics=types.IntrinsicsPinhole( width_px=1280, height_px=720, camera_matrix_3x4=self._f_intrinsics)) vcd.add_stream_properties( stream_name='body_camera', properties={ 'camera_module': 'Intel RealSense D435', 'total_frames': self._b_frames, }, stream_sync=types.StreamSync(frame_shift=body_face_shift), intrinsics=types.IntrinsicsPinhole( width_px=1280, height_px=720, camera_matrix_3x4=self._b_intrinsics)) vcd.add_stream_properties( stream_name='hands_camera', properties={ 'camera_module': 'Intel RealSense D415', 'total_frames': self._h_frames, }, stream_sync=types.StreamSync(frame_shift=hands_face_shift), intrinsics=types.IntrinsicsPinhole( width_px=1280, height_px=720, camera_matrix_3x4=self._h_intrinsics)) if areStatics or isMetadata: # 8.- Add Context of Recording session last_frame = total_frames - 1 ctx_txt = 'recording_context' rec_context_uid = vcd.add_context(name='', semantic_type=ctx_txt, frame_value=(0, last_frame)) if areStatics: vcd.add_context_data(rec_context_uid, types.text(name='weather', val=weather)) vcd.add_context_data(rec_context_uid, types.text(name='setup', val=setup)) # 9.- Add Driver static properties vcd.add_object_data(self.uid_driver, types.num(name='age', val=age)) vcd.add_object_data(self.uid_driver, types.text(name='gender', val=gender)) vcd.add_object_data(self.uid_driver, types.boolean(name='glasses', val=glasses)) vcd.add_object_data( self.uid_driver, types.text(name='experience', val=experience)) vcd.add_object_data( self.uid_driver, types.text(name='drive_freq', val=drive_freq)) if isMetadata: vcd.add_context_data( rec_context_uid, types.text(name='recordTime', val=self.timeStamp)) # 10.- Save annotation and validation vectors in VCD format # Perform general update new_vcd = self.add_annotationsx(vcd, annotations, validations, self.ont_uid) # Update class variable __vcd with newly created object self._vcd = new_vcd return True