Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
Exemplo n.º 4
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)
Exemplo n.º 5
0
    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,