| Notices | Welcome to RetouchPRO . You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload images and access many other special features. Registration is fast, simple and absolutely free so please, join our community today! If you have any problems with the registration process or your account login, please contact contact us. | | Software Photoshop, Paintshop Pro, Painter, etc., and all their various plugins. Of course, you can also discuss all other programs, as well. | 
03-08-2006, 08:46 PM
|  | Moderator | | Join Date: May 2004 Location: Goiânia, Brazil
Posts: 1,549
| | Ken,
The good news: You are not going crazy. Your code is correct.
The bad news: Photoshop gradients are not linear
Put an eyedropper at the transition lines, then go back and see what the readings are at these points in the original gradient.
The channel values will fit in fine. However, they are not at 1/3 intervals.
Maybe stroker can explain to us why that happens.
Meanwhile, if you want to generate a perfectly linear gradient, then do it with FM!!
Rô | 
03-08-2006, 09:41 PM
|  | Senior Member | | Join Date: Jan 2005
Posts: 313
| | When you lay the gradient, make sure Smoothness is set to 0%.
Smoothness 0% = linear interpolation
Smoothness 100% = b-spline interpolation
This tid-bit took me a long time to figure out. Chris Cox of Adobe confirmed, and you can see this for yourself with a little help from Histogram. Since then, whenever I lay a gradient, I *always* double-check Smoothness.
Gonna hide under my rock again for a bit.
edit:
Roland, how good are you with geo/trig? Basic 3D Math
Yeah, I got something brewing, but ran into a funky anomoly.
Last edited by Stroker; 03-08-2006 at 10:30 PM.
| 
03-09-2006, 05:08 AM
|  | Moderator | | Join Date: May 2004 Location: Goiânia, Brazil
Posts: 1,549
| | Thanks, stroker.
I knew you'd have something interesting to add.
Problem is, I can't see how that works out.
The smoothness setting is in the Gradient Map editor. Setting this to "0" really does explain a whole bunch of quirky things that I'd seen on the past.
The Gradient Map, however, does not generate the gradient, just translates it.
So the question stands, how can I generate a black-to-white linear (as in "x" vs. R,G,B) gradient? (in PS, without resorting to FM?)
.....or, maybe I missed something.
(Trigonometry and 3D math never were my favourites - but I can usually muddle my way through. - What's up?)
Rô | 
03-09-2006, 12:32 PM
|  | Senior Member | | Join Date: Jan 2005
Posts: 313
| | | Gradient tool has Smoothness as well. When you lay down the initial gradient with the tool, make sure it is Smoothness 0 right from the begining.
Yes?
Meh. Don't worry about the geo/trig thing. Gonna put it on the back burner for a few. | 
03-09-2006, 07:27 PM
|  | Senior Member | | Join Date: Feb 2005 Location: Lancashire (UK)
Posts: 1,112
| | | Thanks.
The Gradient Was the problem. I set the Smoothness to Zero and my code works fine.
(Smoothness is in the same place as when using Gradient Map – Click on the Gradient)
This does explain a lot. I have been setting Smoothness to Zero when putting Sat back without realising the reason why.
Ken | 
03-10-2006, 04:24 AM
|  | Moderator | | Join Date: May 2004 Location: Goiânia, Brazil
Posts: 1,549
| | Quote: |
Originally Posted by Cameraken Smoothness is in the same place as when using Gradient Map – Click on the Gradient | (insert here a couple of smileys smacking themselves on the forehead)
Thanks, Ken. (insert a couple more here )
Rô | 
03-11-2006, 08:28 AM
|  | Senior Member | | Join Date: Jan 2005
Posts: 313
| | Lab is a sphere. Lab is Cartesian. This good for a lot of simple tricks that just plain rock.
Basically use Pythagoras to measure distance from the center of the Lab sphere. The ranges are 0 to 255 with the center at 128. But because of the math involved, better to offset for a range of -128 to 127. This means that the maximum distance will be 128. Have to multiply that by 2 to get back to 0 to 255.
This isn't exactly mid-tone as most are used to. This is more of a 3d mid-tone and is quite different from Colour Range. Personally, I adore it. Plus this is the beginning of some cool Lab tricks. Code: %ffp
SupportedModes: LABMode
ForEveryTile:{
int x,y,ll,aa,bb;
float dx,dy,dz;
float dist;
int final;
for (y=y_start; y<y_end; y++){
//if(updateProgress(y,y_end)) abort();
for (x=x_start; x<x_end; x++){
// grab values and normalize to 0
ll=src(x,y,0)-128;
aa=src(x,y,1)-128;
bb=src(x,y,2)-128;
// get delta and convert to float
dx=(float)ll;
dy=(float)aa;
dz=(float)bb;
// pythagoras
dist=sqrt(dx*dx + dy*dy + dz*dz);
// convert, invert, and multiply by 2
final=255-(int)dist*2;
// output to greyscale
pset(x,y,0,final);
pset(x,y,1,128);
pset(x,y,2,128);
}} // x,y
return true;
} // for every tile
| 
03-12-2006, 10:52 AM
|  | Senior Member | | Join Date: Jan 2005
Posts: 313
| | Pretty much the same above but with a little extra junk. Just added some controls to define the center of the greyscale. Few other minor changes.
As it is, it is pretty good as a simple colour range do-hickey.
Things you may want to add:
- controls to level the greyscale
- right-click Preview to set controls Code: %ffp
ctl(0):"L",range=(0,255),val=128,track
ctl(1):"a",range=(-128,127),val=0,track
ctl(2):"b",range=(-128,127),val=0,track
ctl(3):checkbox,"Invert",val=0
SupportedModes: LABMode
ForEveryTile:{
int x,y,ll,aa,bb;
float dx,dy,dz;
float dist;
int final;
for (y=y_start; y<y_end; y++){
//if(updateProgress(y,y_end)) abort();
for (x=x_start; x<x_end; x++){
// grab values and normalize to 0
ll=src(x,y,0);
aa=src(x,y,1)-128;
bb=src(x,y,2)-128;
// get delta and convert to float
dx=ll-ctl(0);
dy=aa-ctl(1);
dz=bb-ctl(2);
// pythagoras
dist=sqrt(dx*dx + dy*dy + dz*dz);
// convert, invert, and multiply by 2
final=255-(int)dist*2;
// output to greyscale
if(ctl(3)==1){final=255-final;}
pset(x,y,0,final);
pset(x,y,1,128);
pset(x,y,2,128);
}} // x,y
return true;
} // for every tile
Basic Pythagoras was fun. How about some polar next? | 
03-13-2006, 06:47 AM
|  | Senior Member | | Join Date: Jan 2005
Posts: 313
| | Let's get a little polar in Lab space.
Rather than use Pythagoras and trig functions, going to use FM's built-in polar functions. I believe these polar functions can be found in UserGuide.pdf near the trig functions. Code: %ffp
ctl(0):checkbox,"L* = 128",val=0
supportedmodes: labmode
ForEveryTile:{
int x,y;
int ll,aa,bb;
int theta,rho,maxrho;
for (y=y_start; y<y_end; y++){
//if(updateProgress(y,y_end)) abort();
for (x=x_start; x<x_end; x++){
// grab values
//ll=src(x,y,0);
aa=src(x,y,1)-128;
bb=src(x,y,2)-128;
// convert to polar
theta=c2d(aa,bb);
//rho=c2m(aa,bb);
rho=127;
// back to Cartesian
aa=r2x(theta,rho);
bb=r2y(theta,rho);
// output with L* option
if(ctl(0)==1){pset(x,y,0,128);}
pset(x,y,1,aa+128);
pset(x,y,2,bb+128);
}}// x, y
return true;
} // for every tile
| 
03-13-2006, 02:50 PM
|  | Senior Member | | Join Date: Feb 2005 Location: Lancashire (UK)
Posts: 1,112
| | Quote: |
Basic Pythagoras was fun. How about some polar next?
| OK Great. I hope you can show some uses for Lab.
The code from post 90 is like a channel mixer with monochrome checked. Which is useful as the channel mixer is grayed out in Lab.
Post 91.
Stroker. Could you explain what this code is doing please? It looks like hue.
The Polar functions are in the user guide on page 28
Polar coordinate functions r2x(d,m), r2y(d,m), c2d(x,y), c2m(x,y)
There is also some sample code to convert RGB to Lab (RGB_to_Lab_and_back.ffp). Does this work as well as using PS?
Ken | 
03-14-2006, 07:24 AM
|  | Senior Member | | Join Date: Jan 2005
Posts: 313
| | | Okay, Lab is Cartesian. Uses x, y, and maybe even z. Imagine a square or a cube.
HSL et al are polar. These are things that are round. Angles and magnitudes. Theta and rho. Cylinders, spheres, and cones.
Even though Lab is a sphere, it is Cartesian. This leads to some interesting things. For example, if you want to rotate hue in Lab like you would in HSL, you have to convert to a polar system, and then convert back to Cartesian. Covnerting back and forth between Cartesian and polar is basic trigonometry.
One of the very basic things to know is Pythagoras' Formula. I'm sure you've seen this.
a^2 + b^2 = c^2
That will give us the distance, magnitude, or rho between origin and an arbitrary point. In colour systems, this is commonly called saturation. No matter the name, it's all effectively the same.
In post 90, we used Pythagoras to get 3d distance from the center, which is 50% grey.
a^2 + b^2 + c^2 = r^2
r = sqr( a*a + b*b + c*c )
To get the distance between two arbitrary 3d points, it would look something like this:
(x2-x1)^2 + (y2-y1)^2 + (z2+z1)^2 = r^2
r = sqr( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1) )
In Lab space, this is an excellant trick for converting colour ranges to greyscale. With a little savvy, I find this method better than Photoshop's own Select > Colour Range.
Now, post 91 is also a trick of trig, but with a focus on polar instead of just Pythagoras.
theta = hue
rho = saturation
Convert a and b to theta and rho, set rho to a given value, convert back to a and b. What you are effectively doing is setting saturation to a fixed number. The code basically says set saturation to 127. It is doing this in Lab space using a polar system.
Few more tricks, then the rabbit hole is going to get deep again. | 
03-14-2006, 08:28 AM
|  | Senior Member | | Join Date: Jan 2005
Posts: 313
| | | Almost forgot about rgb2lab and lab2rgb.
For the majority of applications, they work fine. However, be aware that you might run into some shifts due to gamma. Largely negligable, but might make a difference if you are into the device independance thing in Lab. | 
03-15-2006, 01:19 PM
|  | Senior Member | | Join Date: Feb 2005 Location: Lancashire (UK)
Posts: 1,112
| | Thank You for the explanation Stroker.
I’m just about keeping up. But I’m having to do a lot of searching.
Further Math’s ‘A’ Level was a Long Long time ago and now I can’t find my log books. http://en.wikipedia.org/wiki/Lab_color_space
The more I play with the greyscale converter – The more I like it. Another one for my Toolbox.
Ken | 
03-15-2006, 11:38 PM
|  | Senior Member | | Join Date: Jan 2005
Posts: 313
| | Polar is good. But let's try something a little bit different.
To do colour balance in Lab, you just add to a and b channels. There is a way of doing this that is similiar to polar but remains in Cartesian.
Gradient
This is simply an amount. That's it. Displace works by using an x gradient and a y gradient. You know, move things up/down using this gradient and move things left/right using that gradient.
Vector
More than one gradient. All gradients at 90 degrees to each other. For example, ( x+3, y-5) is a vector. So is ( x-2, y+10, z+3).
Normal
A normal is a vector with a unit length of 1. If you use Pythagoras to get the distance of a normal, it will be 1. I guess you can think of a normal as an angle using two (or more) numbers. Or something like that.
Rough analogy:
- hue = x grad and y grad as a normal
- sat = amount to travel in the direction of the normal
Now, it is possible to convert a vector to a normal. This is done simply by dividing each axis by the distance.
x=3
y=-4
distance=5
x grad = 3/5 = 0.6
y grad = -4/5 = -0.8
0.6^2 + -0.8^2 = 1^2
0.36 + 0.64 = 1
Any distance you multiply by 0.6 and -0.8 will go in the same direction as the original 3 and -4.
Cool beans.
Here is a simple example using that junk to colour balance in Lab. Code: %ffp
ctl(0):standard,"x grad",range=(-100,100),val=10,track
ctl(1):standard,"y grad",range=(-100,100),val=10,track
ctl(2):standard,"u",range=(-100,100),val=10,track
ctl(3):checkbox,"Colourize",val=0
supportedmodes: labmode
ForEveryTile:{
int aa,bb,adda,addb;
float distance,nx,ny;
for(x=x_start;x<x_end;x++){
for(y=y_start;y<y_end;y++){
// grab values
// not going to bother with 128
aa=src(x,y,1);
bb=src(x,y,2);
// Pythagoras to get distance
distance=sqrt( (float)ctl(0)*ctl(0) + ctl(1)*ctl(1) );
// normalize the vector
nx=ctl(0)/distance;
ny=ctl(1)/distance;
// amount to add to each axis
adda=ctl(2)*nx;
addb=ctl(2)*ny;;
// output with option
if(ctl(3)==0){l
pset(x,y,1,aa+adda);
pset(x,y,2,bb+addb);
}else{
pset(x,y,1,adda+128);
pset(x,y,2,addb+128);
}
}} // y x
return true;
} // for every tile
Kind of a weird way of going about it, but it has advantages. | 
03-16-2006, 02:29 PM
|  | Senior Member | | Join Date: Feb 2005 Location: Lancashire (UK)
Posts: 1,112
| | Stroker
There is an error in the above code Code: // output with option
if(ctl(3)==0){l
I changed it to Does that look correct?
Changing that seems to get the colourize working.But I don’t think its doing what it should.
Ken |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | All times are GMT -6. The time now is 11:17 PM. | |
|