[Solved] Black pixel artifacts after "modulate" in 6.9.7-4

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
ojensen5115
Posts: 8
Joined: 2018-03-26T14:08:58-07:00
Authentication code: 1152

[Solved] Black pixel artifacts after "modulate" in 6.9.7-4

Post by ojensen5115 »

Update:
  • Bugfix is in 6.9.9-40 (currently beta)
  • Workaround for while you wait for that to hit the repos is in this post


------------------
I am having the identical problem as discussed in this post:
viewtopic.php?f=1&t=29150

I am creating a new thread because that thread is over two years old old according to dlemstra in the penultimate post, it was an issue that should be resolved:
dlemstra wrote: 2016-03-08T14:53:14-07:00 This appeared to be a rounding issue in OpenCL and I just pushed a patch to our GIT repository to fix this. This fix will be included in the next release of ImageMagick (6.9.3-8)
I am running ImageMagick 6.9.7-4 Q16 x86_64 20170114 which should contain this fix, but am still seeing this issue.

Source image:
https://i.imgur.com/uWfUwK0.png

Code: Select all

convert source.png -modulate 100,100,80 result.png
Result image:
https://i.imgur.com/cpA4e9O.png
Last edited by ojensen5115 on 2018-04-08T19:15:18-07:00, edited 2 times in total.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Black pixel artifacts after "modulate" in 6.9.7-4

Post by fmw42 »

It happens also in IM 6.9.9.40 Q16 and IM 7.0.7.28 Q16 HDRI as well. I do not think it is an OpenCL issue, since in my compiles, OpenCL is disabled.

Code: Select all

convert source.png -modulate 100,100,80 result.png
The black does not appear if using HCL colorspace, but does occur for both HSL and HSV

Code: Select all

convert source.png -define modulate:colorspace=HCL -modulate 100,100,80 result.png
ojensen5115
Posts: 8
Joined: 2018-03-26T14:08:58-07:00
Authentication code: 1152

Re: Black pixel artifacts after "modulate" in 6.9.7-4

Post by ojensen5115 »

Thank you fmw42 for your response. The black dots do not indeed appear when using

Code: Select all

modulate:colorspace=HCL
but then the colors get all wonky:
https://i.imgur.com/zPUD2P4.png
ojensen5115
Posts: 8
Joined: 2018-03-26T14:08:58-07:00
Authentication code: 1152

Re: Black pixel artifacts after "modulate" in 6.9.7-4

Post by ojensen5115 »

I note that the black does not appear if I first convert the image to RBG. In general, modulate seems to do rather wonky things with the hue in colorspaces other than SRGB and RGB -- perhaps it is implemented under the assumption that it is working on the RGB colorspace, and the fact that it appears to work for SRGB is merely an artifact of the similarity between the two colorspaces.

To get rid of the black pixel artifacts, doing some colorspace transformations appears to be enough. In PHP / Imagick parlance, replace

Code: Select all

$image->modulateImage(100, 100, 80);
with

Code: Select all

$image->transformImageColorSpace(Imagick::COLORSPACE_RGB);
$image->modulateImage(100, 100, 80);
$image->transformImageColorSpace(Imagick::COLORSPACE_SRGB);
This seems less than ideal, though, so I'm still hoping to find a "better" solution.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Black pixel artifacts after "modulate" in 6.9.7-4

Post by fmw42 »

Your image is already sRGB. So I don't understand that. But see the bug report I sent in and the developers response.
ojensen5115
Posts: 8
Joined: 2018-03-26T14:08:58-07:00
Authentication code: 1152

Re: Black pixel artifacts after "modulate" in 6.9.7-4

Post by ojensen5115 »

Yes, the image is already sRGB. To get "modulate" to work correctly, I have to first convert it from sRGB to RGB, then perform the hue shift on the RGB image, then convert it back from RGB to sRGB (since the rest of my process assumes sRGB).

Thank you for reporting the bug!

EDIT: interestingly, with the pre-modulate conversion to RGB, the resulting shift no longer matches what I get in GIMP or other graphics editing software (after accounting for the fact that GIMP uses -180 - 180 versus ImageMagick's 0 - 200). Performing the hue shift on sRGB images directly yielded "correct" results, but also resulted in the black pixels. I'll be excited to try out the fix once it's pushed.
ojensen5115
Posts: 8
Joined: 2018-03-26T14:08:58-07:00
Authentication code: 1152

Re: Black pixel artifacts after "modulate" in 6.9.7-4

Post by ojensen5115 »

For anyone else who ends up finding this post, while waiting for the "proper" fix to hit the repos I have discovered that the following workaround works very well, without messing up the colors:
  • resize image up to 140% size
  • modulate image to reduce contrast by 75% and reduce lightness by 3%
  • modulate image to perform the desired hue shift
  • modulate image to increase the contrast and lightness back to original (in this case, increase contrast by 400% and lightness by 3%)
  • resize image back to original size
The reduction and restoration of contrast and lightness around the hue shift almost entirely solves the problem, but there's a few stray black pixels left over. Performing it on a scaled-up version before scaling it back down again made even those black pixels go away.

The Imagick code for this procedure is as follows:

Code: Select all

function modulate_wrapper($image, $lightness, $contrast, $hue) {

    // set up parameters
    $size_factor = 1.4;
    $contrast_drop_percent = 75;
    $lightness_drop_percent = 3;

    // calculate lightness and contrast targets
    $contrast_dn = 100 - $contrast_drop_percent;
    $lightness_dn = 100 - $lightness_drop_percent;
    $contrast_up = 100 / (100 - $contrast_drop_percent) * 100;
    $lightness_up = 100 / (100 - $lightness_drop_percent) * 100;

    // expand the image
    $d = $image->getImageGeometry();
    $expanded_width = $d['width'] * $size_factor;
    $expanded_height = $d['height'] * $size_factor;
    $image->resizeImage($expanded_width, $expanded_height, imagick::FILTER_LANCZOS, 1);

    // drop contrast / lightness, hue shift, then restore contrast / lightness
    $image->modulateImage($lightness_dn, $contrast_dn, 100);
    $image->modulateImage($lightness, $contrast, $hue);
    $image->modulateImage($lightness_up, $contrast_up, 100);

    // size the image back
    $image->resizeImage($d['width'], $d['height'], imagick::FILTER_LANCZOS, 1);
}
I'm looking forward to updating ImageMagick as soon as the fix hits the repos, but in the interim this works decently well, and with very little overhead. While I'm certain that it's there, I have not been able to perceive the loss in lightness / contrast fidelity from the compression or the loss in image quality from the resizing.
Post Reply