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.
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 |
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.
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) = 1And: 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
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.orgHi 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) = 1And: 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