user3105222
user3105222

Reputation:

A module/script to get the table of all values from a points based smooth curve (RGB curves type of thing)

I would like to generate a table of values for an input/output curve from 0 to 255 based on specific points, and have that curve smooth.

It is basically the same thing we use when editing the brightness of a picture with RGB curves.

e.g. I would define the points 0,0 ; 128,104 ; 255,255 and I would get all values from 0 to 255 with something smooth (non-linear) around 128,104. I would eventually be able to configure how smooth that curve is.

I could program it but it seems like a little bit of pain and I'm quite sure something like this exists as a module or script already.

Thank you!

EDIT:

The answer from Benjamin W. produces the following result with the following code:

require Math::Spline;

my @x = (0, 64, 128, 204, 255);
my @y = (0, 12, 64, 224, 255);

$spline = Math::Spline->new(\@x,\@y);
for( my $a = 0 ; $a < 256 ; $a++ ){
    print("$a\t".$spline->evaluate($a)."\n");
}

gnuplot curve from this code

Upvotes: 1

Views: 285

Answers (1)

Benjamin W.
Benjamin W.

Reputation: 52152

Smoothly connecting points can be done by means of spline interpolation, where you calculate a piecewise polynomial. For Perl, there is the module Math::Spline.

For your example (slightly modified to make the "bend" better visible), it would roughly look like this:

use strict;
use warnings;
use feature 'say';
use Math::Spline;

my @x = (0, 210, 255);
my @y = (0, 124, 255);
my $spline = Math::Spline->new(\@x, \@y);

my @x_interp = (0 .. 255);
my @y_interp;
for my $x_i (@x_interp) {
    push @y_interp, $spline->evaluate($x_i);
}

say "$x_interp[$_]\t$y_interp[$_]" for (0 .. 255);

The output can be piped to a file and plotted, for example with gnuplot: spline

Upvotes: 2

Related Questions