NEWVectors or files. Pick a path.Start →
    Image Understanding
    6 min read
    Updated 2026-11-03

    Why Does My Logo Search Return the Wrong Brand on Transparent Images?

    A bare image.convert("RGB") throws away the alpha channel and keeps whatever color the file stored under it, so the model embeds a logo on a background you never chose. We flattened nine transparent logos onto black and onto white and queried a production SigLIP index: on black, Adidas returned Louis Vuitton at 0.941. Here is the measurement, the fix and how to check your own index.

    Ethan Steininger
    By , Founder & CEO, Mixpeek
    Logo Search
    Image Search
    Transparent PNG
    Image Embeddings
    SigLIP
    Pillow

    Why does my logo search return the wrong brand on transparent images?



    Your image model takes three color channels, so something has to replace the transparency before the image is embedded. In many pipelines that step is a bare image.convert("RGB"), which throws away the alpha channel and keeps whatever color the file stored under it. The model then embeds your logo on a background you never chose, and that background can matter more than the mark. To fix it, flatten every image onto a background you pick, in the same way on query and on ingest, then re-embed the transparent images you have already indexed.

    We found this on our own brand logo listing. Transparent PNG queries kept returning the same wrong brands at 0.965, while the same Nike logo on a white background returned Nike at 0.915.

    How much does the background change the result?



    We took nine transparent logos, flattened each one onto black and onto white, and sent both versions to the same production index of brand logos, built on SigLIP. The table shows the top result.

    LogoOn black: top resultScoreOn white: top resultScore
    AdidasLouis Vuitton0.941Adidas0.883
    MicrosoftThe North Face0.835Windows0.833
    NikeNike0.837Nike0.905
    AppleApple0.857Apple0.908
    AmazonAmazon0.885Amazon0.902
    GoogleGoogle0.882Google0.898
    SamsungSamsung0.890Samsung0.901
    ShellShell0.863Shell0.871
    NetflixNetflix0.870Netflix0.875


    Black got two of the nine wrong. White got eight right and returned Windows for Microsoft, which is the same company with a different mark. For the seven logos that matched on both backgrounds, white scored higher every time, by 0.005 to 0.068.

    Treat this as one run on one index with one model, on nine logos taken from 1000logos.net on November 3, 2026. It shows the direction and the size of the risk. Your numbers will differ.

    Why doesn't a score threshold catch this?



    The wrong Adidas match scored 0.941, higher than any correct match in the table. A cosine score says two embeddings are close, and two logos on the same large dark field share much of what the model sees. A cutoff high enough to reject that result would also reject every correct answer here, so fix the input before you tune the threshold.

    What color does a bare convert leave under the logo?



    It depends on the file, because the encoder decides what to store in fully transparent pixels. In these nine files, the corner pixel after convert("RGB") came out a muddy green, (71, 112, 76), in six and white in three. Other files store black. The same code therefore gives a different background per file, and you can't see that by opening the image in a viewer, which draws the transparency correctly.

    Check your own pipeline for this call. As of November 3, 2026, the preprocessing in open_clip and OpenAI's CLIP uses a bare convert("RGB"). The convert_to_rgb helper in Hugging Face Transformers composites onto white.

    How do I fix it?



    Flatten before you hand the image to the model:
    from PIL import Image, ImageStat
    
    def flatten_to_rgb(image):
        if image.mode not in ("RGBA", "LA", "PA") and "transparency" not in image.info:
            return image.convert("RGB")
        rgba = image.convert("RGBA")
        alpha = rgba.getchannel("A")
        brightness = ImageStat.Stat(rgba.convert("L"), mask=alpha).mean[0]
        fill = (0, 0, 0) if brightness >= 200 else (255, 255, 255)
        background = Image.new("RGB", rgba.size, fill)
        background.paste(rgba, mask=alpha)
        return background
    Call it on both paths, query and ingest, so both sides of the comparison see the same kind of image. An opaque image passes through with its pixels unchanged.

    How do I check whether my index is affected?



    1. Take a logo you know is in your index, as a transparent PNG. 2. Flatten one copy onto white and one onto black, and send each as a query. 3. If the top result changes, or the score moves by more than a few hundredths, your background is affecting retrieval. 4. Search your code for convert("RGB") on the path to the model.

    To list the files you have to re-embed, open each source image and test image.mode in ("RGBA", "LA", "PA") or "transparency" in image.info. Run the check on the source files, since the vectors keep no record of how they were made.

    How does Mixpeek handle transparent images?



    Mixpeek reads your files where they already live, in S3, GCS or any bucket, and turns what's in them into data your software can search, classify and moderate. Since November 3, 2026 every image model input flattens transparency this way, at query time and at ingest. Opaque images are unchanged.

    Documents ingested from transparent images before that date keep their old vectors until you re-extract them, because nothing rewrites stored vectors automatically. Mixpeek fits teams with a library of files to search. If you have a few hundred logos and a script, the function above is all you need. See the image extractor docs and pricing, or try the behavior on the brand logo listing.

    Frequently Asked Questions



    Which files does this affect?



    PNG, WebP and GIF can carry transparency. JPEG cannot, and frames decoded from video have no alpha channel, so neither is affected. Logos, product cutouts, icons and stickers are where it shows up most, because a large share of the image is transparent: 36% to 83% of the pixels in the nine logos above.

    What about a white logo on a transparent background?



    On a white background it disappears, and the model embeds a blank square. The function above measures the average brightness of the visible pixels and switches to black when it reaches 200 out of 255. Pick that number by looking at your own logos. Reversed marks and light wordmarks are the cases to test.

    Do I have to re-embed everything?



    Only the images that have transparency. Opaque images come out of the flatten step unchanged, so their vectors stay valid. Change the query path and the ingest path together, since a query flattened one way and a document flattened another are being compared across backgrounds.

    Does this happen with models other than SigLIP?



    Any model that takes RGB needs the transparency replaced first, so the question is what your preprocessing does. We measured SigLIP only. Run the check above on your own model before you assume it is safe or affected.

    Related



  1. Best reverse image search APIs
  2. Best visual search APIs
  3. How to find every ad that shows a product
  4. How much it costs to scan every video ad for logos and products
  5. Managed Mixpeek

    Put multimodal search to work

    Connect a bucket and Mixpeek runs the whole multimodal search pipeline for you: extraction, indexing, and search over your own objects. No models to wire up, nothing to host.

    Start with Managed
    MVS · bring your own

    Already have vectors?

    Keep your embeddings on your own cloud and run dense, sparse, and BM25 search directly on object storage. From $25/mo.

    Start with MVS

    Run this on your own data

    Point Mixpeek at the storage you already have and search your video, images, audio, and documents the way this guide describes. Build starts at $25/mo for up to 1M vectors.

    Search your own archiveRead Docs