Wednesday, 28 November 2012

.^ operator vs. logs in Matlab

Quick comparison test. Say you have a large matrix A, what's faster, A.^2.4 or exp(log(A)*2.4)?

Obviously, the fact that I'm asking should kind of give away the answer and the latter is faster. There's however a catch in all this, so it really depends on what you're doing, because you can't take log(0). But, for what I want to do this isn't a problem.

Let's say that our big matrix is actually an image in sRGB colour space, and I want to convert it to linear RGB, that is, I want to remove the gamma correction. From the Wikipedia page I find the formula, and the straightforward implementation is:

linear = srgb;
small = linear < 0.04045;
linear(small) = srgb(small) / 12.92;
linear(~small) = ((srgb(~small) + 0.055)/1.055) .^ 2.4;

But if the image is big (or your computer is slow) we can save seconds using logs.

small = srgb < 0.04045;
linear = exp(log((max(srgb,1e-3)+0.055)/1.055) * 2.4);
linear(small) = srgb(small) / 12.92;

This code, if in a function, is about three times as fast as the previous.

In this case, clipping the image to 0.001 works perfectly fine whether you use 8 or 16 bit precision images, because all those small values are only transformed linearly by this gamma function. Obviously, if you're not doing image processing this may not be good enough for you and you might have to stick to the .^ operator.

Anyhow, this works also for applying the gamma to a linear RGB image. The code is the following:

small = linear < 0.0031308;
srgb = exp(log(1.055) + log(max(linear,1e-3)) / 2.4) - 0.055;
srgb(small) = linear(small) * 12.92;

No comments:

Post a Comment