RSS/Atom feed Twitter
Site is read-only, email is disabled

Incorrect Hue-Saturation results in obscure cases

This discussion is connected to the gimp-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.

This is a read-only list on gimpusers.com so this discussion thread is read-only, too.

3 of 4 messages available
Toggle history

Please log in to manage your subscriptions.

Incorrect Hue-Saturation results in obscure cases Richard Gitschlag 03 Jun 20:30
  Incorrect Hue-Saturation results in obscure cases Joao S. O. Bueno 04 Jun 12:43
   Incorrect Hue-Saturation results in obscure cases Richard Gitschlag 04 Jun 15:49
SNT111-W652B514357E247F637B... 04 Jun 15:49
Richard Gitschlag
2012-06-03 20:30:11 UTC (over 12 years ago)

Incorrect Hue-Saturation results in obscure cases

(Apologies if this is a duplicate post; I tried sending it the other day but it didn't seem to go through)

I've found some obscure conditions under which the Hue-Saturation tool produces incorrect results up to and including current 2.8.0 .

The first one I encountered "in the wild" sometime in 2.6: I had recently finished a pencil drawing and scanned it into an image file, but the "pink" areas of the drawing were not a warm enough shade for my preference. At the time I felt the easiest method to fix this was via Hue-Saturation tool, so I went to the tool, slid the Overlap to 100%, then adjusted the Magenta hue by about +10º. (I chose the Magenta range instead of Red because the image also contained colors in the red/orange region, and I didn't want them affected.) Suddenly my pink pixels were now magenta and blue! As if GIMP was calculating it around the wrong side of the HSV wheel, but that was apparently reported, patched and fixed four years ago (bug #527085) so the explanation can't be that simple.

I've also found another condition that, while it's so improbable a user might never encounter it in the wild, it is still incorrect:

- Adjust the Cyan channel hue by +100º ( -> Magenta/blue) - Adjust the Blue channel hue by -100º ( -> Cyan/green) - Set Overlap to 100%

So if a hue falls between Cyan and Blue ranges, it should get mapped to a Magenta -> Blue -> Cyan -> Green range, right? But instead, GIMP maps them to a Magenta -> Red -> Yellow -> Green range; here it IS going the wrong way around the circle.

This is because of the way GIMP calculates the hue adjustment:

mapped_primary_hue = (input_hue + primary_hue_adjustment) mapped_secondary_hue = (input_hue + secondary_hue_adjustment) ...
final_hue = (mapped_primary_hue * primary_intensity) + (mapped_secondary_hue * secondary_intensity)

A.k.a. it maps both ranges independently then interpolates the result between them. Meanwhile, GIMP ensures that mapped_primary_hue and mapped_secondary_hue are kept inside the (0.0 - 1.0) range, and if there is more than a 180º difference between them, GIMP wraps mapped_secondary_hue again to yield a "shortest circle" route. This is correct 99% of the time, but in the above case, it fails because there's a 200º difference between mapped_primary_hue and mapped_secondary_hue (regardless of the actual input value or master hue adjustement); GIMP assumes it is going the wrong way around the HSV circle when it actually isn't (the actual difference between blue and cyan after these adjustments is 140º, not 200º).

Another testcase to confirm why it's a bug: - Cyan hue +90
- Blue hue -90
Result: Correct (overlap fades from magenta/blue -> cyan/green).

- Cyan hue +91 - Blue hue -91
Result: Incorrect (overlap fades from blue/magenta -> red -> yellow -> green/cyan)

Who knew a humble 2º made such difference? The patch that fixed #527085 cannot tell whether a difference of > 180º is due to crossing the red/magenta wraparound or if that was deliberate on the part of the user. (And it's not the tool's job to question whether the user's adjustments are sane.)

I can submit a patch for this that may fix the issue permanently - but let me know if my algebra is correct first:

Given that: mapped_primary_hue = input_hue + (master_hue_adjustment + primary_hue_adjustment) mapped_secondary_hue = input_hue + (master_hue_adjustment + secondary_hue_adjustment) (primary_intensity + secondary_intensity) = 1

And: final_hue = mapped_primary_hue * primary_intensity + mapped_secondary_hue * secondary_intensity

THEN: final_hue = (input_hue + master_hue_adjusment + primary_hue_adjusment) * primary_intensity + (input_hue + master_hue_adjusment + secondary_hue_adjustment) * secondary_intensity = (input_hue + master_hue_adjustment) * (primary_intensity + secondary_intensity) + primary_hue_adjustment * primary_intensity + secondary_hue_adjustment * secondary_intensity = input_hue + master_hue_adjusment + (primary_hue_adjustment * primary_intensity + secondary_hue_adjustment + secondary_intensity)

In other words, when dealing with pixels in an overlap region the tool should interpolate the hue adjustment from the respective primary and secondary ranges, THEN map that adjustment to the pixel. And since the output value is subsequently converted from HSL back to RGB space with essentially no further processing, there's no need to worry about crossing the red/magenta wraparound at all.

-- Stratadrake strata_ranger@hotmail.com
--------------------
Numbers may not lie, but neither do they tell the whole truth.

Joao S. O. Bueno
2012-06-04 12:43:39 UTC (over 12 years ago)

Incorrect Hue-Saturation results in obscure cases

Hi Richard --

Could you open a bug report at bugzilla@gimp.org about this issue, and attach the example images ?

js -> wrote:

(Apologies if this is a duplicate post; I tried sending it the other day but it didn't seem to go through)

I've found some obscure conditions under which the Hue-Saturation tool produces incorrect results up to and including current 2.8.0 .

The first one I encountered "in the wild" sometime in 2.6:  I had recently finished a pencil drawing and scanned it into an image file, but the "pink" areas of the drawing were not a warm enough shade for my preference.  At the time I felt the easiest method to fix this was via Hue-Saturation tool, so I went to the tool, slid the Overlap to 100%, then adjusted the Magenta hue by about +10º.  (I chose the Magenta range instead of Red because the image also contained colors in the red/orange region, and I didn't want them affected.)  Suddenly my pink pixels were now magenta and blue!  As if GIMP was calculating it around the wrong side of the HSV wheel, but that was apparently reported, patched and fixed four years ago (bug #527085) so the explanation can't be that simple.

I've also found another condition that, while it's so improbable a user might never encounter it in the wild, it is still incorrect:

- Adjust the Cyan channel hue by +100º ( -> Magenta/blue) - Adjust the Blue channel hue by -100º ( -> Cyan/green) - Set Overlap to 100%

So if a hue falls between Cyan and Blue ranges, it should get mapped to a Magenta -> Blue -> Cyan -> Green range, right? But instead, GIMP maps them to a Magenta -> Red -> Yellow -> Green range; here it IS going the wrong way around the circle.

This is because of the way GIMP calculates the hue adjustment:

mapped_primary_hue = (input_hue + primary_hue_adjustment) mapped_secondary_hue = (input_hue + secondary_hue_adjustment) ...
final_hue = (mapped_primary_hue * primary_intensity) + (mapped_secondary_hue * secondary_intensity)

A.k.a. it maps both ranges independently then interpolates the result between them.  Meanwhile, GIMP ensures that mapped_primary_hue and mapped_secondary_hue are kept inside the (0.0 - 1.0) range, and if there is more than a 180º difference between them, GIMP wraps mapped_secondary_hue again to yield a "shortest circle" route.  This is correct 99% of the time, but in the above case, it fails because there's a 200º difference between mapped_primary_hue and mapped_secondary_hue (regardless of the actual input value or master hue adjustement); GIMP assumes it is going the wrong way around the HSV circle when it actually isn't (the actual difference between blue and cyan after these adjustments is 140º, not 200º).

Another testcase to confirm why it's a bug: - Cyan hue +90
- Blue hue -90
Result: Correct (overlap fades from magenta/blue -> cyan/green).

- Cyan hue +91 - Blue hue -91
Result:  Incorrect (overlap fades from blue/magenta -> red -> yellow -> green/cyan)

Who knew a humble 2º made such difference?  The patch that fixed #527085 cannot tell whether a difference of > 180º is due to crossing the red/magenta wraparound or if that was deliberate on the part of the user. (And it's not the tool's job to question whether the user's adjustments are sane.)

I can submit a patch for this that may fix the issue permanently - but let me know if my algebra is correct first:

Given that:  mapped_primary_hue = input_hue + (master_hue_adjustment + primary_hue_adjustment)
 mapped_secondary_hue = input_hue + (master_hue_adjustment + secondary_hue_adjustment)
 (primary_intensity + secondary_intensity) = 1

And:  final_hue = mapped_primary_hue * primary_intensity + mapped_secondary_hue * secondary_intensity

THEN:
 final_hue = (input_hue + master_hue_adjusment + primary_hue_adjusment) * primary_intensity + (input_hue + master_hue_adjusment + secondary_hue_adjustment) * secondary_intensity  = (input_hue + master_hue_adjustment) * (primary_intensity + secondary_intensity) + primary_hue_adjustment * primary_intensity + secondary_hue_adjustment * secondary_intensity  = input_hue + master_hue_adjusment + (primary_hue_adjustment * primary_intensity + secondary_hue_adjustment + secondary_intensity)

In other words, when dealing with pixels in an overlap region the tool should interpolate the hue adjustment from the respective primary and secondary ranges, THEN map that adjustment to the pixel.  And since the output value is subsequently converted from HSL back to RGB space with essentially no further processing, there's no need to worry about crossing the red/magenta wraparound at all.

-- Stratadrake strata_ranger@hotmail.com
--------------------
Numbers may not lie, but neither do they tell the whole truth.

_______________________________________________ gimp-developer-list mailing list
gimp-developer-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gimp-developer-list

Richard Gitschlag
2012-06-04 15:49:28 UTC (over 12 years ago)

Incorrect Hue-Saturation results in obscure cases

Date: Mon, 4 Jun 2012 09:43:39 -0300 Subject: Re: [Gimp-developer] Incorrect Hue-Saturation results in obscure cases From: gwidion@mpc.com.br
To: strata_ranger@hotmail.com
CC: gimp-developer-list@gnome.org

Hi Richard --

Could you open a bug report at bugzilla@gimp.org about this issue, and attach the example images ?

Already filed as bug #644032 and as a comment on #527085. Example screenshot is attached to the first one:

http://bugzilla-attachments.gnome.org/attachment.cgi?id=215132

And the second case was specifically introduced by the way #527085 got patched, which is why I didn't file it as a new bug (yet). I haven't taken a screenshot of it, but I can do that pretty easily.

I've attached a patch that implements the reworked algebra (interpolate first, then map to pixel), but I cannot actually test to verify if it works as I do not have an installed C compiler at this time. :( But it should fix both issues if it works.

-- Stratadrake strata_ranger@hotmail.com
--------------------
Numbers may not lie, but neither do they tell the whole truth.

js
-> wrote:

(Apologies if this is a duplicate post; I tried sending it the other day but it didn't seem to go through)

I've found some obscure conditions under which the Hue-Saturation tool produces incorrect results up to and including current 2.8.0 .

The first one I encountered "in the wild" sometime in 2.6: I had recently finished a pencil drawing and scanned it into an image file, but the "pink" areas of the drawing were not a warm enough shade for my preference. At the time I felt the easiest method to fix this was via Hue-Saturation tool, so I went to the tool, slid the Overlap to 100%, then adjusted the Magenta hue by about +10º. (I chose the Magenta range instead of Red because the image also contained colors in the red/orange region, and I didn't want them affected.) Suddenly my pink pixels were now magenta and blue! As if GIMP was calculating it around the wrong side of the HSV wheel, but that was apparently reported, patched and fixed four years ago (bug #527085) so the explanation can't be that simple.

I've also found another condition that, while it's so improbable a user might never encounter it in the wild, it is still incorrect:

- Adjust the Cyan channel hue by +100º ( -> Magenta/blue) - Adjust the Blue channel hue by -100º ( -> Cyan/green) - Set Overlap to 100%

So if a hue falls between Cyan and Blue ranges, it should get mapped to a Magenta -> Blue -> Cyan -> Green range, right? But instead, GIMP maps them to a Magenta -> Red -> Yellow -> Green range; here it IS going the wrong way around the circle.

This is because of the way GIMP calculates the hue adjustment:

mapped_primary_hue = (input_hue + primary_hue_adjustment) mapped_secondary_hue = (input_hue + secondary_hue_adjustment) ...
final_hue = (mapped_primary_hue * primary_intensity) + (mapped_secondary_hue * secondary_intensity)

A.k.a. it maps both ranges independently then interpolates the result between them. Meanwhile, GIMP ensures that mapped_primary_hue and mapped_secondary_hue are kept inside the (0.0 - 1.0) range, and if there is more than a 180º difference between them, GIMP wraps mapped_secondary_hue again to yield a "shortest circle" route. This is correct 99% of the time, but in the above case, it fails because there's a 200º difference between mapped_primary_hue and mapped_secondary_hue (regardless of the actual input value or master hue adjustement); GIMP assumes it is going the wrong way around the HSV circle when it actually isn't (the actual difference between blue and cyan after these adjustments is 140º, not 200º).

Another testcase to confirm why it's a bug: - Cyan hue +90
- Blue hue -90
Result: Correct (overlap fades from magenta/blue -> cyan/green).

- Cyan hue +91 - Blue hue -91
Result: Incorrect (overlap fades from blue/magenta -> red -> yellow -> green/cyan)

Who knew a humble 2º made such difference? The patch that fixed #527085 cannot tell whether a difference of > 180º is due to crossing the red/magenta wraparound or if that was deliberate on the part of the user. (And it's not the tool's job to question whether the user's adjustments are sane.)

I can submit a patch for this that may fix the issue permanently - but let me know if my algebra is correct first:

Given that: mapped_primary_hue = input_hue + (master_hue_adjustment + primary_hue_adjustment)
mapped_secondary_hue = input_hue + (master_hue_adjustment + secondary_hue_adjustment)
(primary_intensity + secondary_intensity) = 1

And: final_hue = mapped_primary_hue * primary_intensity + mapped_secondary_hue * secondary_intensity

THEN:
final_hue = (input_hue + master_hue_adjusment + primary_hue_adjusment) * primary_intensity + (input_hue + master_hue_adjusment + secondary_hue_adjustment) * secondary_intensity = (input_hue + master_hue_adjustment) * (primary_intensity + secondary_intensity) + primary_hue_adjustment * primary_intensity + secondary_hue_adjustment * secondary_intensity = input_hue + master_hue_adjusment + (primary_hue_adjustment * primary_intensity + secondary_hue_adjustment + secondary_intensity)

In other words, when dealing with pixels in an overlap region the tool should interpolate the hue adjustment from the respective primary and secondary ranges, THEN map that adjustment to the pixel. And since the output value is subsequently converted from HSL back to RGB space with essentially no further processing, there's no need to worry about crossing the red/magenta wraparound at all.

-- Stratadrake strata_ranger@hotmail.com
--------------------
Numbers may not lie, but neither do they tell the whole truth.

_______________________________________________ gimp-developer-list mailing list
gimp-developer-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gimp-developer-list