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.
| Logo | On black: top result | Score | On white: top result | Score |
|---|---|---|---|---|
| Adidas | Louis Vuitton | 0.941 | Adidas | 0.883 |
| Microsoft | The North Face | 0.835 | Windows | 0.833 |
| Nike | Nike | 0.837 | Nike | 0.905 |
| Apple | Apple | 0.857 | Apple | 0.908 |
| Amazon | Amazon | 0.885 | Amazon | 0.902 |
| 0.882 | 0.898 | |||
| Samsung | Samsung | 0.890 | Samsung | 0.901 |
| Shell | Shell | 0.863 | Shell | 0.871 |
| Netflix | Netflix | 0.870 | Netflix | 0.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 backgroundHow 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.