Changing color of an object in an image
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 /.
ComponentMeasurements[isolateSphere[x], {"Centroid","BoundingDiskRadius"}]),
{PlotRange -> Thread[{1, #}], ImageSize -> #} &@ImageDimensions@x]
getAreaToChange[x_Image] := ImageMultiply[i, ColorNegate@makeMask[x]]
shiftColors[x_Image] := Image[ImageData[getAreaToChange[x]] /.
p: {r_, g_, b_} /; r > .3 :> RotateLeft[p, 1]]
finishIt[x_Image] := ImageAdd[ImageMultiply[x, makeMask[x]], ColorConvert[shiftColors[x], "RGB"]]
{#, getReds@#, isolateSphere@#, makeMask@#, getAreaToChange@#, shiftColors@#, finishIt@#} &
@Import["http://i.stack.imgur.com/Qr7Tx.jpg"]
Comparing side to side:
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["http://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}]
A one-liner:
i = Import["http://i.stack.imgur.com/Qr7Tx.jpg"];
Image[ImageData[i] /. {r_, g_, b_} /; r > g && r > b -> {b, g, r}]