How to change the color of the background of an image?

There are built in functions for this. Remove background

RemoveBackground[img]

enter image description here

Replace the background with a different color:

RemoveAlphaChannel[RemoveBackground[img], Green]

enter image description here

That works because removal of background is done with help of setting the alpha channel with mask:

AlphaChannel[RemoveBackground[img]]

enter image description here


img = ExampleData[{"TestImage", "House"}];

edge = ImageMultiply[EdgeDetect[ImageSubtract[#3, #] & @@ ColorSeparate[img], 4, 0.04],
    Image[SparseArray[{{i_, j_} /; Min[i, j] <= 100 -> 1}, ImageDimensions[img]]]]

binary = Binarize[ImageMultiply[ImageSubtract[#3, #] & @@ ColorSeparate[img],
    Image[SparseArray[{{i_, j_} /; Min[i, j] <= 100 -> 1}, ImageDimensions[img]]]], 0.12]

sky = Nest[ImageAdd[ImageFilter[Min, ImageFilter[Max, #, 1], 1], edge] &,
           ImageFilter[Min, ImageAdd[binary, edge], 1], 2]

ImageAdd[
   ImageMultiply[ImageApply[{#[[2]], #[[3]], #[[1]]} &, img], #],
   ImageMultiply[img, ColorNegate[#]]] & /@ {sky, sky - edge}

$\hspace{1.5cm}$


Here is how I would do it:

Get the Image:

img = ExampleData[{"TestImage", "House"}];

Use RegionBinarize to get a mask, and then close up the holes:

backgroundMask = ColorNegate[FillingTransform[Closing[RegionBinarize[img, ColorNegate @ Binarize @ img, 0.25], 5]]];

Choose the color to be targetted based on what occurs in the mask:

backgroundColor = RGBColor[Median[DeleteCases[Flatten[ImageData[backgroundMask img], 1], {0., 0., 0.}]]];

Make the replacement through the whole image:

colorReplacedImg = ColorReplace[img, backgroundColor -> Red];

Arithmetic so the replacement is only kept inside the mask:

resultImg = colorReplacedImg backgroundMask + ColorNegate[backgroundMask] img

Very dramatic and maybe unsettling sunset created with ColorReplace