Esempio n. 1
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)
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)
        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])
                        elif mode == types.Poly2DType.MODE_POLY2D_RS6FCC.name:
                            vec = poly.getVecFromEncodedRS6(
                                int(val[0]), int(val[1]), int(val[2]),
                                int(val[3]), int(val[4]), val[5])
                        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(