Skip to content

FiftyOne Computer Vision Tips and Tricks — Sept 16, 2022

Welcome to our weekly FiftyOne tips and tricks blog where we recap interesting questions and answers that have recently popped up on SlackGitHub, Stack Overflow, and Reddit.

Wait, what’s FiftyOne?

FiftyOne is an open source machine learning toolset that enables data science teams to improve the performance of their computer vision models by helping them curate high quality datasets, evaluate models, find mistakes, visualize embeddings, and get to production faster.

Get started with open source FiftyOne gif

Checking and filtering for valid annotations

Community Slack member Yicheng He asked,

“Is there a way to check for (and possibly filter) valid annotations when loading COCO-styled object detection data into FiftyOne? Some examples include checking if the bounding box annotation is non-empty and if the coordinates are valid.”

One approach is to write your own custom dataset importer that is able to perform whatever validation you need when loading labels into FiftyOne in the COCODetectionDataset format, rather than from one of our integrations. Alternatively, you could filter your dataset after the fact to perform this verification:

# Only omits None-valued samples
view = dataset.exists("ground_truth")

# Also omits samples with empty Detections([])
view = dataset.match(F("ground_truth.detections").length() > 0)

Learn more about writing your own custom dataset importer and filtering your dataset in the FiftyOne Docs.

Loading CVAT projects into FiftyOne

Stackoverflow member MosQuan asked,

“Can I load a previously created CVAT project from a server? If so, what arguments should I specify besides the CVAT project name?”

Yes, you can use the fiftyone.utils.cvat.import_annotations() method to import labels that are already in a CVAT project or task into a FiftyOne Dataset.

Note that in order to use fo.load_dataset(), the dataset needs to already exist in FiftyOne. You can initialize an empty dataset as shown below:

dataset = fo.Dataset("my-dataset-name")

Then, you can call import_annotations(), providing a project name and optionally a data_path and export_media=True to download all of the media from your project to a local directory as well as all of the labels in your project, then import them into the dataset you just created.

dataset = fo.Dataset("my-dataset-name")
fouc.import_annotations(
    dataset,
    project_name=project_name,
    data_path="/tmp/cvat_import",
    download_media=True,
)

If your media already exists on disk, then check out this example for how to provide a data_map mapping the CVAT filename to filepath of the media on the local disk.

Learn more about CVAT integration and the fiftyone.utils.cvat.import_annotations() function in the FiftyOne Docs.

Selecting multiple samples in the FiftyOne App

Community Slack member Nadav Ben-Haim asked,

“Is there a way to batch select lots of videos? In the FiftyOne App I am only able to click on the check box in the top left to select a video, but there doesn’t appear to be a select with some kind of drag & drop capability.”

Yes! You can use shift and ctrl to select ranges of samples in the grid view of the FiftyOne App. Click to select one sample, scroll down, hold shift and click another sample, then all samples in between those two will be selected.

Viewing field information at the frame level

Community Slack member Eric Ng asked,

“Is there a way to view the field information at the frame level? Currently when I add a field at the frame level it shows up in the FiftyOne Apps OTHER tab as frames.field_name, but doesn’t show the value.”

One way to see frame-level field values in the FiftyOne App is to open the JSON viewer by pressing j or clicking the {…} button in the menu at the bottom. If the value is stored as a Classification instance, it will be overlaid on the video itself like this:

Working with object-level embeddings

Community Slack member Yashovardhan Chaturvedi asked,

“Can I store object-level embeddings on the Detection instances in my dataset?”

Yes! The FiftyOne Brain component has support for using object-level embeddings for various purposes.

To learn more about FiftyOne Brain and an object embeddings example, check out the FiftyOne Docs.

What’s Next?