4
$\begingroup$

I am using the answer of bill s in Greater operator should give greater element.

Here he showed the example:

lst1 = {{1, 2}, {3, 4}}; lst2 = {{5, 1}, {7, 2}};

max[list1_, list2_] := Module[{out}, Unprotect[Max]; SetAttributes[Max, Listable];
  out = Max[list1, list2]; ClearAttributes[Max, Listable]; out];

max[lst1, lst2]

{{5, 2}, {7, 4}}

Now I would like to apply it to two images:

image 1:

enter image description here

image 2:

enter image description here

I though the code below would show the superposed image with max intensity at each pixel.

imageData1=ImageData[image1];
imageData2=ImageData[image2];

maxImage=Image[max[imageData1,imageData2]]

The result is a message:

Image::imgarray: The specified argument 1.` should be an array of rank 2 or 3 with machine-sized numbers. >>

What do I wrong?

$\endgroup$
0

2 Answers 2

8
$\begingroup$

Alternative solutions: You could use ImageApply on images:

ImageApply[Max, {i1, i2}]; // RepeatedTiming

{0.0239, Null}

Or MapThread on lists:

Image[MapThread[Max, ImageData /@ {i1, i2}, 2]]; // RepeatedTiming

{0.0231, Null}

And, somewhat surprisingly this uses 2 multiplications and 3 additions per pixel:

 (
   {d1, d2} = ImageData /@ {i1, i2};
   comp = UnitStep[d1 - d2];
   Image[comp*d1 + (1 - comp)*d2]
   ); // RepeatedTiming

{0.00069, Null}

and is still > 30 times faster.

Even more surprisingly (to me):

(
  comp = Binarize[ImageSubtract[i1, i2], 0];
  ImageAdd[ImageMultiply[comp, i1], 
    ImageMultiply[ColorNegate@comp, i2]]
 ); // RepeatedTiming

{0.0017, Null}

Is slower than the double precision arithmetic version above. Apparently, ImageAdd and friends aren't very efficient.

$\endgroup$
1
  • $\begingroup$ I vote for your {d1, d2} solution. I tested a superposition of sequentiell gray scale images (286 png 8bit images, each 347*347 pixels). The code {d1, d2} = ... is in total about 4 times faster than using ImageApply[Max, {img1, img2}]. See imgur.com/MhJApXv and imgur.com/9Thol7v. $\endgroup$
    – mrz
    Jul 5, 2016 at 8:40
6
$\begingroup$

It's simpler than that, since you can use the built-in image processing function ImageApply:

img1 = Import["https://i.stack.imgur.com/bBsDH.png"];
img2 = Import["https://i.stack.imgur.com/O9Vm6.png"];
ImageApply[Max, {img1, img2}]

enter image description here

$\endgroup$
3
  • $\begingroup$ Upvote.I have to say the ImageApply is low efficiency function.Maybe ImageAdjust[ImageAdd[img1, img2]] is enough $\endgroup$
    – yode
    Jul 4, 2016 at 17:17
  • 1
    $\begingroup$ @yode -- it may not be particularly efficient to run, but it is very efficient to write. And it is also very flexible since you can use any function (with the right number of inputs and outputs), not just Max. $\endgroup$
    – bill s
    Jul 4, 2016 at 17:20
  • $\begingroup$ Thank you for your help. Please see my comment below nikies answer. Do you know why your code in mathematica.stackexchange.com/questions/97918/… is not applicable? $\endgroup$
    – mrz
    Jul 5, 2016 at 8:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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