This documentation page is also available as an interactive notebook. You can launch the notebook in
Kaggle or Colab, or download it for use with an IDE or local Jupyter installation, by clicking one of the
above links.
Automatically identify and locate objects in images using YOLOX object
detection models.
Problem
You have images that need object detection—identifying what objects are
present and where they’re located. Manual labeling is slow and
expensive.
Solution
What’s in this recipe:
- Detect objects using YOLOX models (runs locally, no API needed)
- Get bounding boxes and class labels
- Filter detections by confidence threshold
You add a computed column that runs YOLOX on each image. Detection
happens automatically when you insert new images.
Setup
%pip install -qU pixeltable pixeltable-yolox
import pixeltable as pxt
from pixeltable.functions.yolox import yolox
Load images
# Create a fresh directory
pxt.drop_dir('detection_demo', force=True)
pxt.create_dir('detection_demo')
Connected to Pixeltable database at: postgresql+psycopg://postgres:@/pixeltable?host=/Users/pjlb/.pixeltable/pgdata
Created directory ‘detection_demo’.
<pixeltable.catalog.dir.Dir at 0x1413e9ed0>
# Create table for images
images = pxt.create_table('detection_demo.images', {'image': pxt.Image})
Created table ‘images’.
# Insert sample images (COCO dataset samples with common objects)
image_urls = [
'https://raw.githubusercontent.com/pixeltable/pixeltable/main/docs/resources/images/000000000036.jpg',
'https://raw.githubusercontent.com/pixeltable/pixeltable/main/docs/resources/images/000000000090.jpg',
'https://raw.githubusercontent.com/pixeltable/pixeltable/main/docs/resources/images/000000000106.jpg',
]
images.insert([{'image': url} for url in image_urls])
Inserting rows into `images`: 0 rows [00:00, ? rows/s]
Inserting rows into `images`: 3 rows [00:00, 523.85 rows/s]
Inserted 3 rows with 0 errors.
3 rows inserted, 6 values computed.
# View images
images.collect()
Run object detection
Add a computed column that runs YOLOX on each image:
# Run YOLOX object detection
# model_id options: yolox_nano, yolox_tiny, yolox_s, yolox_m, yolox_l, yolox_x
images.add_computed_column(
detections=yolox(images.image, model_id='yolox_m', threshold=0.5)
)
Added 3 column values with 0 errors.
3 rows updated, 3 values computed.
# View detection results
images.select(images.image, images.detections).collect()
Parse the detection output to get object counts and classes:
# Extract number of detections
@pxt.udf
def count_objects(detections: dict) -> int:
"""Count the number of detected objects."""
return len(detections.get('labels', []))
images.add_computed_column(object_count=count_objects(images.detections))
Added 3 column values with 0 errors.
3 rows updated, 6 values computed.
# Extract unique object classes
@pxt.udf
def get_classes(detections: dict) -> list:
"""Get list of detected object classes."""
return list(set(detections.get('labels', [])))
images.add_computed_column(object_classes=get_classes(images.detections))
Added 3 column values with 0 errors.
3 rows updated, 3 values computed.
# View summary
images.select(images.image, images.object_count, images.object_classes).collect()
Explanation
YOLOX model sizes:
Detection output format:
The detections dictionary contains:
labels: List of class names (e.g., “person”, “car”, “dog”)
boxes: Bounding box coordinates [x1, y1, x2, y2]
scores: Confidence scores (0-1)
Adjusting threshold:
- Higher threshold (0.7-0.9): Fewer detections, higher confidence
- Lower threshold (0.3-0.5): More detections, may include false
positives
See also