---
title: "Find a Video from an Image with Pixeltable"
date: "2026-07-20"
author: "Pierre Brunelle"
tags:
  - Image to Video Search
  - Video Finder
  - CLIP
  - PixelSearch
  - Similarity Search
  - Multimodal Search
  - Pixeltable
  - Computer Vision
description: "Image-to-video search without a custom vector stack: extract frames, index with CLIP, query by image or text. Build it or try PixelSearch."
url: "https://www.pixeltable.com/blog/find-video-from-image-pixelsearch"
---

# Find a Video from an Image with Pixeltable

**Summary:** Want an **AI video finder by image**—upload a still and jump to matching moments in a library? With Pixeltable you extract frames, add a CLIP embedding index, and call `.similarity()` with an image or a text string. No separate vector database required. Try the hosted experience at [PixelSearch](/pixelsearch), or build the pipeline below.

 
## What You Are Building

 
People search for this as *image to video search*, *find video from image*, *similar video finder*, and *AI video search*. The product capability is the same:

 

 - Index video content at the **frame** level

 - Query with an **image** (visual similarity) or **text** (cross-modal CLIP)

 - Return the parent video + timestamp / frame position

 

 
## Architecture in Four Steps

 

 - **Videos table** — store `pxt.Video` paths or URLs

 - **Frames view** — `frame_iterator` at a chosen FPS

 - **Embedding index** — CLIP on the frame column

 - **Query** — `frames.frame.similarity(image=...)` or `string=...`

 

 
## Working Example

 
```python

import pixeltable as pxt
from pixeltable.functions.huggingface import clip
from pixeltable.functions.video import frame_iterator

pxt.create_dir('video_finder', if_exists='ignore')

videos = pxt.create_table(
 'video_finder.videos',
 {'video': pxt.Video, 'title': pxt.String},
 if_exists='ignore',
)

frames = pxt.create_view(
 'video_finder.frames',
 videos,
 iterator=frame_iterator(video=videos.video, fps=1),
 if_exists='ignore',
)

frames.add_embedding_index(
 'frame',
 embedding=clip.using(model_id='openai/clip-vit-base-patch32'),
 if_exists='ignore',
)

# Insert your library (local paths and/or URLs)
videos.insert([
 {'video': '/data/library/beach.mp4', 'title': 'Beach walk'},
 {'video': 'https://example.com/demo.mp4', 'title': 'Remote demo'},
])

# --- Query by image: find matching video moments ---
# Parent columns (video, title) are inherited on the frames view.
# Use frame_idx / pos_msec for position in the source video (not pos).
query_image = '/data/queries/still.jpg'
sim = frames.frame.similarity(image=query_image)
results = (
 frames.order_by(sim, asc=False)
 .limit(12)
 .select(
 frames.video,
 frames.title,
 frames.frame_idx,
 frames.pos_msec,
 frames.frame,
 sim=sim,
 )
 .collect()
)

for row in results:
 print(
 row['title'],
 row['video'],
 'frame', row['frame_idx'],
 't_sec', row['pos_msec'] / 1000,
 'score', row['sim'],
 )
 
```

 
### Same Index, Text Query

 
```python

sim = frames.frame.similarity(string='red car on a busy street')
frames.order_by(sim, asc=False).limit(12).select(
 frames.video, frames.title, frames.frame_idx, frames.pos_msec, frames.frame, sim=sim
).collect()
 
```

 
## FPS Tradeoffs

 
| FPS | Best for | Cost |
| --- | --- | --- |
| 0.5 | Long archives, coarse recall | Fewer embeddings |
| 1 | General video finder | Balanced |
| 2+ | Fast action / short clips | More storage + compute |

 
Where frames and indexes live on disk: [VideoRAG storage guide](/blog/videorag-where-pixeltable-stores-indexes).

 
## Use PixelSearch Instead of Building

 
[PixelSearch](/pixelsearch) is a multimodal search UI on Pixeltable—upload media, search by image or text, hybrid signals. Deep dive: [Build your own multimodal search engine](/blog/pixelsearch-multimodal-search-engine). Hard-way comparison: [Video frame similarity search](/blog/video-similarity-search).

 
## Production Notes

 

 - **Incremental:** New videos only embed new frames—indexes stay in sync.

 - **Persistence:** Mount `PIXELTABLE_HOME` in Docker so the catalog survives restarts ([Docker guide](/blog/pixeltable-docker-volumes-pixeltable-home)).

 - **Serve:** Expose search via `FastAPIRouter` and `pxt service update` (Starter Kit patterns).

 

 
## FAQ

 
### Can I embed whole videos instead of frames?

 
Frame-level CLIP is the usual image→moment path. Video-native embedders (e.g. Twelve Labs) are available for segment-level search—see provider docs.

 
### Do I need Pinecone?

 
No. Pixeltable embedding indexes cover this workload for most libraries. Scale media to object storage when needed.

 
### Can this find a movie from a screenshot?

 
Technically similar retrieval works on any indexed frames. Respect copyright and only index content you have rights to search.

 
Class-based receipts for the same jobs: [ClipFinder](/blog/clipfinder-semantic-video-moment-search) for natural-language video moments, [SnapCatalog](/blog/snapcatalog-product-visual-search) for shop-the-look on a product image.

 
## See Also

 

 - [PixelSearch](/pixelsearch)

 - [Video frame similarity search](/blog/video-similarity-search)

 - [Multimodal search engine guide](/blog/pixelsearch-multimodal-search-engine)

 - [Where VideoRAG stores indexes](/blog/videorag-where-pixeltable-stores-indexes)

 - [Video intelligence pipeline](/blog/video-intelligence-pipeline-tutorial)

 - [Docs: Embedding indexes](https://docs.pixeltable.com/platform/embedding-indexes)