Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I think nearly all of us have at least once seen an image like this:

enter image description here

So I wondered whether it is possible to recreate this effect using Mathematica because it seems like it wouldn't need that many processing steps.

Any ideas?

http://hplussummit.com/images/wolfram.jpg this can be used as a source image.

share|improve this question
    
"because it seems like it wouldn't need that many processing steps." Not true in the case of the Barack Obama poster: dvxuser.com/V6/… –  blochwave Jul 23 at 18:21
1  
design.tutsplus.com/tutorials/… as well –  blochwave Jul 23 at 18:23
    
Did you try anything? ColorReplace and Colorize should be useful here. –  Karsten 7. Jul 23 at 18:24
2  
Colorize[image, ColorFunction -> cfunc] is probably what you want, although coming up with the appropriate cfunc is the trick. –  acl Jul 23 at 19:02
1  
@acl ColorFunction -> (Piecewise[{{Darker@Blue, # < 0.5}, {Red, # < 0.67}, {Darker@LightBlue, # < 0.75}, {LightYellow, True}}] &) –  Rahul Narain Jul 23 at 20:03

7 Answers 7

up vote 17 down vote accepted

Here's my attempt, using @RahulNarain ColorFunction with different colors:

obamaize[image_, text_] := 
 Module[{colored = 
  Colorize[image, 
   ColorFunction -> (Piecewise[{{RGBColor[{30, 60, 88}/255], # < 0.5},
   {RGBColor[{202,36, 40}/255], # < 0.67}, {RGBColor[{124, 151, 168}/255], # < 0.75}, 
   {RGBColor[{240, 232, 173}/255], True}}] &)], 
   dims = ImageDimensions[image]},
  ImagePad[
   ImageAssemble[{{colored}, {Rasterize[
   Style[text, 40, FontFamily -> "Arial Black", Bold, 
    RGBColor[{124, 151, 168}/255]], ImageSize -> dims[[2]], 
   Background -> RGBColor[{30, 60, 88}/255]]}}], 10, 
 RGBColor[{240, 232, 173}/255]]
]

And to test it:

obamaize[ExampleData[{"TestImage", "Lena"}], "LENA"]

enter image description here

obamaize[ExampleData[{"TestImage", "Girl2"}], "ARRGH"]

enter image description here

share|improve this answer
    
+1 - but why obama? he isn't that red, is he? –  eldo Jul 23 at 21:04
1  
+1!!! Add a bit of filtering to remove the noisy pixels? Colorize[GaussianFilter[image, 1.5]..., or a bilateral filter –  blochwave Jul 23 at 21:04
3  
@eldo - this is why en.wikipedia.org/wiki/Barack_Obama_%22Hope%22_poster, this is the inspiration for this type of image –  blochwave Jul 23 at 21:05
1  
@blochwave, kale: I find that running Colorize on TotalVariationFilter@Sharpen@image works pretty well. –  Rahul Narain Jul 23 at 21:34
    
Yeah I was about to suggest TV - PeronaMalikFilter is another possibility reference.wolfram.com/language/ref/PeronaMalikFilter.html –  blochwave Jul 23 at 21:40

A somewhat revised approach.

First define the colours and create column images from them. There are four block colours and one striped.

blue = {0.15, 0.23, 0.33};
red = {0.77, 0.16, 0.17};
paleblue = {0.50, 0.60, 0.63};
beige = {0.96, 0.90, 0.69};

cols = Image[Table[Transpose[{##}], {60}] ~Flatten~ 1] & /@
   {{blue}, {red}, {paleblue}, {paleblue, beige}, {beige}};

Now import the image and do some processing. I repeatedly apply a low pass transform and histogram equalisation, then afterwards do a quantisation. The aim is to split the image into 5 brightness regions which have reasonably smooth outlines and which are all about the same area (so that the final image contains all five colours in equal amounts).

i1 = Import["wolfram.jpg"] ~ColorConvert~ "Grayscale";
id = ImageDimensions[i1];

i2 = Nest[HistogramTransform@LowpassFilter[#, 1.5] &, i1, 10];
i3 = ImageApply[0.2 Floor[5 #] &, i2];

{i1, i2, i3} // GraphicsRow

enter image description here

Now I use Binarize to extract masks for the individual regions and create shader images from the colours.

masks = Table[Binarize[i3, {i, 1.01 i}], {i, 0.0, 0.8, 0.2}];

shaders = ImageResize[#, id] & /@ cols;

{masks, shaders} // GraphicsGrid

enter image description here

Finally combine the mask and shader images, and add a label and border:

i4 = Inner[ImageMultiply, masks, shaders, ImageAdd];

label = Rasterize[
   Style["WOLFRAM", 20, FontFamily -> "Arial", Bold, RGBColor@paleblue],
   ImageSize -> id[[1]], Background -> RGBColor@blue];

ImagePad[ImageAssemble[{{i4}, {label}}], 10, RGBColor@red]

enter image description here

share|improve this answer
1  
I think you got the colors reversed for the text & bg... great answer nevertheless! Now if only there was a way to fix that hatch from bleeding into the bg... :) –  rm -rf Jul 24 at 13:11
    
@rm-rf, oh - so I did. Thanks. –  Simon Woods Jul 24 at 13:15
    
+1 for choice of image! –  murray Jul 24 at 19:23

First off, here's @kale's excellent answer modified with a bilateral filter to smooth it a little:

kalesObamaize[image_, text_] := 
 Module[{colored = 
    Colorize[BilateralFilter[image, 2, 0.5], 
     ColorFunction -> (Piecewise[{{RGBColor[{30, 60, 88}/255], # < 
            0.5}, {RGBColor[{202, 36, 40}/255], # < 
            0.67}, {RGBColor[{124, 151, 168}/255], # < 
            0.75}, {LightYellow, True}}] &)], 
   dims = ImageDimensions[image]}, 
  ImagePad[ImageAssemble[{{colored}, {Rasterize[
       Style[text, 40, FontFamily -> "Arial Black", Bold, 
        RGBColor[{124, 151, 168}/255]], ImageSize -> dims[[2]], 
       Background -> RGBColor[{30, 60, 88}/255]]}}], 10, 
   RGBColor[0.94, 0.91, 0.68]]]
kalesObamaize[Import[
  "http://hplussummit.com/images/wolfram.jpg"], "WOLVERINE"]

enter image description here


Second, here's my attempt. The motivation for this is based more on the workflow used in e.g. Adobe Illustrator to vectorize the image, which is how the original example would have been done.

I've not played around with the colours that much (to match the question) so it can definitely be improved. Call it a work-in-progress, suggestions welcome!

Also, if anyone can help me tidy up the code that separates the image out into layers that would be great!

wolfram = 
  ImageAdjust[Import["http://hplussummit.com/images/wolfram.jpg"]];
(* it's this line I'm not sure about! *)
binlist = 
  Reverse[Transpose[{Range[0., 0.8, 0.2], Range[0.2, 1.0, 0.2]}]];
binarylist = MorphologicalBinarize[wolfram, #] & /@ binlist;
imglist = GaussianFilter[#, 1.5] & /@ binarylist

enter image description here

combinedimages = ImageAdjust[Fold[ImageAdd,
   ColorReplace[imglist[[5]], {Black -> Darker@LightBlue}],
   {
    ColorReplace[imglist[[4]], {Black -> Red}],
    ColorReplace[imglist[[3]], {Black -> Red}],
    ColorReplace[imglist[[2]], {Black -> Darker@Blue}]
    }]]

enter image description here

ImageMultiply[
 Colorize[imglist[[1]], 
  ColorRules -> {Black -> LightYellow}], combinedimages]

enter image description here

share|improve this answer
    
One of the things is getting the colours to be vibrant - adding like this with ImageAdd needs transparency in the layers instead of white areas. –  blochwave Jul 23 at 20:44

This is a followup to @Simon Woods' answer and @rm -rf's comment

Now if only there was a way to fix that hatch from bleeding into the bg...

There is!

Let's create a face mask:

i = Import["wolfram.jpg"];
face = FindFaces[i][[1]];
facemask = 
 Graphics[{White, 
   Circle[Mean[face], (Mean[face] - face[[1]])*{.8, 1.2}]},
  Background -> Black, 
  ImageSize -> ImageDimensions[i], 
  PlotRange -> {0, #} & /@ Reverse[ImageDimensions[i]], 
  PlotRangePadding -> 0, Frame -> True, FrameStyle -> Opacity[0]]

Now we only need to modify the existing masks:

cutoff = DeleteSmallComponents[
   ImageSubtract[masks[[4]], ChanVeseBinarize[i, facemask]], 50];
masks[[4]] = ImageSubtract[masks[[4]], cutoff];
masks[[3]] = ImageAdd[masks[[3]], cutoff];

And produce the poster without the bleeding hatch in the background:

i4 = Inner[ImageMultiply, masks, shaders, ImageAdd];

label = Rasterize[
   Style["WOLFRAM", 20, FontFamily -> "Arial", Bold, 
    RGBColor@paleblue], ImageSize -> id[[1]], 
   Background -> RGBColor@blue];

ImagePad[ImageAssemble[{{i4}, {label}}], 10, RGBColor@red]

Mathematica graphics

However, I can't figure out why setting the Background color of the label does not work for me.


And here is an alternative approach, thanks to @Pickett:

i = Import["wolfram.jpg"];
bg = Binarize[RemoveBackground@i, 0.01];
colorbg = 
  Graphics[{RGBColor@paleblue, Rectangle[{-1, -1}, {0, 1}], 
    RGBColor@red, Rectangle[{0, -1}, {1, 1}]}, 
   Method -> {"ShrinkWrap" -> True}, 
   ImageSize -> ImageDimensions[i]];
i5 = ImageAdd[ImageMultiply[i4, bg], 
  ImageMultiply[ColorNegate@bg, colorbg]]

enter image description here

share|improve this answer
    
I tried my hands on this as well using MMA10's RemoveBackground. My code is here and it yields this result. You can add it as another alternative for fixing the problem if you like if you'd like. –  Pickett Jul 24 at 22:38
1  
@Pickett thanks, added –  shrx Jul 24 at 22:45

Here one approach:

im=Import["http://hplussummit.com/images/wolfram.jpg"];
mb=MorphologicalBinarize[im];
cb=ChanVeseBinarize[im];
ia1=ImageAdd[ColorReplace[im,ColorNegate[mb]->Darker@Blue],mb];
ia2=ImageAdd[ColorReplace[RemoveBackground[im],ColorNegate[cb]->Darker@Red],cb];
new1=ImageCompose[ImageCompose[Image@Graphics[{Darker@Blue,Rectangle[{0,0},{120,240}],Darker@Red,Rectangle[{120,0},{240,240}]},Background->None,Frame->False,PlotRangePadding->None,ImagePadding->None,ImageSize->240],ColorReplace[ia2,Binarize[ia2]->Orange]],
RemoveBackground[ia1]];

And a simple cleanup

ColorReplace[new1,Binarize[new1,0.95]->Darker@Blue]

Results in:
enter image description here
Some hair is still left without proper coloring, but more carefull adjustments of threshold values (here mainly default values were used) should solve this.

share|improve this answer

Using Rahul's idea and a bit of blurring:

img = Import["http://hplussummit.com/images/wolfram.jpg"];

bimg = Blur[img];
Colorize[
 bimg, ColorFunction -> (Piecewise[{{Darker@Blue, # < 0.5}, {Red, # < 
        0.67}, {Darker@LightBlue, # < 0.75}, {LightYellow, True}}] &)]

enter image description here

share|improve this answer
    
Very nice, very short, but the Blue is far too aggresive, and the Red could be a nuance darker. –  eldo Jul 23 at 20:38
3  
complaints should be addressed to @RahulNarain who came up with the colours. I'm just here to collect the votes :) –  acl Jul 23 at 20:45
    
@eldo the comment above was for you –  acl Jul 23 at 20:46
2  
Half the reason I didn't post an answer was so that I wouldn't have to bother making the colours look good! So please, do direct any and all complaints towards @acl. Indeed, that blue is terrible, acl, what on earth were you thinking?! –  Rahul Narain Jul 23 at 21:31
    
@RahulNarain truth be told, I did try improving them and got bored after 20s. So I understand you (but I'll hold on to those sweet upvotes anyway) –  acl Jul 23 at 21:33

Here a different approach, that mainly uses the build in ImageEffect "Posterization" and ColorReplace:
First the image is imported, the background removed and blured a bit:

img1=Blur@*RemoveBackground@Import["http://hplussummit.com/images/wolfram.jpg"];

Than the ImageEffect is applied:

img2=ImageEffect[img1,{"Posterization",2}];

The dominant colors are determined with

dColors=DominantColors[img2,4];

and will be replaced using the following rules:

colorReplaceRules={dColors[[1]]->RGBColor[{124,151,168}/255],dColors[[2]]->RGBColor[{240,232,173}/255],dColors[[3]]->RGBColor[{202,36,40}/255],dColors[[4]]->RGBColor[{30,60,88}/255]}

Now the colors can be replaced using

img3 = ColorReplace[img2, colorReplaceRules, 0.001];

With a new background created by

newBackground=With[{imgDim=ImageDimensions@img1},
 Image@Graphics[{RGBColor[{202,36,40}/255],Rectangle[{0,0},{Round[1/2*imgDim[[1]]],imgDim[[2]]}],RGBColor[{124,151,168}/255],Rectangle[{Round[1/2*imgDim[[1]]],0},{imgDim[[1]],imgDim[[2]]}]},Background->None,Frame->False,PlotRangePadding->None,ImagePadding->None,ImageSize->imgDim]];

the final image can be composed

ImageCompose[newBackground, img3]

enter image description here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.