def test_polygon2D(self): vcd = core.VCD() uid_obj1 = vcd.add_object('someName1', '#Some') # Add a polygon with SRF6DCC encoding (list of strings) poly1 = types.poly2d('poly1', (5, 5, 10, 5, 11, 6, 11, 8, 9, 10, 5, 10, 3, 8, 3, 6, 4, 5), types.Poly2DType.MODE_POLY2D_SRF6DCC, False) self.assertEqual(poly1.data['name'], "poly1") self.assertEqual(poly1.data['mode'], "MODE_POLY2D_SRF6DCC") self.assertEqual(poly1.data['closed'], False) vcd.add_object_data(uid_obj1, poly1) # Add a polygon with absolute coordinates (list of numbers) poly2 = types.poly2d('poly2', (5, 5, 10, 5, 11, 6, 11, 8, 9, 10, 5, 10, 3, 8, 3, 6, 4, 5), types.Poly2DType.MODE_POLY2D_ABSOLUTE, False) vcd.add_object_data(uid_obj1, poly2) if not os.path.isfile('./etc/vcd430_test_polygon2D.json'): vcd.save('./etc/vcd430_test_polygon2D.json', True) vcd_read = core.VCD('./etc/vcd430_test_polygon2D.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_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 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)
def test_contours(self): # 1.- Create a VCD instance vcd = core.VCD() # 1.- Create (color) image colors = [(125, 32, 64), (98, 12, 65), (12, 200, 190)] classes = ["class1", "class2", "class3"] classes_colors = dict(zip(classes, colors)) img = draw_basic_image(classes_colors) #cv.imshow('src_image', img) #cv.waitKey(1) # 2.- Split into channels for class_name, color in classes_colors.items(): seg = cv.inRange(img, color, color) # Get contours for this channel # Contours is a list of ndarray with shape (num_points, 1, 2) # Hierarchy is a ndarray with shape (1, num_contours, 4) contours, hierarchy = cv.findContours(seg, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) #print(hierarchy) uid = vcd.add_object('', class_name) for idx, contour in enumerate(contours): flatten_contour = contour.flatten() points = flatten_contour.tolist() hierarchy_list = hierarchy[0][idx].tolist() vcd.add_object_data(uid, types.poly2d('contour' + str(idx), # WARNING: In VCD 4.3.0, names MUST be unique points, types.Poly2DType.MODE_POLY2D_SRF6DCC, closed=True, hierarchy=hierarchy_list) ) if not os.path.isfile('./etc/vcd430_test_contours.json'): vcd.save('./etc/vcd430_test_contours.json', True) # 3.- Reconstruct the image from the VCD poly2d and hierarchies (using OpenCV) contours_dict = {} # A dictionary of contours. Each key is one class type, each value, a contours array hierarchy_dict = {} for object_key, object_val in vcd.data['vcd']['objects'].items(): # Assuming this is static (no frame info) contours_dict.setdefault(object_val['type'], []) hierarchy_dict.setdefault(object_val['type'], []) if 'object_data' in object_val: 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'] if mode == types.Poly2DType.MODE_POLY2D_SRF6DCC.name: vec = poly.getVecFromEncodedSRF6(int(val[0]), int(val[1]), int(val[2]), val[3]) #print(vec) 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)) contours_dict[object_val['type']].append(contour) hierarchy_dict[object_val['type']].append(hierarchy) img_out = np.zeros((640, 480, 3), np.uint8) for class_name, contours in contours_dict.items(): hierarchy_list = hierarchy_dict[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_out, contours, -1, color, hierarchy=hierarchy_array, thickness=-1) #cv.imshow('out_image', img_out) #cv.waitKey(0) # 4.- Check equals diff_val = np.sum(cv.absdiff(img, img_out)) self.assertEqual(diff_val, 0)
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 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,