Images¶

Most Computer Vision applications in 3LC include at least one image column. Use ImageSchema and pick a mode via its sample_type kwarg.

Schema¶

All four modes serialize to the same wire format — a URL string pointing at an image file. What varies is what the column accepts on write and returns on read.

Schema

Input data

Storage

Sample view

ImageSchema() (default sample_type="pil_png")

PIL.Image

Saved as PNG bulk data files

PIL.Image loaded back

ImageSchema(sample_type="pil_jpeg")

PIL.Image

Saved as JPEG bulk data files

PIL.Image loaded back

ImageSchema(sample_type="pil_webp")

PIL.Image

Saved as WEBP bulk data files

PIL.Image loaded back

ImageSchema(sample_type=None)

URL strings (paths to existing files)

Stored inline as-is

str (no conversion)

The three PIL-writing variants differ only in the encoding used when externalizing in-memory PIL images to disk; reading is format-agnostic (PIL sniffs the format from the bytes), so any PIL-decoding variant can read files written by any other.

Important

The sample_type variant is an encoder, not a re-encoder.

The variant’s format (PNG / JPEG / WEBP) only kicks in when a PIL.Image is being saved to disk for the first time — i.e. it was constructed in memory and has no backing file. In every other case, the variant is bypassed:

  • A PIL.Image loaded from disk (carrying a filename or _tlc_url attribute) is referenced verbatim. Its original file stays on disk untouched, regardless of the column’s declared format. An ImageSchema(sample_type="pil_jpeg") column does not re-encode a backed .png to .jpeg.

  • A EncodedSample (pre-encoded image bytes plus an explicit extension) is written verbatim. The column’s format does not apply.

  • Raw bytes are written verbatim. They get the column’s file extension on disk, but no decode/re-encode happens — use EncodedSample if extension mismatch matters.

  • A URL string passes through unchanged.

In short: pick a variant for what you want newly-authored PIL images to be encoded as. Existing images on disk are referenced as-is.

Saving PIL Images¶

When you have PIL Image objects (e.g., from a data pipeline or augmentation), use the default ImageSchema. The TableWriter saves each image as a file and stores a URL reference in the row:

import tlc
from PIL import Image

writer = tlc.TableWriter(
    project_name="My Project",
    dataset_name="train",
    schema={"image": tlc.schemas.ImageSchema()},  # PNG by default
)
writer.add_row({"image": Image.open("photo.jpg")})
table = writer.finalize()

Referencing Existing Images¶

When your images already exist on disk and you just want to point to them, pass sample_type=None:

import tlc

table = tlc.Table.from_dict(
    data={"image": ["path/to/image0.png", "path/to/image1.png"]},
    schema={"image": tlc.schemas.ImageSchema(sample_type=None)},
)

This is the most common pattern for large datasets where images are already organized on disk. The Dashboard displays them directly — no copying or conversion needed.

Image Format Support

Since 3LC Tables store references to images, rather than the images themselves, any image format can be referenced in the Table. The Dashboard is however limited to displaying the formats supported by your web browser. In practice, this means that most common formats can be displayed. For a useful guideline, see the Wikipedia comparison of web browser image format support.

In addition to those supported by your web browser, 3LC supports on-the-fly transcoding of certain formats such that they can be visualized in the Dashboard. Currently, the following cases are supported:

  • TIFF: Single-frame TIFF images are transcoded to PNG format.

  • NumPy: Referenced .npy files are instantiated, and when the array is 2D or 3D with a third dimension of 1 (grayscale), 3 (RGB), or 4 (RGBA) channels, it is transcoded to PNG format.

Note that in all cases, the Schema must declare that the column contains image URLs for transcoding to work. For example, transcoding is not invoked for referenced files without the Image URL role.

Exif Orientation

Exif (exchangeable image file format) is a standard for storing metadata in images. In the Dashboard, images with Exif orientation tags are always visualized in the canonical orientation, meaning rotations/flips are applied such that the images are displayed upright.

Therefore, when storing annotation columns, it is important that these (and any other data such as image dimensions) are stored in the canonical orientation. For image dimensions, many commonly used methods like PIL.Image.size are not based on Exif data, and will not return dimensions in the canonical orientation for certain Exif orientations. To get image dimensions in the canonical orientation, you can use the helper tlc.helpers.ImageHelper.get_exif_image_dimensions() which we use internally.

As a further step it is possible to rotate/flip your images to the canonical orientation and remove the Exif orientation tag from the file. This removes all ambiguity about the orientation of the image, and can be done using PIL.ImageOps.exif_transpose().

Several importer methods create Tables with an image column, notably tlc.Table.from_image_folder(), tlc.Table.from_coco() and tlc.Table.from_yolo_url(). The free-form methods can also be used by declaring the image schema and providing the images as a list of URLs, like in the examples above.

Visualization¶

The Dashboard provides several ways to visualize image data.

Charts¶

To create an image chart, select the IMAGE column (click the column header), RightClick on the IMAGE column header, and select Create 2D Chart on the popup menu. Alternatively, you can press 2 after selecting the IMAGE column.

Viewing images in the Charts panel is useful when you want to visualize images from a single row, and is often visualized with an overlay of geometric labels or predictions, such as bounding boxes or keypoints.

Grid View¶

It is also possible to change the tabular view of the Rows panel and show the rows as a grid. This shows all of the images in a single grid, allowing you to view several at once.

Virtual Columns¶

While images are mostly used for creating charts alongside additional data, it can be useful to derive the string representation of the image as part of debugging where images are stored, why they are not being displayed or if they have aliases. Check the FAQ for how this can be used.