def read_annotation_xml(xml_filename, img_filename):
    info = ImageInfo.FromXML(xml_filename, img_filename)
    if len(info.panels) > 1:
        print('Warning!! Multiple Panels Detected')
    result = [chartinfo for chartinfo in info.panels]
    offsets = [(0, 0)]
    return result, offsets
Esempio n. 2
0
    def load_page(self, paginator, new_page, refresh=False):
        if new_page == self.current_page and not refresh:
            # page not changed ...
            return

        self.current_page = new_page

        page_size = len(self.thumbnails_images)

        current_elements = self.chart_image_list[self.current_page *
                                                 page_size:(self.current_page +
                                                            1) * page_size]

        for idx in range(page_size):
            row = int(idx / self.tb_grid_cols)
            col = idx % self.tb_grid_cols

            if idx < len(current_elements):
                # update image ...
                chart_path = current_elements[idx]
                current_img = cv2.imread(self.chart_dir + chart_path)
                current_img = cv2.cvtColor(current_img, cv2.COLOR_BGR2RGB)
                self.thumbnails_images[idx].set_image(current_img,
                                                      self.tb_width,
                                                      self.tb_height,
                                                      keep_aspect=True)

                # center new image
                corner_x = self.tb_outer_margin + self.tb_col_width * col
                corner_y = self.tb_outer_margin + self.tb_row_height * row
                self.center_image_in_box(self.thumbnails_images[idx], corner_x,
                                         corner_y, self.tb_width,
                                         self.tb_height)

                # find annotation path ...
                relative_dir, img_filename = os.path.split(chart_path)
                img_base, ext = os.path.splitext(img_filename)
                # output dir
                output_dir = self.annotation_dir + relative_dir
                annotation_filename = output_dir + "/" + img_base + ".xml"

                # default : No annotations ...
                if os.path.exists(annotation_filename):
                    # read the annotation ...
                    print(annotation_filename)
                    image_info = ImageInfo.FromXML(annotation_filename,
                                                   current_img)

                    status_ints = ImageInfo.GetAllStatuses(image_info)
                else:
                    status_ints = ImageInfo.GetAllStatuses(None)

                status = self.gen_status_image(status_ints, self.tb_width,
                                               self.tb_progress_h,
                                               self.tb_progress_border)
                self.thumbnails_status[idx].set_image(status, self.tb_width,
                                                      self.tb_progress_h)

                self.thumbnails_labels[idx].set_text(chart_path[1:])

                self.thumbnails_images[idx].visible = True
                self.thumbnails_status[idx].visible = True
                self.thumbnails_labels[idx].visible = True
            else:
                # special case for the last page ...
                self.thumbnails_images[idx].visible = False
                self.thumbnails_status[idx].visible = False
                self.thumbnails_labels[idx].visible = False

        msg = "Page {0:d} of {1:d} ({2:d} elements)".format(
            self.current_page + 1, self.paginator.total_pages,
            len(self.chart_image_list))
        self.lbl_page_descriptor.set_text(msg)

        if not refresh:
            self.selected_element = None
            self.update_selected_image(0)
def split_dir_annotations(in_img_dir, in_annot_dir, out_img_dir, out_annot_dir,
                          rel_path):
    input_dir = in_annot_dir + rel_path
    elements = os.listdir(input_dir)

    panels_per_type = {}
    for element in elements:
        element_path = input_dir + element

        if os.path.isdir(element_path):
            sub_dir_stats = split_dir_annotations(in_img_dir, in_annot_dir,
                                                  out_img_dir, out_annot_dir,
                                                  element_path + "/")

            # add stats
            for chart_type in sub_dir_stats:
                if chart_type in panels_per_type:
                    # already collected this type ...
                    panels_per_type[chart_type] += sub_dir_stats[chart_type]
                else:
                    # first of this type
                    panels_per_type[chart_type] = sub_dir_stats[chart_type]
        else:
            print("Processing: " + element_path)

            # load the corresponding image
            base, ext = os.path.splitext(element)
            img_path = in_img_dir + rel_path + base + ".jpg"
            current_img = cv2.imread(img_path)

            # load the annotation
            image_info = ImageInfo.FromXML(element_path, current_img)

            # For each panel ....
            for panel_idx, panel in enumerate(image_info.panels):
                type_str, orientation_str = panel.get_description()
                chart_type = type_str + "_" + orientation_str

                if chart_type in panels_per_type:
                    panels_per_type[chart_type] += 1
                else:
                    panels_per_type[chart_type] = 1

                # if the panel is non-chart, then skip
                if panel.type == ChartInfo.TypeNonChart:
                    continue

                # crop the panel from main image
                panel_img = image_info.get_panel_image(panel_idx)

                # Save panel image to output image directory
                os.makedirs(out_img_dir + "/" + chart_type + rel_path,
                            exist_ok=True)
                out_img_panel_path = out_img_dir + "/" + chart_type + rel_path + base + "_panel_" + str(
                    panel_idx + 1) + ".jpg"
                cv2.imwrite(out_img_panel_path, panel_img)

                # Create a new annotation structure ... only for that panel
                panel_annotation = ImageInfo.CreateDefault(panel_img)
                panel_annotation.panels[0] = panel

                # Save panel annotation to output image directory
                os.makedirs(out_annot_dir + "/" + chart_type + rel_path,
                            exist_ok=True)
                out_panel_annotation = out_annot_dir + "/" + chart_type + rel_path + base + "_panel_" + str(
                    panel_idx + 1) + ".xml"
                tempo_xml = panel_annotation.to_XML()
                with open(out_panel_annotation, "w") as out_annot_file:
                    out_annot_file.write(tempo_xml)

    return panels_per_type
    def __load_data(self, cache_all_annotations):
        # Load image list from dir ...
        self.img_list = ImageInfo.ListChartDirectory(self.img_dir, "")
        self.auto_check_stats = {
            "total_no_annotation": 0,
            "total_multi_panel": 0,
            "total_no_test": 0,
            "total_passed": 0,
            "total_failed": 0,
        }

        for idx, chart_path in enumerate(self.img_list):
            current_img = None

            # find annotation path ...
            relative_dir, img_filename = os.path.split(chart_path)

            img_base, ext = os.path.splitext(img_filename)
            # output dir
            output_dir = self.annotation_dir + relative_dir
            annotation_filename = output_dir + "/" + img_base + ".xml"

            if os.path.exists(annotation_filename):
                self.img_annotations.append(annotation_filename)
                self.total_annotation_files += 1

                image_info = ImageInfo.FromXML(annotation_filename,
                                               current_img)
                if len(image_info.panels) == 1:
                    # add to single panel index
                    self.all_single_panel.append(idx)

                    type_desc, orientation = image_info.panels[
                        0].get_description()
                    if orientation == "":
                        current_type = type_desc
                    else:
                        current_type = "{0:s} ({1:s})".format(
                            type_desc, orientation)
                    # if type_desc in ["non-chart"]:
                    #     print(annotation_filename)

                    status_ints = ImageInfo.GetAllStatuses(image_info)
                    self.img_statuses.append(status_ints)

                    if current_type in self.single_per_type:
                        self.single_per_type[current_type].append(
                            (idx, status_ints))
                    else:
                        self.single_per_type[current_type] = [(idx,
                                                               status_ints)]

                    if not "auto_check_passed" in image_info.panels[
                            0].properties:
                        self.auto_check_stats["total_no_test"] += 1
                    else:
                        if int(image_info.panels[0].
                               properties["auto_check_passed"]) > 0:
                            self.auto_check_stats["total_passed"] += 1
                        else:
                            self.auto_check_stats["total_failed"] += 1
                else:
                    # add to multi-panel index
                    self.all_multi_panel.append(idx)
                    # TODO: multi-panel case is not handled yet ...

                    self.img_statuses.append(None)
                    self.auto_check_stats["total_multi_panel"] += 1

                # keep or discard the current annotation ...
                if cache_all_annotations:
                    self.cache_annotations.append(image_info)
                else:
                    self.cache_annotations.append(None)
            else:
                self.img_annotations.append(None)
                self.cache_annotations.append(None)
                self.img_statuses.append(ImageInfo.GetNullStatuses())
                self.auto_check_stats["total_no_annotation"] += 1
Esempio n. 5
0
    def __init__(self, img_dir, annotation_dir, cache_all_annotations=False):

        self.img_dir = img_dir
        self.annotation_dir = annotation_dir

        # Load image list from dir ...
        self.img_list = ImageInfo.ListChartDirectory(img_dir, "")

        self.total_annotation_files = 0

        self.img_annotations = []
        self.cache_annotations = []
        self.img_statuses = []

        self.all_single_panel = []
        self.all_multi_panel = []
        self.single_per_type = {}

        for idx, chart_path in enumerate(self.img_list):
            current_img = None

            # find annotation path ...
            relative_dir, img_filename = os.path.split(chart_path)

            img_base, ext = os.path.splitext(img_filename)
            # output dir
            output_dir = self.annotation_dir + relative_dir
            annotation_filename = output_dir + "/" + img_base + ".xml"

            if os.path.exists(annotation_filename):
                self.img_annotations.append(annotation_filename)
                self.total_annotation_files += 1

                image_info = ImageInfo.FromXML(annotation_filename,
                                               current_img)
                if len(image_info.panels) == 1:
                    # add to single panel index
                    self.all_single_panel.append(idx)

                    type_desc, orientation = image_info.panels[
                        0].get_description()
                    if orientation == "":
                        current_type = type_desc
                    else:
                        current_type = "{0:s} ({1:s})".format(
                            type_desc, orientation)

                    status_ints = ImageInfo.GetAllStatuses(image_info)
                    self.img_statuses.append(status_ints)

                    if current_type in self.single_per_type:
                        self.single_per_type[current_type].append(
                            (idx, status_ints))
                    else:
                        self.single_per_type[current_type] = [(idx,
                                                               status_ints)]

                else:
                    # add to multi-panel index
                    self.all_multi_panel.append(idx)
                    # TODO: multi-panel case is not handled yet ...

                    self.img_statuses.append(None)
                # keep or discard the current annotation ...
                if cache_all_annotations:
                    self.cache_annotations.append(image_info)
                else:
                    self.cache_annotations.append(None)
            else:
                self.img_annotations.append(None)
                self.cache_annotations.append(None)
                self.img_statuses.append(ImageInfo.GetNullStatuses())
    def __init__(self, size, chart_dir, annotation_dir, relative_path,
                 parent_menu, admin_mode):
        BaseImageAnnotator.__init__(self,
                                    "Chart Ground Truth Annotation Interface",
                                    size)

        self.general_background = (20, 85, 50)
        self.text_color = (255, 255, 255)

        self.parent = parent_menu
        self.chart_dir = chart_dir
        self.annotation_dir = annotation_dir
        self.relative_path = relative_path
        self.admin_mode = admin_mode

        self.time_stats = TimeStats()
        self.in_menu_time_start = time.time()
        self.wait_mode = ChartImageAnnotator.WaitModeNone

        # find output path ...
        relative_dir, img_filename = os.path.split(self.relative_path)
        img_base, ext = os.path.splitext(img_filename)
        # output dir
        self.output_dir = self.annotation_dir + relative_dir
        self.annotation_filename = self.output_dir + "/" + img_base + ".xml"

        # first ... load image ....
        self.base_rgb_image = cv2.imread(self.chart_dir + self.relative_path)
        self.base_rgb_image = cv2.cvtColor(self.base_rgb_image,
                                           cv2.COLOR_BGR2RGB)
        # ... and cache the gray-scale version
        self.base_gray_image = np.zeros(self.base_rgb_image.shape,
                                        self.base_rgb_image.dtype)
        self.base_gray_image[:, :, 0] = cv2.cvtColor(self.base_rgb_image,
                                                     cv2.COLOR_RGB2GRAY)
        self.base_gray_image[:, :, 1] = self.base_gray_image[:, :, 0].copy()
        self.base_gray_image[:, :, 2] = self.base_gray_image[:, :, 0].copy()

        # load annotations for this image .... (if any)
        if os.path.exists(self.annotation_filename):
            # annotation found!
            self.image_info = ImageInfo.FromXML(self.annotation_filename,
                                                self.base_rgb_image)
        else:
            # create an empty annotation
            self.image_info = ImageInfo.CreateDefault(self.base_rgb_image)

        self.split_panel_operation = None
        self.tempo_panel_tree = None
        self.selected_panel = 0
        self.unsaved_changes = False

        self.elements.back_color = self.general_background

        self.label_title = None
        self.container_confirm_buttons = None
        self.lbl_confirm_message = None
        self.btn_confirm_cancel = None
        self.btn_confirm_accept = None

        self.container_panels_buttons = None
        self.lbl_panels_title = None
        self.btn_label_panels = None
        self.btn_panels_verify = None
        self.lbl_panels_current = None
        self.btn_panels_prev = None
        self.btn_panels_next = None

        self.container_annotation_buttons = None
        self.lbl_edit_title = None
        self.btn_edit_class = None
        self.btn_edit_text = None
        self.btn_edit_legend = None
        self.btn_edit_axis = None
        self.btn_edit_data = None

        self.btn_verify_class = None
        self.btn_verify_text = None
        self.btn_verify_legend = None
        self.btn_verify_axis = None
        self.btn_verify_data = None

        self.container_split_panels = None
        self.lbl_split_panel_title = None
        self.btn_split_panel_horizontal = None
        self.btn_split_panel_vertical = None
        self.btn_merge_panel = None
        self.btn_split_return = None

        self.container_classify_panels = None
        self.lbl_class_panel_title = None
        self.lbx_class_panel_class = None
        self.btn_class_panel_continue = None

        self.btn_save = None
        self.btn_auto_check = None
        self.btn_return = None

        # generate the interface!
        self.create_controllers()

        # get the view ...
        self.update_current_view(True)