How to ask Mathematica to imitate Andy Warhol's pop-art painting?
Let's do it Andy's way
So you are Andy. Nice to meet you. And you never got those hands on a computer. It doesn't matter, I will show you!
First you need to go to Marilyn's place. Don't worry, JF isn't there right now. Ask her for a nice photograph and the negatives.
i = ImageCrop@Import@"http://i.stack.imgur.com/W8hV5.png"
Outstanding picture, good work!
Now please, ask the lab to make a fully saturated neg. Yeah, they'll know how. Let me ask a cab for you, you're too high.
ib = ImageResize[Binarize[i, .55], {440,439}]
Ok, now it's your artistic moment. What? Too drunk? I don't care. Just go and paint some stupid doodles all over that pictures. Use your crayons, don't drink the paint.
cr = Import/@ ("http://i.stack.imgur.com/" <> # <> ".png" & /@ {"lnMTz", "8W9Mf", "CD2c9", "E041Z"})
Five minutes! Is that all you can do? OMG! You'll never ever get to be recognized. What a lazy artist you are!
No! Don't go to sleep yet. Wait. You're the artist. What should I do with these shi..mmering red blots?
I'll clip them, so nobody is going to see how you spoiled those beautiful pictures. Leave those Campbell's cans alone and give me the scissors.
chV = ChanVeseBinarize[#, "TargetColor" -> {Gray, Red}] & /@ cr;
Row[Framed /@ chV]
Hey! Andy, I need to make a phone call. Don't touch anything. Get your hands off those paint buckets. You're going to ... too late.
cs = RandomSample[ColorData[22, "ColorList"], 4];
chVcol = MapThread[ColorReplace[#1, {Black -> #2, White -> Black}] &, {chV, cs}]
Ok. so now we have a few silly painted "what should we call them". I hope you are happy now. All that work turned garbage and Marilyn will go mad. Yes! do whatever you want with them. Just leave me alone and tell me where you stock the beer. Collage?, yes, whatever you want I said.
if = Fold[ImageAdd[ImageMultiply[#1, ColorNegate@Binarize@#2], #2] &, chVcol];
ImageMultiply[if, ib]
Let's go to the MoMA, you're late again!
Alright, instead of separating the picture by graylevels, I tried to get more involved with component detections. I noticed the original painting has a different color for hair, face, mouth, eyes, and clothes. I tried my best to replicate this.
i = ImageCrop[Import["http://s2.hubimg.com/u/4262573_f520.jpg"]];
id = ImageDimensions[i];
back := Image[RandomColor[], ImageSize -> id];
bw = ChanVeseBinarize[i, Binarize[GradientFilter[i, 1], .05]] //
ColorNegate;
ib = ColorConvert[
RemoveAlphaChannel[
RemoveBackground[i, {"Background", {"Uniform", 0.1}}],
Darker[Gray, 1]], "Grayscale"];
noback = DeleteSmallComponents[ChanVeseBinarize[ib, EdgeDetect[ib]]];
face = Round[FindFaces[bw]][[1]];
facemask =
Rasterize[
Style[Show[{SetAlphaChannel[bw, 0],
Graphics[{Black, Disk[Mean[face], (Mean[face]/2)*{1, 1.4}]},
Background -> Transparent]}], Antialiasing -> False]];
facemask = SetAlphaChannel[facemask, facemask // ColorNegate];
facemaskc :=
ColorReplace[facemask,
Black -> RandomColor[Hue[_, _, RandomReal[{.6, 1}]]]];
mouth = ImageTake[
DeleteSmallComponents[
RemoveAlphaChannel[
RemoveBackground[
ImagePad[ImageTrim[bw, face], {{0, 0}, {0, 10}}, Black]],
White] // ColorNegate] // ColorNegate, {11, -1}];
mouth = ImagePad[
RemoveAlphaChannel[
ColorConvert[
SetAlphaChannel[mouth,
ColorNegate[
Dilation[Closing[ColorNegate[mouth], 30],
DiskMatrix[{2, 5}]]]], "RGB"],
Black], {{face[[1, 1]], id[[1]] - face[[2, 1]]}, {face[[1, 2]],
id[[2]] - face[[2, 2]]}}, White];
mouthc :=
ColorReplace[
SetAlphaChannel[mouth, Binarize[mouth, .9999] // ColorNegate],
Black -> RandomColor[]];
Rasterize[
Overlay[{noback,
SetAlphaChannel[Binarize[facemask], Binarize[facemask]]}]];
ImageAdd[#, DeleteSmallComponents[# // ColorNegate]] &[%];
eyesNose =
DeleteSmallComponents[Opening[%, 2] // ColorNegate] // ColorNegate;
lines = ImageLines[EdgeDetect[eyesNose], MaxFeatures -> 1][[1]];
eyes = SelectComponents[ColorNegate[eyesNose], "Centroid",
Abs[#[[2]] - Mean[lines[[All, 2]]]] < 20 &] // ColorNegate;
eyes = ImageTake[
ImagePad[
RemoveAlphaChannel[
ColorConvert[
SetAlphaChannel[eyes,
ColorNegate[
Dilation[Closing[ColorNegate[eyes], 10],
DiskMatrix[{2, 7}]]]], "RGB"], Black], {{0, 0}, {7, 0}},
White], {8, -1}];
eyesc := ColorReplace[
SetAlphaChannel[eyes, Binarize[eyes] // ColorNegate],
Black -> RandomColor[]];
SetAlphaChannel[ColorConvert[noback, "RGB"], noback];
hair = ImageTake[%, id[[2]] - face[[1, 2]] + 1];
torso = ImageTake[%%, -face[[1, 2]] + 1];
hairTorso :=
ImageAssemble[
Map[ColorReplace[#,
White -> RandomColor[]] &, {{hair}, {torso}}, {2}]];
composition :=
Rasterize[
Overlay[{back,
ImageCompose[hairTorso, ImageCompose[facemaskc, ImageCompose[eyesc,
ImageCompose[mouthc,
SetAlphaChannel[
ColorReplace[bw,
Black -> RandomColor[Hue[_, _, RandomReal[{.05, .5}]]]],
bw // ColorNegate]]]]]}]]
GraphicsGrid[Partition[Table[composition, {8}], 4], ImageSize -> 800]
I'm quite pleased with the result, but the code got kind of long and I'm sure it could be optimiesd.
Making use of the "Posterization"
option in ImageEffect
:
img = Import@"http://i.stack.imgur.com/yNEqN.png";
awImage := ColorReplace[#, Thread[DominantColors[#] -> RandomColor[4]]] &
[ImageEffect[img, {"Posterization", 2}]]
GraphicsGrid[Partition[Table[awImage, {8}], 4]]