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"

Mathematica graphics

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

Mathematica graphics

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"})

Mathematica graphics

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]

Mathematica graphics

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

Mathematica graphics

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!

Mathematica graphics


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]

Mathematica graphics

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]]

Images