# How to blend two photos in Mathematica?

The following two photographs forest and tiger were blended into one with screen blending mode in Photoshop. How to accomplish the same result in Mathematica?

Images:1 2

• Please post the images "separated" (upload three images) Sep 2, 2014 at 2:37
• The "screen" blending mode is equivalent to the negative of the "multiply" blending mode applied to the negatives of the images, so you can do ColorNegate[ImageMultiply[ColorNegate[forest], ColorNegate[tiger]]] and it should be identical to what Photoshop gives.
– user484
Sep 2, 2014 at 4:29
• Putterboy, please consider switching the Accept to Rahul's answer. Oct 11, 2014 at 17:03

Although I think belisarius's result is prettier your example image clearly has the background visible through the dark parts of the tiger image, and since you wrote that you want "the same result in Mathematica" I propose this as a starting point:

{img1, img2} = Import /@
{"http://i.stack.imgur.com/gPKY5.jpg",
"http://i.stack.imgur.com/G39md.jpg"};

img2a =
SetAlphaChannel[
img2,
img2 ~ColorSeparate~ "R" ~ImageAdjust~ {0.6, 1}
];

Show[{img1, img2a}]


• This method avoids the blown-out highlights of a simple ImageAdd operation.

• You can vary the parameters of ImageAdjust to tune the blending. You can also try other channels besides red, or a combination by using ColorConvert[img2, "Grayscale"].

• Ha! Your transparent-stripped got accepted! Sep 2, 2014 at 15:05
• @belisarius And two down-votes from people who didn't actually read the question and look at the example. :^) Sep 2, 2014 at 22:00
• OMG. That deserves retaliative upvoting . +1 in spite of the disservice to the tiger's onine community Sep 2, 2014 at 22:35
• @belisarius Thanks, but I prefer that people do not use votes in that manner. (Counter other votes, "retaliate," down-vote because a post is "too popular" etc.) IMO a vote should be determined by a post itself not the way others reacted to the post. Sep 2, 2014 at 22:41
• Ok, Now I'll have to downvote five answers of yours as compensative downvoting :) Sep 3, 2014 at 0:09
getBlacks[x_Image] := Binarize[x, .005]
isolateTiger[x_Image] := Erosion[getBlacks[x], 2]
getAreaToChange[tig_Image, fst_Image] := ImageMultiply[fst, Blur[ColorNegate@isolateTiger[tig], 30]]
GraphicsRow[{#, getBlacks@#, isolateTiger@#, getAreaToChange[##], addImages[##]} & @@ {tiger,forest}]


Edit

The following is more sophisticated, but the results are better (code partially stolen from here)

i = tiger;
b = DeleteSmallComponents@FillingTransform@ChanVeseBinarize[i, "TargetColor" -> Black];
skeleton = SkeletonTransform[b];
pruned = Pruning[skeleton, 1, 5];
GraphicsRow[{i, b, skeleton, pruned, mask, ib, f}]


• You could have used the images under the links in the question, resolution would be nicer. Sep 2, 2014 at 15:41
• @AlexeyBobrick They weren't posted when I wrote the answer Sep 2, 2014 at 15:42

ImageAdd does the job. Blend allows you to adjust the blending level.

ImageAdd[tiger, background]


I had originally posted this only as a comment, because it was not clear whether the OP wanted something that was exactly like Photoshop's screen blending mode, or whether he just wanted to composite the two images together in a nice way like @belisarius's answer. Now that the OP has clarified that a replication of Photoshop's behaviour is indeed desired, I must point out that the accepted answer is not exactly correct.

Photoshop:

Mr.Wizard's method:

You can see that they are not identical.

The screen blending mode, as documented by Adobe, combines two images according to the formula $c_{\text{out}} = 1 - (1-c_1)(1-c_2)$. To do this in Mathematica, we can use ImageApply:

ImageApply[1 - (1 - #1) (1 - #2) &, {forest, tiger}]


and the same approach would also work for any other blending mode whose formula you know. For the screen blending mode in particular, though, there's a much faster way:

ColorNegate[ImageMultiply[ColorNegate[forest], ColorNegate[tiger]]]


As verification, one can check the maximum difference in pixel values between this and the Photoshop result, via Max@ImageData@ImageDifference[..., ...]; it is only about $1.6\%$.

• Darn, I somehow overlooked the Screen Blend thing. +1 for the correct answer. Sep 11, 2014 at 14:41

Here's an approach based on wavelets

forest = Import["http://i.stack.imgur.com/gPKY5.jpg"];
tiger = Import["http://i.stack.imgur.com/G39md.jpg"];

swd = StationaryWaveletTransform[#, DaubechiesWavelet[8], 3] & /@ {forest, tiger};

forestVals = swd[[1]][{___, 0 | 1 | 2 | 3}, {"Values",
{"Image", "ImageFunction" -> Identity}}];

tigerVals = swd[[2]][{___, 0 | 1 | 2 | 3}, {"Values",
{"Image", "ImageFunction" -> Identity}}];

InverseWaveletTransform[DiscreteWaveletData[
{{0} -> blended[[1]],
{1} -> blended[[2]]}], DaubechiesWavelet[8]]


As you can see I have compressed and fused both images in one step - you can always add/remove different wavelet coefficients, use ImageMultiply on the parameters in ImageAdd, use a different wavelet transform or just a different wavelet family - it's up to you :)

• Wait, the wavelet transform is linear, so adding the wavelet coefficients is equivalent to just adding the pixel values. Indeed your result looks identical to @paw's answer using ImageAdd directly on the images.
– user484
Sep 3, 2014 at 0:39
• @RahulNarain Well, that's the classical algorithm - you can just google that and I am sure thousands of results will pop up. I have used the one I found in "Wavelet analysis and its applications, and active media technology" pt.1 (2004). Sadly, I have this book in my library, but not scanned.. If you want an explanation on how and why this algorithm works - you will have to wait (prepping for finals as we speak) Sep 3, 2014 at 11:50
• I don't understand how your reply addresses my comment. My point was that your method does exactly the same thing as ImageAdd[forest, tiger].
– user484
Sep 3, 2014 at 14:23
• @RahulNarain Because I wasn't trying to reply to your comment. I was just adding some info :D There's a big difference tho - I can fuse only the details, or the edges, or compress the image (lossy) or lossless, etc, etc Sep 3, 2014 at 15:15

This is actually not an answer but a simple review of the answers given above. Screen blending mode is equivalent to Black passing through, White halt, 50% gray half through. So a picture containing four distinct areas, namely transparent, black, 50% gray and white can be used to test the outcomes of the methods given above. The picture tbgw.png below contains an alpha channel, and picture bgw.jpg contains no alpha channel.

First, is the output from Photoshop's screen blending mode:

Second, result from Paw's method by using Mathematica's AddImage which refused to add pictures with different channel numbers. So bgw.jpg was used for the blending. And please note that the picture was lightened under the gray area. Obviously, the blending effect from AddImage is not screen instead it is lighten.

Third, result from Belisarius' method: It is a kind of masking rather than blending actually, but the outcome of the answer above is awesome.

Finally, result from Mr. Wizard's method: It is pretty close to the result from Photoshop. It is really a true screen blending method in Mathematica.

{img1, img2} = Import /@
{"http://i.stack.imgur.com/gPKY5.jpg",
"http://i.stack.imgur.com/rr9EN.png"};
img2a = SetAlphaChannel[img2, img2~ColorSeparate~"L" ];
Show[{img1, img2a}]


Again, clean, short and straight to the point, thank you so much Mr. Wizard.

• I'm glad you have found a method that works for you, but there are a few factual errors in this answer...
– user484
Sep 3, 2014 at 0:43
• Could you please point them out, I'm glad to know and discuss to make things clear and correct. Sep 3, 2014 at 5:56
• I've posted an answer explaining the main issue. Other factual errors: 1. The screen blending mode is not equivalent to "50% grey half through", because screen applied to two layers both 50% grey becomes lighter, specifically GrayLevel[0.75]. 2. @paw's method is not lighten (which is $c_{\text{out}}=\max(c_1,c_2)$) but add ($c_{\text{out}}=c_1+c_2$), also known as linear dodge in Photoshop.
– user484
Sep 11, 2014 at 1:56