0

I have a labeling JSON file for images that looks like this (https://i.stack.imgur.com/Z6ZYn.png) Here's an example of an image(Multiple images of the same format exist) (https://i.stack.imgur.com/g6PML.jpg) I need help importing the above two files and opening them in fiftyone. The official documentation says to define the type when importing, but I don't even know the type, and when I try to import from_json or from_dir, I get an error. After consulting various sources, I've come up with the following code, but after running it, I don't think it will complete. It's taking too long...

import glob
import fiftyone as fo
import json

images_patt = "./data/*.jpg"

# Ex: load your custom label format
with open('./Waste_Plastics_result.json', 'r') as f:
    annotations = json.load(f)

# Create samples for your data
samples = []
for filepath in glob.glob(images_patt):
    sample = fo.Sample(filepath=filepath)

    # Convert detections to FiftyOne format
    detections = []
    for obj in annotations:
        width = obj["width"]
        height = obj["height"]
        #id = obj["id"]
        file_name = obj["file_name"]
        #image_id = obj["image_id"]
        category_id = obj["category_id"]
        metainfo_id = obj["metainfo_id"]
        # Bounding box coordinates should be relative values
        # in [0, 1] in the following format:
        # [top-left-x, top-left-y, width, height]
        bbox = obj["bbox"]
        #ignore = obj["ignore"]
        #iscrowd = obj["iscrowd"]
        area = obj["area"]

        detections.append(
            fo.Detection(width=width, height=height, file_name=file_name, category_id=category_id, metainfo_id=metainfo_id,
                         bbox=bbox, area=area)
        )

    # Store detections in a field name of your choice
    sample["ground_truth"] = fo.Detections(detections=detections)

    samples.append(sample)

# Create dataset
dataset = fo.Dataset.from_images_dir("./data")
dataset.add_samples(samples)

# FiftyOne session
session = fo.launch_app(dataset)
session.wait()  

Any help would be appreciated.

1 Answers1

0

Your code is currently loading every detection onto every sample which is why it is taking such a long time.

You'll want to first go through your annotations and group the objects by the corresponding image file, then only load the detections for a given image onto that sample:

import os
import glob
import fiftyone as fo
import json

images_patt = "./data/*.jpg"

# Ex: load your custom label format
with open('./Waste_Plastics_result.json', 'r') as f:
    annotations = json.load(f)

annotation_map = {}
for obj in annotations:
    fn = obj["file_name"]
    if fn not in annotation_map:
        annotation_map[fn] = []
    annotation_map[fn].append(obj)

# Create samples for your data
samples = []
for filename, objects in annotation_map.items():
    filepath = os.path.join("data", filename)
    sample = fo.Sample(filepath=filepath)

    # Convert detections to FiftyOne format
    detections = []
    for obj in objects:
        width = obj["width"]
        height = obj["height"]
        #id = obj["id"]
        file_name = obj["file_name"]
        #image_id = obj["image_id"]
        category_id = obj["category_id"]
        metainfo_id = obj["metainfo_id"]
        # Bounding box coordinates should be relative values
        # in [0, 1] in the following format:
        # [top-left-x, top-left-y, width, height]
        bbox = obj["bbox"]
        #ignore = obj["ignore"]
        #iscrowd = obj["iscrowd"]
        area = obj["area"]

        detections.append(
            fo.Detection(width=width, height=height, file_name=file_name, category_id=category_id, metainfo_id=metainfo_id,
                         bbox=bbox, area=area)
        )

    # Store detections in a field name of your choice
    sample["ground_truth"] = fo.Detections(detections=detections)

    samples.append(sample)

Also, you don't need to import from_images_dir if you're already defining the samples and their filepaths above.

# Create dataset
dataset = fo.Dataset("my_dataset")
dataset.add_samples(samples)

# FiftyOne session
session = fo.launch_app(dataset)
session.wait()  

Eric Hofesmann
  • 504
  • 2
  • 7