[argyllcms] Re: perceptual black too light

  • From: Graeme Gill <graeme@xxxxxxxxxxxxx>
  • To: Gerhard Fuernkranz <nospam456@xxxxxx>
  • Date: Sun, 12 Feb 2006 14:02:30 +1100

Gerhard Fuernkranz wrote:

For CMYK, I've seen you're using powell() to minimize bfindfunc() in xlut.c for finding the BP. I've looked briefly at the code and did not see an obviour error, except one issue: icxLimit() seems to apply the inverse input table before summing up the ink amounts, but bfindfunc() passes CMYK values to icxLimit(), prior to feeding them through the input table. After changing the code, such that icxLimit() is called after applying the input tables

Interesting - I discovered that bug a week or two ago when I was investigating gamut boundary issues. I've split icxLimit() into two to fix this.

Furthermore, I have played with the starting point for powell(). I tried to 
start at CMYK=[0,0,0,1] and then I got

[...]
Find white & black points
White point XYZ = 0.785929 0.802246 0.777140, Lab = 91.785540 2.470131 
-10.226005
K only value (Lab) = 15.377936 0.779203 0.335627
Black point XYZ = 0.019416 0.019792 0.016025, Lab = 15.377936 0.779203 0.335627
[...]

==> strange, that powell() did not move away from the K-only starting point 
now, not even a little bit, since obviously, aprox 2dE darker would still have 
been possible.

$ xicclu -ia -fif -l250 -kh CHP410-1200.icc
15.3 0.779203 0.335627
15.300000 0.779203 0.335627 [Lab] -> Lut -> 0.486792 0.461311 0.436228 0.988796 
[CMYK] Lim 2.373127
14.3 0.779203 0.335627
14.300000 0.779203 0.335627 [Lab] -> Lut -> 0.463523 0.421306 0.406673 0.997251 
[CMYK] Lim 2.288753
13.3 0.779203 0.335627
13.300000 0.779203 0.335627 [Lab] -> Lut -> 0.428279 0.350430 0.322285 1.000000 
[CMYK] Lim 2.100994 (clip)

OK - the explanation is probably that it is caught in a local minima. One of the issues that my approach to inverting CMYK profiles doesn't deal with, is that the device response near the black point is often topologically complicated, "non-smooth" and probably disconnected. While each inversion in itself is perfectly accurate, as measured by the forward profile, there may be no usable connection between that point and other points within the gamut. This is a problem when interpolation is relied upon to represent the overall conversion in a practical fashion.

The reason for this is not too hard to understand :- even if the device
behaviour itself is basically monotonic in each channel, and the colorants
behave in a subtractive fashion when overlaid, the combination of colorants
with at least two colorant at their extreme values (0 or 100%) is the
surface of a 4 dimensional hyper-cube, that is the boundary of the devices
physical gamut. Because color space is three dimensional, this 4D cube
gets folded into 3D space, and because all the corners of the 4D cube that
have a K value of 100% or C=M=Y=100% are very close together in 3D colorspace,
the "dark" faces of the 4D cube end up overlapping and intersecting. There
is no way of avoiding this. (I have an illustration - if you take a data set
and create an MPP profile from it, and then use mpplu -t2, it creates an
artificially colored visualization. See the attached .wrl file of your dataset.
Note that the MPP is not as accurate as a normal profile in representing
the device behaviour.) For devices with >3 non-K colorants, this effect is
even worse, because overlaps occur on "light" faces.

Each of these faces is a gamut boundary, even if it is within the volume
of another section of the hyper-cube. That means there is no way from
such a point, outwards to another point within the gamut, without
a discontinuity in device values. Such topology is ripe for
getting local minima in trying to establish a suitable black point.
It also makes inverting >3 colorant profiles in a fashion that
produces continuity between interpolated points, quite a challenge.

[This is not something I've seen any research literature about.
It's hard to know if this problem has been tackled in any systematic
fashion by anyone.]

Currently in Argyll, I'm fudging over all this, and ignoring it.
With many devices, the dark cusp (corner of hyper-cube) colors are
sufficiently close together in colorspace, and the edges and faces
that connect these cusps are sufficiently close together in colorspace,
that discontinuities caused by this in the interpolation are not very
visible. For other devices, the artefacts are quite visible.
For the latter type of device, the usable gamut may well be smaller
than the absolute gamut, since there may be point that are too hard
to "get to", or have a narrow path to them, that simply doesn't
map in any usable way into an interpolation table. I had a go
at working around these problems a while ago, and some of
these attempts can still be seen in the code. In the end,
I decided to take a different approach, that would work for
>3 colorant devices, but this work has not been completed.
(Real world concerns have got in the way, and continue to do so.)

For the moment, I will make the black point location code
more robust against local minima, and ignore the larger issues.

Graeme Gill.





Other related posts: