2
$\begingroup$

I'm a newbie in image processing using Mathematica.

I'd like to compose an image $A$ over an image $B$ into an image C such that

$\quad C[i,j] = B[i,j]$, if $A[i,j]$ is white

$\quad C[i,j] = A[i,j]$, otherwise

It would work if I could do Min on each pixel:

$\quad C[i,j] = \min(A[i,j],B[i,j])$

but Min does not seem to work component-wise.

Perhaps I could turn white in $A$ into transparency and then compose over $B$. How can I do this?

$\endgroup$
  • $\begingroup$ Did you check the Image Composition docs? $\endgroup$ – Öskå Sep 5 '14 at 11:42
  • $\begingroup$ @Öskå, I did but can't seem to achieve what I want. $\endgroup$ – lhf Sep 5 '14 at 11:44
  • 3
    $\begingroup$ You can use ImageApply to apply a function like Min pixel-wise. Or turn the images to normal arrays using ImageData and use MapThread. $\endgroup$ – Niki Estner Sep 5 '14 at 11:58
  • 3
    $\begingroup$ Your comment to @Öskå suggests that you have tried something, which means you can post it here, which will help us help you. $\endgroup$ – bobthechemist Sep 5 '14 at 12:11
  • 1
    $\begingroup$ @m_goldberg You're right. I assumed the first one in my answer $\endgroup$ – Dr. belisarius Sep 5 '14 at 19:17
6
$\begingroup$

The naive method for component-wise Min is

img1 = Import["ExampleData/lena.tif"]
img2 = ColorNegate[img1]

enter image description here

ImageApply[Min /@ Transpose@{##} &, {img1, img2}] // AbsoluteTiming

enter image description here

But it is quite slow. However, one can note that $$ \min(A,B) = \frac{A}{2}+\frac{B}{2}-\left|\frac{A}{2}-\frac{B}{2}\right| $$ Therefore, let's try the following

ImageSubtract[ImageAdd[##], ImageDifference[##]] &[
  ImageMultiply[img1, 0.5], ImageMultiply[img2, 0.5]] // AbsoluteTiming

enter image description here

It is much faster!

P.S. It is also faster then ColorSeparate/ColorCombine:

ColorCombine[ImageApply[Min, #] & /@ 
   Transpose[ColorSeparate /@ {img1, img2}]] // AbsoluteTiming

enter image description here

$\endgroup$
5
$\begingroup$
(* Two sample images *)
a = Image[RandomReal[1, {100, 100, 3}]];
b = Image[Array[If[#1 < #2, RandomReal[.5, 3], {1, 1, 1}] &, {100, 100}]];

(* Calculate*)

Timing[
 mask = Binarize[b, {1., 1., 1.} == # &];
 c = ImageAdd[ImageMultiply[a, mask], ImageMultiply[b, ColorNegate@mask]];
 GraphicsRow[{a, b, mask, c}]]

Mathematica graphics

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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