Killing the yellow halo in AI image compositing

Fourteen years with WordPress, and the current wave is everyone bolting AI onto their workflow. Most developers treat AI image compositing as a black box: throw an image at a model, take whatever comes back, then wonder why the result looks like a bad 90s Photoshop job with a yellow halo around every edge.

I thought I had seen every way a background replacement could break, and then I started building image pipelines that had to run at volume. Standard RGB alpha blending loses this fight for reasons that have nothing to do with your code. The fix is Lab color space, and it is worth understanding why.

Where RGB blending falls down

RGB alpha blending is the naive approach. It handles each channel on its own and computes weighted averages. Take a dark hair pixel (RGB 80, 60, 40) against a yellow wall (RGB 200, 180, 120): blend them at 50% and you get a muddy yellowish average. The mask can be pixel perfect and the color contamination from the old background is still baked into the edge.

RGB does not separate lightness from chroma, which is the whole problem. Blending in RGB changes the background and shifts the hue of the subject’s edges at the same time. The same tension shows up whenever you handle high-resolution image libraries and have to keep both performance and visual fidelity.

Why Lab color space handles this better

Move the operation into Lab (CIE 1976) instead. Lab keeps Lightness (L) apart from chromaticity (the a and b channels), so you can strip background contamination out of a pixel without touching the luminance that defines the object’s edge.

Vector deprojection in the ab plane tells you which part of a pixel’s color came from the background, and then you subtract that part. Nothing else about the pixel moves. I looked at a related class of perceptual glitch in fixing AI attention artifacts.

A three-tier mask strategy

Running AI image compositing off a single model is how you end up paged at 2:00 AM. User uploads are messy, so the pipeline needs somewhere to fall back to:

  • BiRefNet gives the best quality on complex hair and fine detail, using bilateral reference to hold on to high-resolution segmentation.
  • U²-Net through rembg is the fallback, and it tends to cope when BiRefNet struggles with small subjects or odd aspect ratios.
  • Traditional gradients are the safety net. If the GPU models hang, a Sobel or Laplacian filter with a guided filter keeps the site working.

Deprojecting the chroma vector

In a backend service this is usually Python. The deprojection that clears the yellow spill comes out like this:

import numpy as np
from skimage import color

def bbioon_remove_contamination(pixel_lab, bg_chroma_vector):
    # pixel_lab is (L, a, b)
    # bg_chroma_vector is (a_bg, b_bg)
    
    chroma = np.array([pixel_lab[1], pixel_lab[2]])
    bg_unit = bg_chroma_vector / np.linalg.norm(bg_chroma_vector)
    
    # Project current chroma onto background direction
    projection_mag = np.dot(chroma, bg_unit)
    
    if projection_mag > 0:
        # Subtract the component parallel to the background
        corrected_chroma = chroma - (projection_mag * bg_unit)
        return np.array([pixel_lab[0], corrected_chroma[0], corrected_chroma[1]])
    
    return pixel_lab

A separate path for cartoon art

Models trained on photographs tend to butcher line art. They see a black outline and decide it belongs to the background. My pipeline detects the case first, using Canny edge density and color simplicity thresholds, and when it reads as a cartoon it switches to a morphological closing routine that protects the dark outlines (luminance < 80) and pushes internal fill opacity to 255.

If this kind of AI image compositing work is eating your dev hours, I can take it off your plate. I have been wrestling with WordPress and custom API integrations since the 4.x days.

What actually ships

Production AI is an orchestration problem more than a model-selection problem. Lab space plus a three-tier fallback is what moves a compositing service from working on your laptop to surviving whatever users upload to it. If you are still blending in RGB, the edges are where it will show.

author avatar
Ahmad Wael
I'm a WordPress and WooCommerce developer with 15+ years of experience building custom e-commerce solutions and plugins. I specialize in PHP development, following WordPress coding standards to deliver clean, maintainable code. Currently, I'm exploring AI and e-commerce by building multi-agent systems and SaaS products that integrate technologies like Google Gemini API with WordPress platforms, approaching every project with a commitment to performance, security, and exceptional user experience.