def convert_to_coco(self, input_data, output_dir, output_image_dir=None, is_dir=True):
        self._check_format(Format.COCO)
        ensure_dir(output_dir)
        output_file = os.path.join(output_dir, 'result.json')
        if output_image_dir is not None:
            ensure_dir(output_image_dir)
            output_image_dir_rel = output_image_dir
        else:
            output_image_dir = os.path.join(output_dir, 'images')
            os.makedirs(output_image_dir, exist_ok=True)
            output_image_dir_rel = 'images'
        images, categories, annotations = [], [], []
        category_name_to_id = {}
        data_key = self._data_keys[0]
        item_iterator = self.iter_from_dir(input_data) if is_dir else self.iter_from_json_file(input_data)
        for item_idx, item in enumerate(item_iterator):
            if not item['output']:
                logger.warning('No completions found for item #' + str(item_idx))
                continue
            image_path = item['input'][data_key]
            if not os.path.exists(image_path):
                try:
                    image_path, is_downloaded = download(image_path, output_image_dir, input_dir=input_data)
                    if is_downloaded:
                        image_path = os.path.join(output_image_dir_rel, os.path.basename(image_path))
                except:
                    logger.error('Unable to download {image_path}. The item {item} will be skipped'.format(
                        image_path=image_path, item=item
                    ), exc_info=True)
            labels = next(iter(item['output'].values()))
            if len(labels) == 0:
                logger.error('Empty bboxes.')
                continue
            width, height = labels[0]['original_width'], labels[0]['original_height']
            image_id = len(images)
            images.append({
                'width': width,
                'height': height,
                'id': image_id,
                'file_name': image_path
            })

            for label in labels:
                if 'rectanglelabels' in label:
                    category_name = label['rectanglelabels'][0]
                elif 'polygonlabels' in label:
                    category_name = label['polygonlabels'][0]
                else:
                    raise ValueError("Unknown label type")

                if category_name not in category_name_to_id:
                    category_id = len(categories)
                    category_name_to_id[category_name] = category_id
                    categories.append({
                        'id': category_id,
                        'name': category_name
                    })
                category_id = category_name_to_id[category_name]

                annotation_id = len(annotations)

                if "rectanglelabels" in label:
                    x = int(label['x'] / 100 * width)
                    y = int(label['y'] / 100 * height)
                    w = int(label['width'] / 100 * width)
                    h = int(label['height'] / 100 * height)

                    annotations.append({
                        'id': annotation_id,
                        'image_id': image_id,
                        'category_id': category_id,
                        'segmentation': [],
                        'bbox': [x, y, w, h],
                        'ignore': 0,
                        'iscrowd': 0,
                        'area': w * h
                    })
                elif "polygonlabels" in label:
                    points_abs = [(x / 100 * width, y / 100 * height) for x, y in label["points"]]
                    x, y = zip(*points_abs)

                    annotations.append({
                        'id': annotation_id,
                        'image_id': image_id,
                        'category_id': category_id,
                        'segmentation': [[coord for point in points_abs for coord in point]],
                        'bbox': get_polygon_bounding_box(x, y),
                        'ignore': 0,
                        'iscrowd': 0,
                        'area': get_polygon_area(x, y)
                    })
                else:
                    raise ValueError("Unknown label type")

        with io.open(output_file, mode='w', encoding='utf8') as fout:
            json.dump({
                'images': images,
                'categories': categories,
                'annotations': annotations,
                'info': {
                    'year': datetime.now().year,
                    'version': '1.0',
                    'contributor': 'Label Studio'
                }
            }, fout, indent=2)
    def convert_to_coco(self,
                        input_data,
                        output_dir,
                        output_image_dir=None,
                        is_dir=True):
        self._check_format(Format.COCO)
        ensure_dir(output_dir)
        output_file = os.path.join(output_dir, 'result.json')
        if output_image_dir is not None:
            ensure_dir(output_image_dir)
        else:
            output_image_dir = os.path.join(output_dir, 'images')
            os.makedirs(output_image_dir, exist_ok=True)
        images, categories, annotations = [], [], []
        category_name_to_id = {}
        data_key = self._data_keys[0]
        item_iterator = self.iter_from_dir(
            input_data) if is_dir else self.iter_from_json_file(input_data)
        for item_idx, item in enumerate(item_iterator):
            if not item['output']:
                logger.warning('No annotations found for item #' +
                               str(item_idx))
                continue
            image_path = item['input'][data_key]
            if not os.path.exists(image_path):
                try:
                    image_path = download(image_path,
                                          output_image_dir,
                                          project_dir=self.project_dir,
                                          return_relative_path=True,
                                          upload_dir=self.upload_dir)
                except:
                    logger.error(
                        'Unable to download {image_path}. The item {item} will be skipped'
                        .format(image_path=image_path, item=item),
                        exc_info=True)

            # concatentate results over all tag names
            labels = []
            for key in item['output']:
                labels += item['output'][key]

            if len(labels) == 0:
                logger.warning(f'Empty bboxes for {item["output"]}')
                continue

            first = True

            for label in labels:
                if 'rectanglelabels' in label:
                    category_name = label['rectanglelabels'][0]
                elif 'polygonlabels' in label:
                    category_name = label['polygonlabels'][0]
                elif 'labels' in label:
                    category_name = label['labels'][0]
                else:
                    logger.warning("Unknown label type: " + str(label))
                    continue

                # get image sizes
                if first:
                    width, height = label['original_width'], label[
                        'original_height']
                    image_id = len(images)
                    images.append({
                        'width': width,
                        'height': height,
                        'id': image_id,
                        'file_name': image_path
                    })
                    first = False

                if category_name not in category_name_to_id:
                    category_id = len(categories)
                    category_name_to_id[category_name] = category_id
                    categories.append({
                        'id': category_id,
                        'name': category_name
                    })
                category_id = category_name_to_id[category_name]

                annotation_id = len(annotations)

                if 'rectanglelabels' in label or 'labels' in label:
                    x = int(label['x'] / 100 * width)
                    y = int(label['y'] / 100 * height)
                    w = int(label['width'] / 100 * width)
                    h = int(label['height'] / 100 * height)

                    annotations.append({
                        'id': annotation_id,
                        'image_id': image_id,
                        'category_id': category_id,
                        'segmentation': [],
                        'bbox': [x, y, w, h],
                        'ignore': 0,
                        'iscrowd': 0,
                        'area': w * h,
                    })
                elif "polygonlabels" in label:
                    points_abs = [(x / 100 * width, y / 100 * height)
                                  for x, y in label["points"]]
                    x, y = zip(*points_abs)

                    annotations.append({
                        'id':
                        annotation_id,
                        'image_id':
                        image_id,
                        'category_id':
                        category_id,
                        'segmentation':
                        [[coord for point in points_abs for coord in point]],
                        'bbox':
                        get_polygon_bounding_box(x, y),
                        'ignore':
                        0,
                        'iscrowd':
                        0,
                        'area':
                        get_polygon_area(x, y)
                    })
                else:
                    raise ValueError("Unknown label type")

                if os.getenv('LABEL_STUDIO_FORCE_ANNOTATOR_EXPORT'):
                    annotations[-1].update(
                        {'annotator': item['completed_by'].get('email')})

        with io.open(output_file, mode='w', encoding='utf8') as fout:
            json.dump(
                {
                    'images': images,
                    'categories': categories,
                    'annotations': annotations,
                    'info': {
                        'year': datetime.now().year,
                        'version': '1.0',
                        'contributor': 'Label Studio'
                    }
                },
                fout,
                indent=2)