# Performance of ImageApply

I would like to optimize this code

fadeAndShine[old_, new_] := If[old == new, {1, 0.8, 0.2}, new];


Is it possible, and if yes, on what should I focus?

Applying fadeAndShine to following image takes 0.53 sec on my pc, while applying Max takes 0.31 sec.

imageA =
Rasterize[Graphics[Table[Circle[{x, 0}, x], {x, 1, 25}]], "Image",
ImageSize -> 500];
imageB =
Rasterize[Graphics[Table[Circle[{0.8 x, 0}, x], {x, 1, 25}]],
"Image", ImageSize -> 500];


I'm willing to use another functionality as long as I get same result for any pair of images.

Your If codition is pretty simple and can be precomputed on all pixels more efficiently to generate a composition mask

mask = Binarize[ImageDifference[imageA, imageB], 0] You can then use simple arithmetic to combine it

ImageAdd[
ImageMultiply[ColorNegate[mask], RGBColor @@ {1, 0.8, 0.2}],
] Putting all together

fadeAndShine2[old_, new_, color: _?ColorQ : RGBColor[1, 0.8, 0.2]] :=
With[
]
]

(* => 0.012 *)


And

MinMax[

(* => {0., 0.} *)

• Very neat. (+1) May 4, 2018 at 10:58
• Your code seems simplest and fastest. May 4, 2018 at 13:11

You can try to use compiled code and apply it to the ImageData of your images:

fadeAndShine[old_, new_] := If[old == new, {1, 0.8, 0.2}, new];

cFadeAndShine = Compile[{{old, _Real, 1}, {new, _Real, 1}},
If[old == new, {1., 0.8, 0.2}, new],
CompilationTarget -> "C",
RuntimeAttributes -> {Listable},
Parallelization -> True
];


And here the usage example with timings:

imageA = Rasterize[Graphics[Table[Circle[{x, 0}, x], {x, 1, 25}]],
"Image", ImageSize -> 500];
imageB = Rasterize[Graphics[Table[Circle[{0.8 x, 0}, x], {x, 1, 25}]],
"Image", ImageSize -> 500];

imageC = ImageApply[fadeAndShine, {imageA, imageB}]; //
AbsoluteTiming // First
AbsoluteTiming // First
ImageData[imageC] - ImageData[imageD] // Abs // Max


0.355039

0.035754

0.

• I actually forgot about this way. Making a Listable compiled function is indeed a very useful trick for more complex behaviours. May 4, 2018 at 17:11
imageA=Rasterize[Graphics[Table[Circle[{x,0},x],{x,1,25}]],"Image",ImageSize->500];
imageB=Rasterize[Graphics[Table[Circle[{0.8 x,0},x],{x,1,25}]],"Image",ImageSize->500];

data1=ImageApply[Function[{old,new},If[old==new,{1.,0.8,0.2},new]],{imageA,imageB}]//
ImageData;//AbsoluteTiming

data2=Map[With[{old=#[[{1,2,3}]],new=#[[{4,5,6}]]},If[old==new,{1.,0.8,0.2},new]]&,
Join[ImageData[imageA],ImageData[imageB],3],{2}];//AbsoluteTiming

data3=With[{old=ImageData[imageA],new=ImageData[imageB]},
With[{k=Unitize[new-old]},Map[{1.,0.8,0.2}#&, 1-k,{2}]+new k]];//AbsoluteTiming

data1==data2==data3


{0.637831, Null}

{0.249619, Null}

{0.0957136, Null}

True