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_create_mesh_with_API_frames(self): # Load from previous test vcd = core.VCD('./etc/test_mesh.json') # Let's assume we know the structure of the mesh # # P0 L0 P1 L4 P4 # *--------*--------* # | | | # |L3 A0 |L1 A1 |L5 # | | | # *--------*--------* # P3 L2 P2 L6 P5 # # V0 [A0,A1] # Let's read mesh object # mesh1 = vcd.get_objects_with_object_data_name("parkslot1") mesh1 = vcd.get_object(0) # Let's read static object_data # od_mesh = mesh1.data['object_data']['mesh'] od_mesh = vcd.get_object_data(0, "parkslot1", frame_num=None) vertices = od_mesh['point3d'] edges = od_mesh['line_reference'] areas = od_mesh['area_reference'] # Let's add some frame-specific attributes (for line-reference and area-references) # Currently, only way to do it is by creating a new mesh object_data # and add it to the existing Object, specifying the frame for frame_num in range(0, 2): mesh1_frame = types.mesh("parkslot1") for line_key, line_val in edges.items(): # If we want to add a line_reference attribute: Reconstruct line_reference # Read existing info # "None" for val, so it is not copied at frame-lev. lX = types.lineReference( line_val['name'], reference_type=types.ObjectDataType.point3d, val=None) lX.add_attribute(types.text("PM_line_colour", "not set")) mesh1_frame.add_edge(lX, line_key) for area_key, area_val in areas.items(): # If we want to add an area_reference attribute: Reconstruct area_reference # Read existing info aX = types.areaReference( area_val['name'], reference_type=types.ObjectDataType.line_reference, val=None) aX.add_attribute(types.text("PM_park_slot_content", "Empty")) mesh1_frame.add_area(aX, area_key) vcd.add_object_data(0, mesh1_frame, frame_num) # Save it if not os.path.isfile('./etc/test_mesh_frame.json'): vcd.save('./etc/test_mesh_frame.json', True)
def test_object_change_from_static_to_dynamic(self): # Static->Dynamic # Case A) (when VCD has no other object with frames) vcd_a = core.VCD() uid_a = vcd_a.add_object("Enara", "Child") # Let's add some object data vcd_a.add_object_data(uid=uid_a, object_data=types.text(name="FavouriteColor", val="Pink")) self.assertEqual(vcd_a.get_object_data(uid=uid_a, data_name='FavouriteColor', frame_num=3), None) self.assertEqual(vcd_a.get_object_data(uid=uid_a, data_name='FavouriteColor')['val'], 'Pink') if not os.path.isfile('./etc/' + vcd_version_name + '_test_object_change_from_static_to_dynamic_a_before.json'): vcd_a.save('./etc/' + vcd_version_name + '_test_object_change_from_static_to_dynamic_a_before.json') # Let's modify the object so it has a certain frame interval (object_data frame intervals remain void) vcd_a.add_object(name="Enara", semantic_type="Child", uid=uid_a, frame_value=[(5, 10)]) if not os.path.isfile('./etc/' + vcd_version_name + '_test_object_change_from_static_to_dynamic_a_after.json'): vcd_a.save('./etc/' + vcd_version_name + '_test_object_change_from_static_to_dynamic_a_after.json') # Check that the element data is now also defined for this frame interval (and thus removed from the root) self.assertEqual(vcd_a.get_object_data(uid=uid_a, data_name='FavouriteColor', frame_num=3), None) self.assertEqual(vcd_a.get_object_data(uid=uid_a, data_name='FavouriteColor')['val'], 'Pink') self.assertEqual(vcd_a.get_object_data(uid=uid_a, data_name='FavouriteColor', frame_num=8)['val'], 'Pink') # Case B (when VCD has some other frame intervals already defined): VCD's get_element_data behaves differently vcd_b = core.VCD() vcd_b.add_object(name="room1", semantic_type="Room", frame_value=[(0, 10)]) uid_b = vcd_b.add_object(name="Enara", semantic_type="Child") vcd_b.add_object_data(uid=uid_b, object_data=types.text(name="FavouriteColor", val="Pink")) if not os.path.isfile('./etc/' + vcd_version_name + '_test_object_change_from_static_to_dynamic_b_before.json'): vcd_b.save('./etc/' + vcd_version_name + '_test_object_change_from_static_to_dynamic_b_before.json') # In this case, as the VCD has frames, the object is assumed to exist in all the scene # when the user asks for element_data at certain frame, VCD looks for element_data at that frame, and if there # is nothing, it then searches at the static part self.assertEqual(vcd_b.get_object_data(uid=uid_b, data_name='FavouriteColor', frame_num=3)['val'], 'Pink') self.assertEqual(vcd_b.get_object_data(uid=uid_b, data_name='FavouriteColor')['val'], 'Pink') vcd_b.add_object(name="Enara", semantic_type="Child", uid=uid_b, frame_value=[(5, 10)]) if not os.path.isfile('./etc/' + vcd_version_name + '_test_object_change_from_static_to_dynamic_b_after.json'): vcd_b.save('./etc/' + vcd_version_name + '_test_object_change_from_static_to_dynamic_b_after.json') self.assertEqual(vcd_b.get_object_data(uid=uid_b, data_name='FavouriteColor', frame_num=3), None) self.assertEqual(vcd_b.get_object_data(uid=uid_b, data_name='FavouriteColor')['val'], 'Pink') self.assertEqual(vcd_b.get_object_data(uid=uid_b, data_name='FavouriteColor', frame_num=8)['val'], 'Pink')
def test_static_dynamic_object_1(self): # 1.- Create a VCD instance vcd = core.VCD() # 2. - Let's create a static object and add some dynamic properties # When the attribute is added, the frame information is propagated to the element uid1 = vcd.add_object(name='line1', semantic_type='#LaneMarking') vcd.add_object_data(uid=uid1, object_data= types.text(name='type', val='dashed'), frame_value=(5, 10)) #print(vcd.stringify(False)) #self.assertEqual(vcd.stringify(False), '{"vcd":{"frames":{"5":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}},"6":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}},"7":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}},"8":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}},"9":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}},"10":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}}},"schema_version":"4.3.0","frame_intervals":[{"frame_start":5,"frame_end":10}],"objects":{"0":{"name":"line1","type":"#LaneMarking","frame_intervals":[{"frame_start":5,"frame_end":10}],"object_data_pointers":{"type":{"type":"text","frame_intervals":[{"frame_start":5,"frame_end":10}]}}}}}}') if not os.path.isfile('./etc/' + vcd_version_name + '_test_static_dynamic_object_1_1.json'): vcd.save('./etc/' + vcd_version_name + '_test_static_dynamic_object_1_1.json') # 3. - Let's add some static attributes vcd.add_object_data(uid=uid1, object_data= types.text(name='color', val='yellow')) #print(vcd.stringify(False)) #self.assertEqual(vcd.stringify(False), '{"vcd":{"frames":{"5":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}},"6":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}},"7":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}},"8":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}},"9":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}},"10":{"objects":{"0":{"object_data":{"text":[{"name":"type","val":"dashed"}]}}}}},"schema_version":"4.3.0","frame_intervals":[{"frame_start":5,"frame_end":10}],"objects":{"0":{"name":"line1","type":"#LaneMarking","frame_intervals":[{"frame_start":5,"frame_end":10}],"object_data_pointers":{"type":{"type":"text","frame_intervals":[{"frame_start":5,"frame_end":10}]},"color":{"type":"text","frame_intervals":[]}},"object_data":{"text":[{"name":"color","val":"yellow"}]}}}}}') if not os.path.isfile('./etc/' + vcd_version_name + '_test_static_dynamic_object_1_2.json'): vcd.save('./etc/' + vcd_version_name + '_test_static_dynamic_object_1_2.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_object_change_from_dynamic_to_static(self): vcd = core.VCD() uid1 = vcd.add_object("Enara", "Child") vcd.add_object_data(uid=uid1, object_data=types.text(name="FavouriteColor", val="Pink")) vcd.add_object_data(uid=uid1, object_data=types.vec(name="Position", val=(1.0, 5.0)), frame_value=8) if not os.path.isfile('./etc/' + vcd_version_name + '_test_object_change_from_dynamic_to_static_before.json'): vcd.save('./etc/' + vcd_version_name + '_test_object_change_from_dynamic_to_static_before.json') vcd.add_object(name="Enara", semantic_type="Child", uid=uid1, set_mode=core.SetMode.replace) if not os.path.isfile('./etc/' + vcd_version_name + '_test_object_change_from_dynamic_to_static_after.json'): vcd.save('./etc/' + vcd_version_name + '_test_object_change_from_dynamic_to_static_after.json') self.assertEqual(vcd.get_object_data(uid=uid1, data_name='FavouriteColor', frame_num=8), None) self.assertEqual(vcd.get_object_data(uid=uid1, data_name='FavouriteColor')['val'], 'Pink') self.assertEqual(vcd.get_object_data(uid=uid1, data_name='Position', frame_num=8), None) self.assertEqual(vcd.get_object_data(uid=uid1, data_name='Position'), None)
def test_ontology_list(self): vcd = core.VCD() ont_uid_1 = vcd.add_ontology( "http://www.vicomtech.org/viulib/ontology") ont_uid_2 = vcd.add_ontology("http://www.alternativeURL.org/ontology") # Let's create an object with a pointer to the ontology uid_car = vcd.add_object('CARLOTA', '#Car', frame_value=None, uid=None, ont_uid=ont_uid_1) vcd.add_object_data(uid_car, types.text('brand', 'Toyota')) vcd.add_object_data(uid_car, types.text('model', 'Prius')) uid_marcos = vcd.add_object('Marcos', '#Person', frame_value=None, uid=None, ont_uid=ont_uid_2) vcd.add_object_data(uid_marcos, types.bbox('head', (10, 10, 30, 30)), (2, 4)) self.assertEqual(vcd.get_object(uid_car)['ontology_uid'], ont_uid_1) self.assertEqual(vcd.get_object(uid_marcos)['ontology_uid'], ont_uid_2) self.assertEqual(vcd.get_ontology(ont_uid_1), "http://www.vicomtech.org/viulib/ontology") self.assertEqual(vcd.get_ontology(ont_uid_2), "http://www.alternativeURL.org/ontology") if not os.path.isfile('./etc/vcd430_test_ontology.json'): vcd.save('./etc/vcd430_test_ontology.json', True) vcd_read = core.VCD('./etc/vcd430_test_ontology.json', validation=True) self.assertEqual(vcd_read.stringify(), vcd.stringify())
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 test_static_dynamic_object_2(self): # 1.- Create a VCD instance vcd = core.VCD() # 2.- Create a dynamic object with static information # The attribute is added ot the objects section uid1 = vcd.add_object(name='line1', semantic_type='#BottsDots', frame_value=(5, 10)) poly = types.poly2d(name='poly', val=(100, 100, 110, 110, 120, 130, 500, 560), mode=types.Poly2DType.MODE_POLY2D_ABSOLUTE, closed=False) poly.add_attribute(object_data=types.text(name='type', val='single_dot')) vcd.add_object_data(uid=uid1, object_data=poly) #print(vcd.stringify(False)) #self.assertEqual(vcd.stringify(False), '{"vcd":{"frames":{"5":{"objects":{"0":{}}},"6":{"objects":{"0":{}}},"7":{"objects":{"0":{}}},"8":{"objects":{"0":{}}},"9":{"objects":{"0":{}}},"10":{"objects":{"0":{}}}},"schema_version":"4.3.0","frame_intervals":[{"frame_start":5,"frame_end":10}],"objects":{"0":{"name":"line1","type":"#BottsDots","frame_intervals":[{"frame_start":5,"frame_end":10}],"object_data":{"poly2d":[{"name":"poly","val":[100,100,110,110,120,130,500,560],"mode":"MODE_POLY2D_ABSOLUTE","closed":false,"attributes":{"text":[{"name":"type","val":"single_dot"}]}}]},"object_data_pointers":{"poly":{"type":"poly2d","frame_intervals":[],"attributes":{"type":"text"}}}}}}}') if not os.path.isfile('./etc/' + vcd_version_name + '_test_static_dynamic_object_2.json'): vcd.save('./etc/' + vcd_version_name + '_test_static_dynamic_object_2.json')
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 test_multi_value_attributes(self): # This test shows how to use "Vec" attribute with strings vcd = core.VCD() uid = vcd.add_object(name="car1", semantic_type="car") vcd.add_object_data(uid=uid, object_data=types.vec(name="signals", val=[0.1, 0.2, 0.3])) vcd.add_object_data(uid=uid, object_data=types.vec(name="categories", val=["Tourism", "Large", "Old"])) # Add additionalPropertis at attributes (apart from "name" and "val"), e.g. "quality", "locked", etc # Works for any attribute type (vec, bbox, etc) vcd.add_object_data(uid=uid, object_data=types.vec(name="shape", val=[0, 0, 100, 100], properties={"locked": True, "score": 0.8})) vcd.add_object_data(uid=uid, object_data=types.text(name="color", val="Blue", properties={"locked": False, "status": "validated"})) if not os.path.isfile('./etc/' + vcd_version_name + '_test_multi_value_attributes.json'): vcd.save('./etc/' + vcd_version_name + '_test_multi_value_attributes.json', True) vcd_read = core.VCD('./etc/' + vcd_version_name + '_test_multi_value_attributes.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_scene_KITTI_Tracking_3(self): sequence_number = 3 vcd_file_name = './etc/' + vcd_version_name + '_kitti_tracking_' + str( sequence_number).zfill(4) + ".json" vcd = core.VCD(vcd_file_name) frame_num_last = vcd.get_frame_intervals().get_outer()['frame_end'] ''' "In a city, being sunny, the ego-vehicle drives in the left lane of a single-way two-lanes road, Two other cars drive in the right lane. When the cars pass the ego-vehicle, then the ego-vehicle changes to the right lane, and then the ego-vehicle drives in the right lane." ''' vcd.add_metadata_properties({ "cnl_text": "In a city, being sunny, the ego-vehicle drives in the left lane of a single-way two-lanes road, Two other cars drive in the right lane. When the cars pass the ego-vehicle, then the ego-vehicle changes to the right lane, and then the ego-vehicle drives in the right lane." }) # Let's add VCD entries following the order # Contexts (1-2) vcd.add_context(name="City1", semantic_type="City") vcd.add_context(name="Sunny1", semantic_type="Sunny") # Add non-labeled actors (Ego-vehicle and lanes) uid_ego = vcd.get_object_uid_by_name(name="Egocar") uid_lane_left = vcd.add_object(name="Lane1", semantic_type="Lane") uid_lane_right = vcd.add_object(name="Lane2", semantic_type="Lane") uid_road = vcd.add_object(name="Road1", semantic_type="Road") vcd.add_element_data(element_type=core.ElementType.object, uid=uid_lane_left, element_data=types.text(name="Position", val="Left")) vcd.add_element_data(element_type=core.ElementType.object, uid=uid_lane_right, element_data=types.text(name="Position", val="Right")) vcd.add_element_data(element_type=core.ElementType.object, uid=uid_road, element_data=types.text(name="Direction", val="Single-way")) vcd.add_element_data(element_type=core.ElementType.object, uid=uid_road, element_data=types.num(name="NumberOfLanes", val=2)) vcd.add_relation_object_object(name="", semantic_type="isPartOf", object_uid_1=uid_lane_left, object_uid_2=uid_road) vcd.add_relation_object_object(name="", semantic_type="isPartOf", object_uid_1=uid_lane_right, object_uid_2=uid_road) # Actors uid_car_a = "0" # (0, 75) uid_car_b = "1" # (22, 143) uid_car_other_a = "3" uid_car_other_b = "4" uid_van = "5" uid_car_other_c = "6" uid_car_other_d = "7" uid_car_other_e = "8" # Actions # Driving straight before lane change uid_action_drive_straight_1 = vcd.add_action( name="DriveStraight1", semantic_type="DriveStraight", frame_value=[ (0, 31) ]) # Approx. at frame 31, the ego vehicle starts changing lane vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_ego, action_uid=uid_action_drive_straight_1) vcd.add_relation_object_action(name="", semantic_type="isObjectOfAction", object_uid=uid_lane_left, action_uid=uid_action_drive_straight_1) uid_action_drive_straight_2 = vcd.add_action( name="DriveStraight2", semantic_type="DriveStraight", frame_value=vcd.get_element_frame_intervals( element_type=core.ElementType.object, uid=uid_car_a).get()) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_car_a, action_uid=uid_action_drive_straight_2) vcd.add_relation_object_action(name="", semantic_type="isObjectOfAction", object_uid=uid_lane_right, action_uid=uid_action_drive_straight_2) uid_action_drive_straight_3 = vcd.add_action( name="DriveStraight3", semantic_type="DriveStraight", frame_value=vcd.get_element_frame_intervals( element_type=core.ElementType.object, uid=uid_car_b).get()) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_car_b, action_uid=uid_action_drive_straight_3) vcd.add_relation_object_action(name="", semantic_type="isObjectOfAction", object_uid=uid_lane_right, action_uid=uid_action_drive_straight_3) # Lane changing (event and action) uid_action_lane_change = vcd.add_action(name="LaneChange1", semantic_type="LaneChange", frame_value=[(33, 75)]) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_ego, action_uid=uid_action_lane_change) #uid_event_pass = vcd.add_event(name="CarB_passes_EgoCar", semantic_type="Pass", frame_value=32) #vcd.add_relation_subject_object(name="", semantic_type="Causes", subject_type=core.ElementType.event, subject_uid=uid_event_pass, # object_type=core.ElementType.action, object_uid=uid_action_lane_change) uid_event_pass = vcd.add_event(name="Pass1", semantic_type="Pass", frame_value=32) vcd.add_relation_subject_object(name="", semantic_type="isSubjectOfEvent", subject_type=core.ElementType.object, subject_uid=uid_car_b, object_type=core.ElementType.event, object_uid=uid_event_pass) vcd.add_relation_subject_object(name="", semantic_type="isObjectOfEvent", subject_type=core.ElementType.object, subject_uid=uid_ego, object_type=core.ElementType.event, object_uid=uid_event_pass) vcd.add_relation_subject_object(name="", semantic_type="causes", subject_type=core.ElementType.event, subject_uid=uid_event_pass, object_type=core.ElementType.action, object_uid=uid_action_lane_change) # Driving straight after lane change uid_action_drive_straight_4 = vcd.add_action( name="DriveStraight1", semantic_type="DriveStraight", frame_value=[ (76, frame_num_last) ]) # Approx. at frame 31, the ego vehicle starts changing lane vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_ego, action_uid=uid_action_drive_straight_4) vcd.add_relation_object_action(name="", semantic_type="isObjectOfAction", object_uid=uid_lane_right, action_uid=uid_action_drive_straight_4) vcd.add_relation_action_action( name="", semantic_type="meets", action_uid_1=uid_action_lane_change, action_uid_2=uid_action_drive_straight_4, frame_value=75) # Store if not os.path.isfile('./etc/' + vcd_version_name + '_kitti_tracking_0003_actions.json'): vcd.save('./etc/' + vcd_version_name + '_kitti_tracking_0003_actions.json', validate=True)
def test_create_mesh_with_API(self): # 1.- Create a VCD instance vcd = core.VCD() # Mesh sample representation # # P0 L0 P1 L4 P4 # *--------*--------* # | | | # |L3 A0 |L1 A1 |L5 # | | | # *--------*--------* # P3 L2 P2 L6 P5 # # V0 [A0,A1] mesh1 = types.mesh("parkslot1") # Vertex # P0 p0 = types.point3d("Vertex", (25, 25, 0)) p0.add_attribute(types.text("T Shape", "PM_line_ending_type")) p0_id = mesh1.add_vertex(p0) # P1 p1 = types.point3d("Vertex", (26, 25, 0)) p1.add_attribute(types.text("I Shape", "PM_line_ending_type")) mesh1.add_vertex(p1) # P2 p2 = types.point3d("Vertex", (26, 26, 0)) p2.add_attribute(types.text("U Shape", "PM_line_ending_type")) mesh1.add_vertex(p2) # P3 p3 = types.point3d("Vertex", (25, 26, 0)) p3.add_attribute(types.text("C Shape", "PM_line_ending_type")) mesh1.add_vertex(p3) # P4 p4 = types.point3d("Vertex", (27, 25, 0)) p4.add_attribute(types.text("T Shape", "PM_line_ending_type")) mesh1.add_vertex(p4) # P5 p5 = types.point3d("Vertex", (27, 26, 0)) p5.add_attribute(types.text("I Shape", "PM_line_ending_type")) mesh1.add_vertex(p5) # Edges # L0 l0 = types.lineReference("Edge", [0, 1], types.ObjectDataType.point3d) l0.add_attribute(types.text("Single Solid", "PM_line_marking_type")) l0.add_attribute( types.text("White", "PM_lPM_line_colourine_marking_typ")) l0_id = mesh1.add_edge(l0) # L1 l1 = types.lineReference("Edge", [1, 2], types.ObjectDataType.point3d) l1.add_attribute(types.text("Double Solid", "PM_line_marking_type")) l1.add_attribute( types.text("Blue", "PM_lPM_line_colourine_marking_type")) l1_id = mesh1.add_edge(l1) # L2 l2 = types.lineReference("Edge", [2, 3], types.ObjectDataType.point3d) l2.add_attribute(types.text("Dashed", "PM_line_marking_type")) l2.add_attribute( types.text("Yellow", "PM_lPM_line_colourine_marking_type")) l2_id = mesh1.add_edge(l2) # L3 l3 = types.lineReference("Edge", [3, 0], types.ObjectDataType.point3d) l3.add_attribute(types.text("Cross", "PM_line_marking_type")) l3.add_attribute( types.text("Green", "PM_lPM_line_colourine_marking_type")) mesh1.add_edge(l3) # L4 l4 = types.lineReference("Edge", [1, 4], types.ObjectDataType.point3d) l4.add_attribute(types.text("Single Solid", "PM_line_marking_type")) l4.add_attribute( types.text("White", "PM_lPM_line_colourine_marking_type")) mesh1.add_edge(l4) # L5 l5 = types.lineReference("Edge", [4, 5], types.ObjectDataType.point3d) l5.add_attribute(types.text("Double Solid", "PM_line_marking_type")) l5.add_attribute( types.text("Blue", "PM_lPM_line_colourine_marking_type")) mesh1.add_edge(l5) # L6 l6 = types.lineReference("Edge", [5, 2], types.ObjectDataType.point3d) l6.add_attribute(types.text("Dashed", "PM_line_marking_type")) l6.add_attribute( types.text("Yellow", "PM_lPM_line_colourine_marking_type")) mesh1.add_edge(l6) # Areas # A0 a0 = types.areaReference("Slot", [0, 1, 2, 3], types.ObjectDataType.line_reference) a0.add_attribute(types.text("Fishbone", "PM_park_slot_type")) a0.add_attribute(types.text("Empty", "PM_park_slot_content")) mesh1.add_area(a0) a1 = types.areaReference("Slot", [4, 5, 6, 1], types.ObjectDataType.line_reference) a1.add_attribute(types.text("Fishbone", "PM_park_slot_type")) a1.add_attribute(types.text("Empty", "PM_park_slot_content")) mesh1.add_area(a1) mesh_id = vcd.add_object("mesh1", "mesh") vcd.add_object_data(mesh_id, mesh1) string_mesh = mesh1.get_mesh_geometry_as_string() self.assertEqual( string_mesh, "[[[25,25,0],[26,25,0],[26,26,0],[25,26,0],[27,25,0],[27,26,0]]," "[[0,1],[1,2],[2,3],[3,0],[1,4],[4,5],[5,2]],[[0,1,2,3],[4,5,6,1]]]" ) if not os.path.isfile('./etc/test_mesh.json'): vcd.save('./etc/test_mesh.json', True)
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
def test_action_frame_interval_modification(self): vcd = core.VCD() # Basic modification of element-level information, including frame-intervals uid1 = vcd.add_action('Drinking_5', 'distraction/Drinking', [(5, 10), (15, 20)]) fis = vcd.get_element_frame_intervals(core.ElementType.action, uid1).get_dict() self.assertDictEqual(fis[0], {'frame_start': 5, 'frame_end': 10}) self.assertDictEqual(fis[1], {'frame_start': 15, 'frame_end': 20}) # Usual "just-one-frame" update for online operation: internally updates frame interval using FUSION (UNION) vcd.add_action('Drinking_5', 'distraction/Drinking', 21, uid1) # default SetMode is union fis = vcd.get_element_frame_intervals(core.ElementType.action, uid1).get_dict() self.assertDictEqual(fis[0], {'frame_start': 5, 'frame_end': 10}) self.assertDictEqual(fis[1], {'frame_start': 15, 'frame_end': 21}) # Entire modification with potential removal and extension vcd.add_action('Drinking_5', 'distraction/Drinking', [(5, 11), (17, 20)], uid1, set_mode=core.SetMode.replace) # adding 11, and deleting 15, 16, and 21 fis = vcd.get_element_frame_intervals(core.ElementType.action, uid1).get_dict() self.assertDictEqual(fis[0], {'frame_start': 5, 'frame_end': 11}) self.assertDictEqual(fis[1], {'frame_start': 17, 'frame_end': 20}) # Complex modification of element_data level information vcd.add_action_data(uid1, types.text('label', 'manual'), [(5, 5), (11, 11), (20, 20)]) vcd.add_action_data(uid1, types.text('label', 'auto'), [(11, 11)]) # this is an update, we want to modify # part of the action_data, without the need to substitute it entirely. This function can alse be used to # increase element's range self.assertEqual(vcd.get_action_data(uid1, 'label', 5)['val'], 'manual') self.assertEqual(vcd.get_action_data(uid1, 'label', 11)['val'], 'auto') self.assertEqual(vcd.get_action_data(uid1, 'label', 20)['val'], 'manual') fis = vcd.get_element_frame_intervals(core.ElementType.action, uid1).get_dict() self.assertDictEqual(fis[0], {'frame_start': 5, 'frame_end': 11}) self.assertDictEqual(fis[1], {'frame_start': 17, 'frame_end': 20}) # element should not be modified so far # If element-data is defined BEYOND the element limits -> Element is automatically extended vcd.add_action_data(uid1, types.text('label', 'manual'), [(5, 25)]) for i in range(5, 26): self.assertEqual(vcd.get_action_data(uid1, 'label', i)['val'], 'manual') fis = vcd.get_element_frame_intervals(core.ElementType.action, uid1).get_dict() self.assertDictEqual(fis[0], {'frame_start': 5, 'frame_end': 25}) # Note: any further modification of Action also modifies (e.g. removes) any action_data vcd.add_action('Drinking_5', 'distraction/Drinking', [(5, 11), (15, 19)], uid1, set_mode=core.SetMode.replace) # removing frames 20 and 21, and also from 12 to 14 fis = vcd.get_element_frame_intervals(core.ElementType.action, uid1).get_dict() self.assertDictEqual(fis[0], {'frame_start': 5, 'frame_end': 11}) self.assertDictEqual(fis[1], {'frame_start': 15, 'frame_end': 19}) self.assertEqual(vcd.get_action_data(uid1, 'label', 20), None) # Action data can also be "modified", which means fully substituted vcd.add_action_data(uid1, types.text('label', 'auto'), [(7, 26), (28, 28)], set_mode=core.SetMode.replace) # this will remove 5, 6 and add 26 and 28 fis_ad = vcd.get_action_data_frame_intervals(uid1, 'label').get_dict() self.assertDictEqual(fis_ad[0], {'frame_start': 7, 'frame_end': 26}) self.assertDictEqual(fis_ad[1], {'frame_start': 28, 'frame_end': 28}) # The action should not be removed because an inner action-data is removed fis = vcd.get_element_frame_intervals(core.ElementType.action, uid1).get_dict() self.assertDictEqual(fis[0], {'frame_start': 5, 'frame_end': 26}) self.assertDictEqual(fis[1], {'frame_start': 28, 'frame_end': 28}) # Move completely the frame intervals of an element shift = 100 vcd.add_action('Drinking_5', 'distraction/Drinking', [(5 + shift, 26 + shift), (28 + shift, 28 + shift)], uid1, set_mode=core.SetMode.replace) res = vcd.get_action_data(uid1, 'label', 5) self.assertEqual(res, None)
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)
def test_actions(self): # 1.- Create a VCD instance vcd_a = core.VCD() vcd_b = core.VCD() vcd_c = core.VCD() # 2.- Add ontology vcd_a.add_ontology(ontology_name="http://vcd.vicomtech.org/ontology/automotive") vcd_b.add_ontology(ontology_name="http://vcd.vicomtech.org/ontology/automotive") vcd_c.add_ontology(ontology_name="http://vcd.vicomtech.org/ontology/automotive") # 3.- Add some objects uid_pedestrian1 = vcd_a.add_object(name="", semantic_type="Pedestrian", frame_value=None, ont_uid=0) # therefore its uri is "http://vcd.vicomtech.org/ontology/automotive/#Pedestrian" uid_car1 = vcd_a.add_object(name="", semantic_type="Car", frame_value=None, ont_uid=0) uid_pedestrian1 = vcd_b.add_object(name="", semantic_type="Pedestrian", frame_value=None,ont_uid=0) uid_car1 = vcd_b.add_object(name="", semantic_type="Car", frame_value=None, ont_uid=0) uid_pedestrian1 = vcd_c.add_object(name="", semantic_type="Pedestrian", frame_value=None,ont_uid=0) uid_car1 = vcd_c.add_object(name="", semantic_type="Car", frame_value=None, ont_uid=0) # 4.- Add (intransitive) Actions # Option a) Add (intransitive) Actions as Object attributes # Pro: simple, quick code, less bytes in JSON # Con: No explicit Relation, lack of extensibility, only valid for simple subject-predicates vcd_a.add_object_data(uid=uid_pedestrian1, object_data=types.text(name="action", val="Walking")) vcd_a.add_object_data(uid=uid_car1, object_data=types.text(name="action", val="Parked")) # Option b) Add (intransitive) Actions as Actions and use Relations to link to Objects # Pro: Action as element with entity, can add action_data, link to other Objects or complex Relations # Con: long to write, occupy more bytes in JSON, more difficult to parse uid_action1 = vcd_b.add_action(name="", semantic_type="Walking", frame_value=None, ont_uid=0) uid_rel1 = vcd_b.add_relation(name="", semantic_type="performsAction", ont_uid=0) vcd_b.add_rdf(relation_uid=uid_rel1, rdf_type=core.RDF.subject, element_uid=uid_pedestrian1, element_type=core.ElementType.object) vcd_b.add_rdf(relation_uid=uid_rel1, rdf_type=core.RDF.object, element_uid=uid_action1, element_type=core.ElementType.action) uid_action2 = vcd_b.add_action(name="", semantic_type="Parked", frame_value=None, ont_uid=0) uid_rel2 = vcd_b.add_relation(name="", semantic_type="performsAction", ont_uid=0) vcd_b.add_rdf(relation_uid=uid_rel2, rdf_type=core.RDF.subject, element_uid=uid_car1, element_type=core.ElementType.object) vcd_b.add_rdf(relation_uid=uid_rel2, rdf_type=core.RDF.object, element_uid=uid_action2, element_type=core.ElementType.action) # Option c) Add Actions as Actions, and use action_Data to point to subject Object # Pro: simple as option a # Con: sames as a uid_action1 = vcd_c.add_action(name="", semantic_type="Walking", frame_value=None, ont_uid=0) uid_action2 = vcd_c.add_action(name="", semantic_type="Parked", frame_value=None, ont_uid=0) vcd_c.add_action_data(uid=uid_action1, action_data=types.num(name="subject", val=uid_pedestrian1)) vcd_c.add_action_data(uid=uid_action2, action_data=types.num(name="subject", val=uid_car1)) if not os.path.isfile('./etc/test_actions_a.json'): vcd_a.save('./etc/test_actions_a.json') if not os.path.isfile('./etc/test_actions_b.json'): vcd_b.save('./etc/test_actions_b.json') if not os.path.isfile('./etc/test_actions_c.json'): vcd_c.save('./etc/test_actions_c.json')
def test_scene_KITTI_Tracking_0(self): sequence_number = 0 vcd_file_name = "./etc/in/vcd_420_kitti_tracking_" + str(sequence_number).zfill( 4) + ".json" vcd = core.VCD(vcd_file_name) # Natural language scene description: # In a city, being sunny, the ego-vehicle drives straight following a cyclist, and a van. The van, cyclist # and ego-vehicle turn right. The road is single lane, and there are parked cars at both sides of it. There # are some pedestrians walking along the footwalk. ''' 1) City is a Context 2) Sunny is a Context 3) Ego-vehicle is an Object 4) Cyclist is an Object 5) Van is an Object 6) Ego-vehicle isSubjectOfAction drives-straight 7) Ego-vehicle isSubjectOfAction following1 8) Cyclist isObjectOfAction following1 9) Cyclist isSubjectOfAction following2 10) Van isObjectOfAction following2 11) Van isObjectOfAction turn-right 12) Cyclist isObjectOfAction turn-right 13) Ego-vehicle isObjectOfAction turn-right 14) Road is an Object 15) Footwalk is an Object 16) Road hasAttribute single-lane 17) Cars are Objects (multiple Car is Object) 18) Cars performAction Parked 19) Pedestrians are Objects 20) Pedestrians isSubjectOfAction Walking 21) Footwalk isObjectOfAction Walking ''' # Let's add VCD entries following the order # Contexts (1-2) vcd.add_context(name="", semantic_type="City") vcd.add_context(name="", semantic_type="Sunny") # Ego-vehicle (3) uid_ego = vcd.add_object(name="Ego-vehicle", semantic_type="Car") # The objects already labeled are the pedestrians, cars, vans, etc. Inspecting the VCD we can see the uids # of the main actors # Cyclist, van (4-5), (17) and (19) uid_cyclist = 2 uid_van = 1 # Driving straight (6) uid_action_6 = vcd.add_action(name="", semantic_type="driving-straight", frame_value=[(0, 30), (41, 153)]) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_ego, action_uid=uid_action_6) # Ego-vehicle following Cyclist (7-8) uid_action_7 = vcd.add_action(name="", semantic_type="following") # , frame_value=[(0, 153)]) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_ego, action_uid=uid_action_7) vcd.add_relation_object_action(name="", semantic_type="isObjectOfAction", object_uid=uid_cyclist, action_uid=uid_action_7) # Cyclist following Van (9-10) uid_action_9 = vcd.add_action(name="", semantic_type="following") # , frame_value=[(0, 153)]) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_cyclist, action_uid=uid_action_9) vcd.add_relation_object_action(name="", semantic_type="isObjectOfAction", object_uid=uid_van, action_uid=uid_action_9) # Van Turn-right (11) uid_action_11 = vcd.add_action(name="", semantic_type="turning-right", frame_value=(31, 40)) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_van, action_uid=uid_action_11) # Cyclist Turn-right (12) uid_action_12 = vcd.add_action(name="", semantic_type="turning-right", frame_value=(58, 65)) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_cyclist, action_uid=uid_action_12) # Ego-vehicle Turn-right (13) uid_action_13 = vcd.add_action(name="", semantic_type="turning-right", frame_value=(76, 84)) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_ego, action_uid=uid_action_13) # Road object (14), footwalk (15) and road attribute (16) uid_road = vcd.add_object(name="", semantic_type="road") uid_footwalk = vcd.add_object(name="", semantic_type="footwalk") vcd.add_object_data(uid=uid_road, object_data=types.text(name="road-type", val="single-lane")) # Cars (and a van) are parked (18), pedestrians are walking (20) # NOTE: read frame_interval from object, so the action is bounded to such limits for uid_obj_aux, object_ in vcd.data['vcd']['objects'].items(): frame_intervals = object_['frame_intervals'] frame_value = utils.as_frame_intervals_array_tuples(frame_intervals) if object_['type'] == 'Car': uid_act_aux = vcd.add_action(name="", semantic_type="parked", frame_value=frame_value) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_obj_aux, action_uid=uid_act_aux) elif object_['type'] == 'Pedestrian': uid_act_aux = vcd.add_action(name="", semantic_type="walking", frame_value=frame_value) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_obj_aux, action_uid=uid_act_aux) vcd.add_relation_object_action(name="", semantic_type="isObjectOfAction", object_uid=uid_footwalk, action_uid=uid_act_aux) elif object_['type'] == "Van" and uid_obj_aux is not uid_van: uid_act_aux = vcd.add_action(name="", semantic_type="parked", frame_value=frame_value) vcd.add_relation_object_action(name="", semantic_type="isSubjectOfAction", object_uid=uid_obj_aux, action_uid=uid_act_aux) # Store frame 0 - static and dynamic if not os.path.isfile('./etc/test_kitti_tracking_0_frame_0_static-dynamic.json'): vcd.save_frame(frame_num=0, file_name='./etc/test_kitti_tracking_0_frame_0_static-dynamic.json', dynamic_only=False) # Same but dynamic only if not os.path.isfile('./etc/test_kitti_tracking_0_frame_0_dynamic.json'): vcd.save_frame(frame_num=0, file_name='./etc/test_kitti_tracking_0_frame_0_dynamic.json', dynamic_only=True) # Store if not os.path.isfile('./etc/test_kitti_tracking_0_actions.json'): vcd.save('./etc/test_kitti_tracking_0_actions.json', False)
# Add annotation data and calibrated sensor data. for frame_num in range(0, my_scene['nbr_samples']): for annotation_token in current_sample['anns']: annotation = nusc.get('sample_annotation', annotation_token) instance_token = annotation['instance_token'] instance = nusc.get('instance', instance_token) category_token = instance['category_token'] category = nusc.get('category', category_token) attribute_token = annotation['attribute_tokens'] if len(attribute_token) > 0: attribute = nusc.get('attribute', attribute_token[0]) vcd.add_object_data(objects_uids[instance['token']], types.text('attribute', attribute['name']), (frame_num, frame_num)) visibility_token = annotation['visibility_token'] visibility = nusc.get('visibility', visibility_token) vcd.add_object_data( objects_uids[instance['token']], types.point3d('translation', tuple(annotation['translation'])), (frame_num, frame_num)) vcd.add_object_data(objects_uids[instance['token']], types.vec('size', tuple(annotation['size'])), (frame_num, frame_num)) vcd.add_object_data( objects_uids[instance['token']], types.vec('rotation', tuple(annotation['rotation'])),
def add_annotations(self, vcd: core.VCD, annotations, validations, ontology_uid: int): # Loop over all annotation levels to add the elements present in # annotation vector for level_code, level_type in zip(self._annotation_levels, self._annotation_types): level_idx = int(level_code[0]) level_name = level_code[1] level_type_idx = int(level_type[0]) level_type_name = level_type[1] assert (level_idx == level_type_idx) assert (len(self._level_labels) > 0) level_labels = self._level_labels[level_idx] for label_idx, label_name in level_labels.items(): # Do not save NaN and Empty annotations if label_idx == 100 or label_idx == 99: continue annotations = np.array(annotations) validations = np.array(validations) # Compute frame number of all occurrences of label_idx f_list = np.where(annotations[:, level_idx] == label_idx)[0] v_list = validations[f_list, level_idx] #From frames with lable_idx, select frames with validation 0, 1 and 2 v_list_0 = f_list[np.where(v_list == 0)] v_list_1 = f_list[np.where(v_list == 1)] v_list_2 = f_list[np.where(v_list == 2)] #If there are not annotated frames, then all validations are 0 (unchanged) if len(f_list) == 0: v_list_0 = validations[f_list, level_idx] # Make intervals of frames f_interv = [] f_interv = list(self.interval_extract(f_list)) #Make intervals of validation v_0_intervals = list(self.interval_extract(v_list_0)) v_1_intervals = list(self.interval_extract(v_list_1)) v_2_intervals = list(self.interval_extract(v_list_2)) # ## Add the elements # Add an action if level_type_name == 'action': action_type = level_name + '/' + label_name if len(f_interv) > 0: el_uid = vcd.add_action("", semantic_type=action_type, frame_value=f_interv, ont_uid=ontology_uid) # Add how the annotation was done if len(v_0_intervals) > 0: #Intervals with validation 0 validation_data = types.text(name='annotated', val=annotate_dict[0]) vcd.add_action_data(uid=el_uid, action_data=validation_data, frame_value=v_0_intervals) if len(v_1_intervals) > 0: #Intervals with validation 1 validation_data = types.text(name='annotated', val=annotate_dict[1]) vcd.add_action_data(uid=el_uid, action_data=validation_data, frame_value=v_1_intervals) if len(v_2_intervals) > 0: #Intervals with validation 2 validation_data = types.text(name='annotated', val=annotate_dict[2]) vcd.add_action_data(uid=el_uid, action_data=validation_data, frame_value=v_2_intervals) # Add an object elif level_type_name == 'object': object_type = label_name if len(f_interv) > 0: el_uid = vcd.add_object("", semantic_type=object_type, frame_value=f_interv, ont_uid=ontology_uid) # Add how the annotation was done #Intervals with validation 0 validation_data = types.text(name='annotated', val=annotate_dict[0]) vcd.add_object_data(uid=el_uid, object_data=validation_data, frame_value=v_0_intervals) #Intervals with validation 1 validation_data = types.text(name='annotated', val=annotate_dict[1]) vcd.add_object_data(uid=el_uid, object_data=validation_data, frame_value=v_1_intervals) #Intervals with validation 2 validation_data = types.text(name='annotated', val=annotate_dict[2]) vcd.add_object_data(uid=el_uid, object_data=validation_data, frame_value=v_2_intervals) # Add stream properties elif level_type_name == 'stream_properties': # When a level is defined as stream_properties, the annotations # will always be considered as boolean, since TaTo only allows # the presence or absence of that property. # E.g. occlusion can only be True or False if len(f_interv) > 0: for i, frame_num in enumerate(f_list): stream = label_name if stream == "--": continue property_dict = { level_name: { 'val': True, 'annotated': annotate_dict[int(v_list[i])] } } vcd.add_stream_properties( stream_name=stream, stream_sync=types.StreamSync( frame_vcd=int(frame_num)), properties=property_dict) else: raise RuntimeError('Invalid group type: ' + level_type_name) return vcd