# Changing color of an object in an image

Consider the following image:

How can I change all red colors in this image into (for example) blue.

Here's a version using Manipulate with a Locator to pick the colour to replace. There is also a tolerance control which determines how wide a range of hues to replace.

i=Import["https://i.stack.imgur.com/Qr7Tx.jpg"];

{h,s,b}=ColorSeparate[i,"HSB"];

colourchange[c_,from_,tol_,to_]:=Module[
{offset=Mod[c-from+0.5,1]-0.5},
If[Abs[offset]>tol,c,to]];

Manipulate[
ColorCombine[
{ImageApply[colourchange[#,ImageValue[h,pos],tol,ColorConvert[to,Hue][[1]]]&,h],s,b},
"HSB"],
{{to,Blue,"Change to"},Blue},
{{tol,-0.01,"Tolerance"},-0.01,0.5},
{{pos,{100,50}},Locator}]


• You could also add a polygon defined by other locators, to define the mask of impact... Apr 27, 2012 at 10:11
• Or use another locator as a brush Apr 27, 2012 at 10:48
• ...and I see a full image-processing graphical suit a la Photoshop implemented in Mathematica coming up soon... Apr 27, 2012 at 13:25
• @Simon Woods: nice approach! I like that one but still: see the two people on the left hand side of the ball? The went blue too. How one avoid that?
– John
Apr 27, 2012 at 18:44

I wanted to change only the color of the ball, leaving all other red objects untouched:

getReds[x_Image] := First@ColorSeparate[x, "Hue"]
isolateSphere[x_Image] := SelectComponents[Binarize[getReds[x], .9], Large]
makeMask[x_Image] := Image@Graphics[ Disk @@ (1 /.
{PlotRange -> Thread[{1, #}], ImageSize -> #} &@ImageDimensions@x]
shiftColors[x_Image] := Image[ImageData[getAreaToChange[x]] /.
p: {r_, g_, b_} /; r > .3 :> RotateLeft[p, 1]]

{#, getReds@#, isolateSphere@#, makeMask@#, getAreaToChange@#, shiftColors@#, finishIt@#} &
@Import["https://i.stack.imgur.com/Qr7Tx.jpg"]


Comparing side to side:

• Nice. What should one change to change the from and to colors? Or it only works for red and blue?
– Rojo
Apr 26, 2012 at 18:30
• +1 Nice. What would you have done if there were other instances of red in the picture that you did not want to alter? Apr 26, 2012 at 18:51
• @Rojo In fact Red is the most difficult case, since it is at the beginning and at the end of the Hue[] table. Try Graphics[Raster[Table[{h, s, 1}, {s, 0, 1, .01}, {h, 0, 1, .01}], ColorFunction -> Hue]] Apr 26, 2012 at 19:19
• @DavidCarraher That happens usually in image processing. Things like "reddish" and "the big thingie in the middle" are not as easy to program as CylindricalDecomposition[] :) Apr 26, 2012 at 21:28
– rm -rf
Apr 30, 2012 at 2:30

A one-liner:

i = Import["https://i.stack.imgur.com/Qr7Tx.jpg"];

Image[ImageData[i] /. {r_, g_, b_} /; r > g && r > b -> {b, g, r}]


• ImageApply[RotateLeft, i] have a same effect. :)
– yode
Jun 28, 2016 at 8:59

# First Method

If you just want to get different color of your ball,but don't want to name the color.I will recommend you this solution,which makes your life easier.In the meantime,it will change other place's color,not just the ball,like CSP's answer

img = Import["https://i.stack.imgur.com/Qr7Tx.jpg"];
Select[ColorCombine /@ Tuples[ColorSeparate[img], {3}],
ImageMeasurements[ColorDistance[ColorConvert[#, "Grayscale"], #],
"Total"] > 8000 &]


You get 20 different color ball by a line code.

# Second Method

If you just want to change your ball's color with a specified color and want maintain other place,like Dr. belisarius' answer,I make a custom function for you to do this

ChangeColor[img_, color_] :=
Dilation[
DeleteSmallComponents[
ChanVeseBinarize[
KarhunenLoeveDecomposition[
ColorCombine /@ Permutations[ColorSeparate[img]]][[1, 2]]]],
ColorConvert[
ColorCombine[
Prepend[Rest[
First[ColorSeparate[
ImageMultiply[
ConstantImage[color, ImageDimensions[img],
ColorSpace -> "HSB"], mask]]]], "HSB"], "RGB"]]]


Usage:

ChangeColor[img, #] & /@ RandomColor[5]


• It seems that the background change in the first solution, so I prefer the second one
– Wjx
Jun 28, 2016 at 9:07
• @Wjx Thanks. :)
– yode
Jun 28, 2016 at 9:10
• ChanVeseBinarize[] looks to be the key component here. Jun 28, 2016 at 13:54