Image annotation conversion from json format to YOLOv7 format

2.3k Views Asked by At

I am trying object detection in YOLOv7. As I have downloaded some public dataset for training, I got annotations in JSON format.

{
  "width": 4608,
  "height": 3456,
  "ispano": false,
  "objects": [
    {
      "key": "o5a4uvvzxdp6dod5uiexhl",
      "label": "regulatory--stop--g1",
      "bbox": {
        "xmin": 2496.375,
        "ymin": 2449.40625,
        "xmax": 2557.125,
        "ymax": 2548.125
      },
      "properties": {
        "barrier": false,
        "occluded": false,
        "out-of-frame": false,
        "exterior": false,
        "ambiguous": false,
        "included": false,
        "direction-or-information": false,
        "highway": false,
        "dummy": false
      }
    },
    {
      "key": "0f05h7prxavgpvxre68ml0",
      "label": "warning--wild-animals--g4",
      "bbox": {
        "xmin": 1957.5,
        "ymin": 2652.75,
        "xmax": 1978.875,
        "ymax": 2674.6875
      },
      "properties": {
        "barrier": false,
        "occluded": false,
        "out-of-frame": false,
        "exterior": false,
        "ambiguous": false,
        "included": false,
        "direction-or-information": false,
        "highway": false,
        "dummy": false
      }
    },
    {
      "key": "bd43wshq6ayz0jowsxgp23",
      "label": "other-sign",
      "bbox": {
        "xmin": 3211.875,
        "ymin": 2170.96875,
        "xmax": 3704.625,
        "ymax": 2261.25
      },
      "properties": {
        "barrier": false,
        "occluded": false,
        "out-of-frame": false,
        "exterior": false,
        "ambiguous": false,
        "included": false,
        "direction-or-information": true,
        "highway": false,
        "dummy": false
      }
    },
    {
      "key": "qzoqx6j766ovaw4x7zd6wi",
      "label": "regulatory--reversible-lanes--g2",
      "bbox": {
        "xmin": 2250.0,
        "ymin": 2481.46875,
        "xmax": 2311.875,
        "ymax": 2570.90625
      },
      "properties": {
        "barrier": false,
        "occluded": false,
        "out-of-frame": false,
        "exterior": false,
        "ambiguous": false,
        "included": false,
        "direction-or-information": false,
        "highway": false,
        "dummy": false
      }
    },
    {
      "key": "q0g8osx48bubijrosgfpda",
      "label": "warning--junction-with-a-side-road-perpendicular-left--g3",
      "bbox": {
        "xmin": 1990.125,
        "ymin": 2609.71875,
        "xmax": 2032.875,
        "ymax": 2651.90625
      },
      "properties": {
        "barrier": false,
        "occluded": false,
        "out-of-frame": false,
        "exterior": false,
        "ambiguous": false,
        "included": false,
        "direction-or-information": false,
        "highway": false,
        "dummy": false
      }
    },
    {
      "key": "do3wb1gql83q76xg9zmnkr",
      "label": "other-sign",
      "bbox": {
        "xmin": 1929.375,
        "ymin": 2662.03125,
        "xmax": 1944.0,
        "ymax": 2678.0625
      },
      "properties": {
        "barrier": false,
        "occluded": false,
        "out-of-frame": false,
        "exterior": false,
        "ambiguous": true,
        "included": false,
        "direction-or-information": false,
        "highway": false,
        "dummy": false
      }
    }
  ]
}

I need the annotations in YOLOv7 PyTorch version. I tried the conversion in roboflow, but as I uploaded the the files with the annotations, it was saying none of the images are annotated. Is there a way I can convert these annotations to YOLOv7 PyTorch version?

3

There are 3 best solutions below

1
On
import json

# Load the JSON file
with open('lables.json', 'r') as f:
  data = json.load(f)

# Extract the necessary information from the JSON file
images = data['images']
annotations = data['annotations']
categories = {c['id']: c['name'] for c in data['categories']}

# Iterate through the images
for image in images:
  # Get the file name for the image
  file_name = image['file_name']

  # Create an empty list of bounding boxes for category 1
  bounding_boxes = []

  # Iterate through the annotations
  for annotation in annotations:
    # If the annotation's image ID matches the current image's ID
    if annotation['image_id'] == image['id']:
      # Get the category ID for the annotation
      category_id = annotation['category_id']

      # If the category ID is 1
      if category_id == 1:
        # Get the bounding box coordinates
        x, y, w, h = annotation['bbox']

        # Convert the bounding box coordinates to normalized xywh
        x = x / image['width']
        y = y / image['height']
        w = w / image['width']
        h = h / image['height']

        # Create a string with the class ID, center x, center y, width, and height values, separated by spaces
        bounding_box_str = f"{category_id} {x + w/2} {y + h/2} {w} {h}"

        # Add the string to the list of bounding boxes
        bounding_boxes.append(bounding_box_str)

  # Create a new text file with the same name as the image file, but with a .txt extension
  with open(f"{file_name}.txt", 'w') as f:
    # Write the bounding boxes to the text file
    for bounding_box in bounding_boxes:
      f.write(f"{bounding_box}\n")

1)This script only convert boundary box annotations of .json ot yolov7 pytorch format 2) in (if category_id == 1) "1" is for person class only you can change according to your requirement

0
On

I developed a library in order to convert from LabelMe to Yolov7 format you can download it here:

https://github.com/Tlaloc-Es/labelme2yolov7segmentation

And you can see how I do the conversion in order to that you can develop your version.

0
On

I have used PyLabel, and it solved my problem. https://github.com/pylabel-project/pylabel

PyLabel is a Python package to help you prepare image datasets for computer vision models including PyTorch and YOLOv5. It can translate bounding box annotations between different formats. (For example, COCO to YOLO.) And it includes an AI-assisted labeling tool that runs in a Jupyter notebook.

You can do:

pip install pylabel

then:

import logging

from pylabel import importer

logging.getLogger().setLevel(logging.CRITICAL)

#Specify path to the coco.json file

path_to_annotations = r"C:\Users\Desktop\Object-Detection-Model\Dataset\Train\trainval.json"

#Specify the path to the images (if they are in a different folder than the annotations)

path_to_images = r"C:\Users\Desktop\Object-Detection-Model\Dataset\Train\images"

#Import the dataset into the pylable schema

dataset = importer.ImportCoco(path_to_annotations, path_to_images=path_to_images, name="Segmentation")

dataset.df.head(5)

for Yolov7 format use:

dataset.path_to_annotations = "data/yolo"

dataset.export.ExportToYoloV5(segmentation=True)[1]

for Yolov5 format use:

#run this code to convert from the json to text Yolov5 formate

dataset.path_to_annotations = r"C:\Users\Desktop\Object-Detection-Model\Dataset\Train\trainval.json"

dataset.export.ExportToYoloV5()[0]