Consider the following image:
How can I change all red colors in this image into (for example) blue.
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityHere'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}]
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:
CylindricalDecomposition[]
:)
$\endgroup$
Apr 26, 2012 at 21:28
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}]
ImageApply[RotateLeft, i]
have a same effect. :)
$\endgroup$
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["http://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.
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_] :=
Module[{mask =
Dilation[
DeleteSmallComponents[
ChanVeseBinarize[
KarhunenLoeveDecomposition[
ColorCombine /@ Permutations[ColorSeparate[img]]][[1, 2]]]],
9]}, ImageAdd[ImageSubtract[img, ImageMultiply[img, mask]],
ColorConvert[
ColorCombine[
Prepend[Rest[
ColorSeparate[ColorConvert[ImageMultiply[img, mask], "HSB"]]],
First[ColorSeparate[
ImageMultiply[
ConstantImage[color, ImageDimensions[img],
ColorSpace -> "HSB"], mask]]]], "HSB"], "RGB"]]]
Usage:
ChangeColor[img, #] & /@ RandomColor[5]
ChanVeseBinarize[]
looks to be the key component here.
$\endgroup$
Jun 28, 2016 at 13:54