Page 1 of 1

ImageMagick produces different results compared to GPUimage

Posted: 2015-10-06T09:04:21-07:00
by carlb
I'm currently using GPUimage to change the color(RGB) channels of images to produce "filter like" effects. The values I use for GPUImage are the X,Y values of the points of the color curve tool in photoshop. So for example I might have these points:

Photoshop curve tool. Please note that the image here doesn't represent
the current data points that I am using

Image
Red:
0,0
0.1176,0.0196
0.2275,0.098
0.3294,0.3333
0.4392,0.549
0.7451,0.8627
1,1
Green:
0,0
0.0784,0.0196
0.1961,0.2431
0.5176,0.5882
0.7451,0.8039
1,1
Blue:
0,0.2549
0.1569,0.3529
0.3333,0.451
0.8314,0.7255
1,0.8039
GPUImage handles these points without problems, however since Imagemagick doesn't support direct input of these values I have to convert each channel points to the curve's expression like this:

Code: Select all

Red: -237.407*u^6 + 634.277*u^5 - 615.934*u^4 + 261.501*u^3 - 44.054*u^2 + 2.617*u
Green: -32.880*u^5 + 80.544*u^4 - 68.222*u^3 + 22.707*u^2 - 1.148*u
Blue: -0.382*u^4 + 0.744*u^3 - 0.498*u^2 + 0.686*u + 0.255
**I am using the im_fx_curves script found here to convert the points to the expression.**

So my process would normally look like this:

Code: Select all

convert test_image.png \
\( -channel Red -fx "`perl im_fx_curves.pl 0,0 0.1176,0.0196 0.2275,0.098 0.3294,0.3333 0.4392,0.549 0.7451,0.8627 1,1`" \) \
\( -channel Green -fx "`perl im_fx_curves.pl 0,0 0.0784,0.0196 0.1961,0.2431 0.5176,0.5882 0.7451,0.8039 1,1`" \) \
\( -channel Blue -fx "`perl im_fx_curves.pl 0,0.2549 0.1569,0.3529 0.3333,0.451 0.8314,0.7255 1,0.8039`" \) result.png
These are the coefficients made by im_fx_curves with the -c option.

Code: Select all

R: -237.407,634.277,-615.934,261.501,-44.054,2.617,0.000
G: -32.880,80.544,-68.222,22.707,-1.148,-0.000
B: 0.263,0.041,-0.155,-0.155,0.652,0.255
However the results are slightly different. And I'm confused on why this is happening. I would gladly take any tips on what I might be doing wrong!

I've already using different options of colorspace but it mostly seem to make it worse.

This is the comparisation between the results where only GPUimage handles my curve points exactly like Photoshop:
Image
Desired result:
Image

Re: [Colorchannels] ImageMagick produces wrong results

Posted: 2015-10-06T09:27:56-07:00
by snibgo
Which GPU filter are you using? From the page you linked, https://github.com/BradLarson/GPUImage :
GPUImageToneCurveFilter: Adjusts the colors of an image based on spline curves for each color channel.
So the output will be created by joining together a number of spline curves.

By contrast, the im_fx_curves.pl script creates polynomials, so the entire output is built from a single expression.

In both cases, the resulting curve will pass through the control points. Between the points, the curves will be different.

As a general rule, I prefer spline curves for colour adjustment. Polynomial can give "crazy" results. I think Fred has a script for splines.

Re: [Colorchannels] ImageMagick produces wrong results

Posted: 2015-10-06T10:03:53-07:00
by fmw42
snibgo wrote: think Fred has a script for splines.
See my script curves at my link below. But note, that this may still differ from Photoshop and/or GIMP curves.

Re: [Colorchannels] ImageMagick produces wrong results

Posted: 2015-10-06T10:23:41-07:00
by Bonzo
The title of this thread made me laugh; why do people blame Imagemagick as it produces "different" results?

Re: [Colorchannels] ImageMagick produces wrong results

Posted: 2015-10-06T10:33:55-07:00
by carlb
snibgo wrote:Which GPU filter are you using? From the page you linked, https://github.com/BradLarson/GPUImage :
GPUImageToneCurveFilter: Adjusts the colors of an image based on spline curves for each color channel.
So the output will be created by joining together a number of spline curves.

By contrast, the im_fx_curves.pl script creates polynomials, so the entire output is built from a single expression.

In both cases, the resulting curve will pass through the control points. Between the points, the curves will be different.

As a general rule, I prefer spline curves for colour adjustment. Polynomial can give "crazy" results. I think Fred has a script for splines.

I'm using the GPUImageToneCurveFilter. However instead of using the Polynomials I decided to go with this method from michael.huber.1841 instead. Which makes the image identical to the GPUimage frameworks output.

Bonzo wrote:The title of this thread made me laugh; why do people blame Imagemagick as it produces "different" results?
I changed it, better now?

Re: ImageMagick produces weird results compared to GPUimage

Posted: 2015-10-06T11:08:28-07:00
by snibgo
carlb wrote:... I decided to go with this method from michael.huber.1841 instead.
Good stuff. You can append the gradient to the input with this (Windows BAT syntax):

Code: Select all

convert ^
  %1 ^
  -set option:size 1x%%[fx:w] ^
  ( gradient: -rotate 90 ) ^
  +swap ^
  -append ^
  editthis.png
... then edit the curves with Photoshop or whatever, being able to see what you are doing. Then extract the modified gradient and apply it to the image.

Code: Select all

convert ^
  editthis.png ^
  -crop x1+0+0 +repage ^
  +write x.png ^
  %1 ^
  +swap ^
  -clut ^
  out.png

Re: ImageMagick produces weird results compared to GPUimage

Posted: 2015-10-07T08:46:51-07:00
by snibgo
Just to say: if "-sparse-color" had an option for "spline", then IM could easily generate a clut from a set of (in,out) pairs. The "spline" option would create a 2-D spline image, though a clut needs only 1-D.

Re: ImageMagick produces weird results compared to GPUimage

Posted: 2015-10-07T09:21:39-07:00
by fmw42
Not all spline curves interpolate the same. So there is no guarantee that my curves spline or any potential IM spline would match the desired software. My curves spline is a Catmull-Rom spline.

P.S. I would not say that IM results are "weird", just different

P.S. 2 When using -clut, you have a choice of interpolation filters including spline. See -interpolate or

Code: Select all

convert -list intepolate