While trialing Mathematica 8, I noticed ImageResize[] doesn't seem to linearize
the colorspace before resizing.
Is this intentional?
Reasoning why it would be a nice option to have:
http://www.4p8.com/eric.brasseur/gamma.html
Of course, to "fix" this properly, image needs to have information in what
colorspace it is in in the first place, but to have
the option available directly in ImageResize would be nice, as I suspect it
could be made quite a bit faster.
This non-linearization is probably assumed for all other image functions too?
Example how to expose the issue (and how to fix, albeit slow and convoluted):
(used "Dalai Lama" pic from the link above, which is constructed to exhibit the
issue)
(remove compilation target etc if you don't have a compiler - was testing how
to make corrections run "faster")
Clear[srgb2linear, linear2srgb, linearresize, image];
srgb2linear = Compile[{{Csrgb, _Real, 1}},
With[{\[Alpha] = 0.055}, Table[Piecewise[
{{C/12.92,
C <= 0.04045}, {((C + \[Alpha])/(1 + \[Alpha]))^2.4,
C > 0.04045}}], {C, Csrgb}]], RuntimeAttributes ->
{Listable}, Parallelization -> True, CompilationTarget ->
"C", RuntimeOptions -> "Speed"];
linear2srgb = Compile[{{Clinear, _Real, 1}},
With[{\[Alpha] = 0.055}, Table[Piecewise[
{{12.92*C,
C <= 0.0031308}, {(1 + \[Alpha])*C^(1/2.4) - \[Alpha],
C > 0.0031308}}], {C, Clinear}]],
RuntimeAttributes -> {Listable}, Parallelization -> True,
CompilationTarget -> "C", RuntimeOptions -> "Speed"];
linearresize[image_Image, scaling_] :=
Module[{}, ((Image[#1, ColorSpace -> "RGB"] & )[
linear2srgb[ImageData[#1, Interleaving -> True]]] & )[
ImageResize[(Image[#1, ColorSpace -> "RGB"] & )[
srgb2linear[ImageData[image, Interleaving -> True]]],
scaling]]]
image = Image["Dalai Lama", "Real"]
In[432]:= ImageResize[ImageResize[image, Scaled[1/2]], Scaled[2]]
Out:= Screwed up picture
In[433]:= linearresize[linearresize[image, Scaled[1/2]], Scaled[2]]
Out:= Correct image (of course sampled)
This genuine issue will be properly addressed in a future release of
Mathematica. In the meanwhile, one needs to revert to bits of code,
as you did.
In this particular case, your code produces on my machine a white
image. That gamma correction seems to give a correct result:
lin = ImageAdjust[image, {0, 0, 1.8}];
res = ImageResize[ImageResize[lin, Scaled[1/2]], Scaled[2]];
res = ImageAdjust[res, {0, 0, 1/1.8}];
(These values may be machine and OS dependent.)
Matthias Odisio
Wolfram Research
Thank you very much for the confirmation! I was not sure if it was something
that would be addressed, or if all imagedata was to be assumed linearized.
>In this particular case, your code produces on my machine a white
>image. That gamma correction seems to give a correct result:
>
>lin = ImageAdjust[image, {0, 0, 1.8}];
>res = ImageResize[ImageResize[lin, Scaled[1/2]], Scaled[2]];
>res = ImageAdjust[res, {0, 0, 1/1.8}];
>
>(These values may be machine and OS dependent.)
Yes, very much so, dependent on the source image, and how you got it into
Mathematica (copy/paste results from browser are dependent on browser & OS
used, for example).
My "quick code" assumes strictly SRGB (flat part of the curve accounted for
instead of pure gamma curve), normalized to [0,1] and, I think, does not handle
alpha channels properly. :)
ImageAdjust works well if you have just a pure gamma curve (like you would with
AdobeRGB, for example), or if absolute accuracy isn't too important and
approximation is good enough (like it is for this test image, actually).
Can you divulge if there would be any plans to implement generalized color
handling for images in Mathematica?
I.e. something along the lines:
(* assert image colorspace as "xxx")
img=Image[blaa, ColorSpace->"AdobeRGB"];
(* convert to new space *)
ColorConvert[img, "SRGB"]
Preferrably with the possibility of user definable matrices/color
primaries/transfer functions? (of course, this could be expanded to be usable
in Import/Export and image functions in general)
I was going to implement something like that (for my own amusement mainly, to
learn Mathematica and some color theory and to test analyzing some video data
where it is important to have the BT.601/709 primaries accounted for). This is,
of course, going to be "slowish" (for "real" use) compared to if internal
functions would support something like this directly. Compile[] seems to work
wonders, though (still slow as molasses compared to properly vectorized asm
implementation, which is not surprising). :)
>Matthias Odisio
>Wolfram Research
JariP
>> This genuine issue will be properly addressed in a future release of
>> Mathematica. In the meanwhile, one needs to revert to bits of code,
>> as you did.
>
> Thank you very much for the confirmation! I was not sure if it was something
> that would be addressed, or if all imagedata was to be assumed linearized.
/.../
>
> Can you divulge if there would be any plans to implement generalized color
> handling for images in Mathematica?
That's what I meant by 'properly addressed', yes.
Feel free to reply to me off the list if you'd like to be in contact
with developers involved in this project.
Matthias Odisio
Wolfram Research