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

I have an image, and I want to change the color of its background. For example, I want to change the color of the sky from blue to green (or just to pure-white, for simplicity). I have already get the edge of the house, i.e. imgEdges2 (my method of getting the imgEdges2 is very ad-hoc, and any advice for improvement is also welcome), how can I change the color of the sky?

Many thanks!

img = ExampleData[{"TestImage", "House"}]
imgEdges = EdgeDetect[img, 6.7, 0.11];
edgeData = ImageData@imgEdges;
edgeData[[246 ;; 256, All]] = 0;
edgeData[[80 ;; 120, 100 ;; 256]] = 0;
edgeData[[60 ;; 79, 90 ;; 154]] = 0;
edgeData[[50 ;; 59, 90 ;; 110]] = 0;
edgeData[[57 ;; 59, 111 ;; 115]] = 0;
imgEdges2 =Image@edgeData

• As a first suggestion, you might try something like: Manipulate[ColorReplace[#,First@DominantColors@#->rep,d]&@img,{d,0,.1}] This will more or less work if your background is a solid color and is dominant in the image. You can replace the First with a manual index after DominantColors if it's not dominant. The Manipulate lets you figure out the right thresholding. This doesn't do anything with edge detection or morphological binarization, though—there's certainly more to be done! This gets me this. – Ben Kalziqi Jul 27 '18 at 18:57

## 3 Answers

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}$

There are built in functions for this. Remove background

RemoveBackground[img]

Replace the background with a different color:

RemoveAlphaChannel[RemoveBackground[img], Green]

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

AlphaChannel[RemoveBackground[img]]

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