3
$\begingroup$

This question already has an answer here:

Suppose I have a 2D array im of real values between 0 and 1, representing a grayscale image. I can turn im into an image very efficiently with Image[im] (in fact, on my machine, AbsoluteTiming@Image[im] returns 0. for a 1920 by 1080 array). I would like to colorize im by applying a ColorDataFunction, for example, ColorData["AvocadoColors"], to each entry of im. My first thought was to use Image@Map[ColorData["AvocadoColors"], im, {2}], but this is unreasonably expensive, taking nearly a minute for a 1920 by 1080 array. What is a more efficient way to produce the same output?

$\endgroup$

marked as duplicate by Mr.Wizard Feb 17 '15 at 19:54

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    $\begingroup$ Colorize[im, ColorFunction->"AvocadoColors"]? $\endgroup$ – kglr Feb 17 '15 at 18:08
  • $\begingroup$ @kguler Remember to ColorFunctionScaling -> False. $\endgroup$ – Kuba Feb 17 '15 at 18:11
  • $\begingroup$ @kguler I just came back to post that, that's the correct solution. Why don't you post it? $\endgroup$ – Szabolcs Feb 17 '15 at 18:12
  • $\begingroup$ @kguler Did you mean Colorize[Image[im], ColorFunction -> "AvocadoColors"]? When I execute your code, I'm told that Colorize is Expecting an integer matrix or an image instead of {<<1>>}. $\endgroup$ – David Zhang Feb 17 '15 at 18:17
  • 1
    $\begingroup$ @Szabolcs, just posted the comment as answer. Your deleted answer seems to be faster on a few example images i tried. $\endgroup$ – kglr Feb 17 '15 at 18:32
3
$\begingroup$
im = ExampleData[{"TestImage", "Aerial"}];

Colorize[im, ColorFunction -> "AvocadoColors"] // Timing // First
(* 0.093750 *)

versus

ImageApply[List @@ ColorData["AvocadoColors"][#] &, im] // Timing // First
(* 0.265625 *)

ImageApply[List @@ Blend["AvocadoColors", #] &, im] // Timing // First (thanks: @Kuba *)
(* 0.109375 *)

For a larger image:

imlarge = Image[ RandomReal[1, {1080, 1920}]];

f1 = Colorize[#, ColorFunction -> "AvocadoColors"] &;
f2 = Image@Raster[ImageData[#, DataReversed -> True], ColorFunction -> "AvocadoColors"] &;
f3 = ImageApply[List @@ Blend["AvocadoColors", #] &, #] &;

First[Timing@#[imlarge]] & /@ {f1, f2, f3}
{2.234375, 2.140625, 3.093750}
$\endgroup$
  • $\begingroup$ Is this really the fastest it can be done? I was hoping, since Image[im] is so fast, that I might be able to apply a ColorDataFunction in a comparable amount of time. For me, these all take several seconds for a 1920 by 1080 image. $\endgroup$ – David Zhang Feb 17 '15 at 19:22
  • $\begingroup$ @DavidZhang, i am sure answers with faster methods will trickle in if you wait a few hours/days. $\endgroup$ – kglr Feb 17 '15 at 20:18
2
$\begingroup$

Raster will be helpful, as it has the ColorFunction option and it can be directly converted back to an Image.

Let img be a grayscale image:

img = ColorConvert[ExampleData[{"TestImage", "Lena"}], "Grayscale"]

Image@Raster[ImageData[img, DataReversed -> True], ColorFunction -> "Rainbow"]

Mathematica graphics

$\endgroup$
  • $\begingroup$ Note: this is just an idea that has the advantage of brevity and simplicity. I haven't tested performance. $\endgroup$ – Szabolcs Feb 17 '15 at 18:05
  • $\begingroup$ Undeleted on request. kguler's answer is the "standard" way though. $\endgroup$ – Szabolcs Feb 17 '15 at 19:10

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