NEWVectors or files. Pick a path.Start →

    Visual Similarity Search

    Unified visual similarity search across both images and video frames. Query with a photo, screenshot, or frame to discover visually related content regardless of format, with MMR diversification to ensure variety in results.

    image
    video
    Multi-Tier
    from mixpeek import Mixpeek
    client = Mixpeek(api_key="YOUR_API_KEY", namespace="visual-assets")
    # 1. Buckets for images and for videos, and a multimodal_extractor collection over each
    images = client.buckets.create(
    bucket_name="image-assets",
    bucket_schema={
    "properties": {
    "image": {
    "type": "image",
    },
    },
    },
    )
    videos = client.buckets.create(
    bucket_name="video-assets",
    bucket_schema={
    "properties": {
    "video": {
    "type": "video",
    },
    },
    },
    )
    image_col = client.collections.create(
    collection_name="image_assets",
    source={"type": "bucket", "bucket_ids": [images["bucket_id"]]},
    feature_extractor={
    "feature_extractor_name": "multimodal_extractor",
    "version": "v1",
    },
    )
    video_col = client.collections.create(
    collection_name="video_assets",
    source={"type": "bucket", "bucket_ids": [videos["bucket_id"]]},
    feature_extractor={
    "feature_extractor_name": "multimodal_extractor",
    "version": "v1",
    },
    )
    # 2. Upload and process
    client.buckets.upload(
    images["bucket_id"],
    blobs=[{"property": "image", "type": "image", "data": "s3://your-bucket/images/hero-shot.jpg"}],
    )
    client.buckets.upload(
    videos["bucket_id"],
    blobs=[{"property": "video", "type": "video", "data": "s3://your-bucket/videos/campaign-cut.mp4"}],
    )
    client.collections.trigger(image_col["collection_id"])
    client.collections.trigger(video_col["collection_id"])
    # 3. One image query across both collections, diversified with MMR
    retriever = client.retrievers.create(
    retriever_name="visual-similarity",
    collection_identifiers=["image_assets", "video_assets"],
    input_schema={
    "image": {
    "type": "image",
    "required": True,
    },
    },
    stages=[
    {
    "stage_name": "search",
    "stage_id": "feature_search",
    "parameters": {
    "searches": [
    {
    "feature_uri": "mixpeek://multimodal_extractor@v1/vertex_multimodal_embedding",
    "query": {
    "input_mode": "content",
    "value": "{{INPUT.image}}",
    },
    "top_k": 50,
    },
    ],
    "final_top_k": 50,
    },
    },
    {
    "stage_name": "diversify",
    "stage_id": "mmr",
    "parameters": {
    "lambda": 0.7,
    "diversity_feature_uri": "mixpeek://multimodal_extractor@v1/vertex_multimodal_embedding",
    "top_k": 20,
    },
    },
    ],
    )
    # 4. Search
    results = client.retrievers.execute(
    retriever["retriever_id"],
    inputs={
    "image": "https://example.com/reference.jpg",
    },
    )
    for doc in results["documents"]:
    print(doc["document_id"], doc["score"])

    Feature Extractors

    Multimodal Extractor

    Unified embeddings for video, audio, image, and text: scene/silence chunking, Whisper transcription, thumbnails, and Gemini vision.

    Retriever Stages

    feature search

    Search and filter documents by vector similarity using feature embeddings

    filter

    mmr

    Reorder results using Maximal Marginal Relevance for diversity

    sort

    Frequently asked questions

    What is MMR and why should I use it?

    Maximal Marginal Relevance (MMR) balances relevance with diversity. It prevents results from being dominated by near-identical items, giving you a broader set of visually related content.

    Can I search across both images and video frames together?

    Yes. Multimodal embeddings share the same vector space, so a single query retrieves relevant results from both image collections and video scene collections simultaneously.

    How do I control the relevance vs diversity tradeoff?

    Adjust the MMR lambda parameter. Lambda=1.0 maximizes relevance (no diversification), lambda=0.0 maximizes diversity. A value of 0.7 works well for most use cases.