RetouchPRO

Go Back   RetouchPRO > Tools > Software
Register Blogs FAQ Site Nav Search Today's Posts Mark Forums Read


Software Photoshop, Lightroom, Paintshop Pro, Painter, etc., and all their various plugins. Of course, you can also discuss all other programs, as well.

FilterMeister - Color Theory and Conversions

Reply
 
Thread Tools
  #61  
Old 03-17-2006, 05:42 AM
Stroker's Avatar
Stroker Stroker is offline
Senior Member
 
Join Date: Jan 2005
Posts: 370
Nice catch with that pesky character. Wonder how that snuck in?

The last code does work as it should. It just doesn't work as most folks are used to. Hard to explain. If I think about it, I might be able to come with a way of explaining it.

Here comes a subject I adore.

Contrast is finding the difference and amplifying it. It can be anything you desire. Can be difference in saturation between subjects. Can be shades of red and shades of blue. A common use of contrast is Levels. Basically contrast between high/low in each seperate channel.

Earlier I showed how to get 3d mid-tones in Lab. You know, the distance from the center thing. With vectors and normals, you can actually move values away from the mid-tone center in a 3d manner. This is a form of contrast.

Very basic example for Lab:

Code:
%ffp

ctl(0):standard,"Amount",range=(-100,100),val=10,track
ctl(1):checkbox,"Absolute Distance",val=0

supportedmodes: labmode

ForEveryTile:{
int ll,aa,bb;
float distance,nx,ny,nz;

for(x=x_start;x<x_end;x++){
for(y=y_start;y<y_end;y++){

// grab values
// bother with 128 to make things easier
ll=src(x,y,0)-128;
aa=src(x,y,1)-128;
bb=src(x,y,2)-128;

// Pythagoras to get distance
distance=sqrt( (float)ll*ll + aa*aa + bb*bb);

//distance hack, move straight up
if(distance==0){
   nx=1;
   ny=0;
   nz=0;

}else{

// normalize the vector
   nx=ll/distance;
   ny=aa/distance;
   nz=bb/distance;

} // end distance hack

// add with option
if(ctl(1)==0){
// relative
   ll=ll+nx*ctl(0);
   aa=aa+ny*ctl(0);
   bb=bb+nz*ctl(0);
}else{
// absolute distance
   ll=nx*ctl(0);
   aa=ny*ctl(0);
   bb=nz*ctl(0);
}

// output, don't forget 128
pset(x,y,0,ll+128);
pset(x,y,1,aa+128);
pset(x,y,2,bb+128);

}} // y x

return true;
} // for every tile
With positive values for Amount, you will move values away from the center of the Lab sphere. With negative values for Amount, you will move values through the center and out the other side for an invert effect.

(If you want to, you don't have to push values away from the center. With some controls and offsetting, you can actually push values away from any given point. To tickle your brain, imagine using gravity instead of vectors. With gravity, you can pull towards and push away from several points. How would you like a magnet effect for contrast and colour balance?)

As the code is, it works just like Levels - except you are doing all 3 channels at once in a simple manner. Since this can be done with Levels, it may seem a bit silly. Believe me, it's not. This is just a building block.
Reply With Quote top
  #62  
Old 03-18-2006, 03:23 PM
Cameraken's Avatar
Cameraken Cameraken is offline
Senior Member
 
Join Date: Feb 2005
Location: Lancashire (UK)
Posts: 1,158
That works just fine Stroker, Thank you.
It sounds like there is better to come.


I found this great thread on HSB
http://photoshoptechniques.com/forum...t=10495&page=2

Pity I didn’t find it sooner. I may have won more cookies.

Ken.
Reply With Quote top
  #63  
Old 03-19-2006, 06:25 AM
Stroker's Avatar
Stroker Stroker is offline
Senior Member
 
Join Date: Jan 2005
Posts: 370
Dude, I haven't seen that thread in awhile. Now that's an old school rampage. If I remember correctly, I made some gnarly mistakes in that thread and had to do some follow-ups to ammend.

Let's talk about gradients some more.

With trigonometry you can do a lot of things with triangles, especially if they are right triangles. The Photoshop's Gradient tool is proof positive of this. How does the Gradient tool work? Vectors and trig.

When you drag a the Gradient tool, you are defining a 2d vector in screen space. Basically a position vector in x and y. As you go through the x and y loops, you use one point on the defined vector to define a second vector. Then you make it a right triangle. Using a simple formula, you can get another angle in the right triangle. After that, it should be cake to finish it up.

The forumula to get the angle is simply:
p1 * p2 = |p1| * |p2| * cos(angle)
cos(angle) = p1 * p2 / |p1| * |p2|
angle = acos( p1 * p2 / |p1| * |p2| )

Well, maybe not simply. Maybe if you read Understanding the Dot Product enough times will click. Or maybe the attached graphic will help.

The graphic attached shows distance along a vector. Just a simple percentage with the length of v1 = 100%. The length of p3 along v1 = 50%.

And that's how the Linear Gradient tool in Photoshop works.

Um, yeah.
Attached Images
File Type: jpg dalong.jpg (14.1 KB, 8 views)
Reply With Quote top
  #64  
Old 03-19-2006, 06:39 AM
Stroker's Avatar
Stroker Stroker is offline
Senior Member
 
Join Date: Jan 2005
Posts: 370
I mentioned that Levels is a common method for increasing contrast. Once in a great while I take issue with this. Why? Because each channel is done seperately and you end up with a square. If you do this in 3d space, you end up with a box.

While the two points and the line between maybe good and gradual, sometimes I don't like what happens to the rest of the space around the 'vector'.
Attached Images
File Type: jpg levelssquare.jpg (9.7 KB, 5 views)
Reply With Quote top
  #65  
Old 03-19-2006, 06:50 AM
Stroker's Avatar
Stroker Stroker is offline
Senior Member
 
Join Date: Jan 2005
Posts: 370
Why not create a gradient based on colour values instead of pos x and y? Why not make it 3d? Why not in Lab which is good for our eyes instead of RGB which is good for monitors?

Here is an early version of one of my personal filters that does just that.

Code:
%ffp

Category:"Tech Slop Lab"
Title:"3D Linear Grad"
Author:"JLHalmich"
Copyright: "2005 by JLHalmich"
Organization:"Tech Slop"
Version:"beta 1"
Filename: "TS_3dlineargrad.8bf"
Description: "Linear gradient in 3d Lab space"
About: "!t Plug-in !V\n!C\n!c\n!D"

SupportedModes: LabMode

dialog: size=(395,175)

ctl[CTL_OK]: MODIFY, pos=(315,155)
ctl[CTL_CANCEL]: MODIFY, pos=(355,155)

ctl(0):standard,"L",pos=(260,15),range=(0,255),val=25,track
ctl(1):standard,"a",pos=(260,25),range=(-127,127),val=-25,track
ctl(2):standard,"b",pos=(260,35),range=(-128,128),val=-25,track

ctl(3):standard,"L",pos=(260,65),range=(0,255),val=240,track
ctl(4):standard,"a",pos=(260,75),range=(-127,127),val=25,track
ctl(5):standard,"b",pos=(260,85),range=(-127,127),val=25,track

ctl(6):checkbox,"LL against Lightness",pos=(260,105)

ctl(7):groupbox,"Black", pos=(240,5),size=(150,45)
ctl(8):groupbox,"White",pos=(240,55),size=(150,45)

ctl(9):standard,"Blend",pos=(260,120),val=255,track

OnFilterStart:{
setPreviewCursor (32515);

return false;
}

OnCtl(n):{

if (e==FME_RIGHTCLICKED_DOWN && n==CTL_PREVIEW){
int x,y,ll,aa,bb;
x = getPreviewCoordX();//*scaleFactor;
y = getPreviewCoordY();//*scaleFactor;

ll=src(x,y,0);
aa=src(x,y,1)-128;
bb=src(x,y,2)-128;


if(getAsyncKeyState(VK_CONTROL)>=0){
// white
   setCtlVal(3,ll);
   setCtlVal(4,aa);
   setCtlVal(5,bb);
} else {
// black
   setCtlVal(0,ll);
   setCtlVal(1,aa);
   setCtlVal(2,bb);
}


doAction(CA_PREVIEW);
} // end right click

return false;
} // on ctl

ForEveryTile:{
int x,y,ll,aa,bb,c,a;
int final;
//float pi = 3.14159;

// p1 with normalization
int p1x,p1y,p1z;
float p1dist;
float p1nx,p1ny,p1nz;

//p2 without normalization
int p2x,p2y,p2z;
float p2dist;

// theta junk
float pretheta,theta;
float adj;

// can pre-calculate some junk before the loop

// do p1 with offset
p1x=ctl(3)-ctl(0);
p1y=ctl(4)-ctl(1);
p1z=ctl(5)-ctl(2);

// get length of p1
p1dist = sqrt( (float)p1x*p1x + p1y*p1y + p1z*p1z);

//normalize p1
p1nx=(float)p1x/p1dist;
p1ny=(float)p1y/p1dist;
p1nz=(float)p1z/p1dist;

for (y=y_start; y<y_end; y++){
//if(updateProgress(y,y_end)) abort();
for (x=x_start; x<x_end; x++){

c = srcp (x,y);

//Explode it into the color values
ll =  Rval(c); //c & 0xff;
aa =  Gval(c)-128; //c >> 8 & 0xff;
bb =  Bval(c)-128; //c >> 16 & 0xff;
//if (Z>3) a =  Aval(c); //c >> 24 & 0xff;

// p2
p2x=ll-ctl(0);
p2y=aa-ctl(1);
p2z=bb-ctl(2);

p2dist = sqrt( (float)p2x*p2x + p2y*p2y + p2z*p2z);

// get angle, aka theta
// don't forget: float and radians
// p1 * p2 = |p1| * |p2| * cos(angle)
// cos(angle)= p1 * p2 / |p1| * |p2|
pretheta=(p1x*p2x + p1y*p2y + p1z*p2z) / (p1dist*p2dist);
theta=acos(pretheta);

if(theta==0){ // theta hack, seems around 99.99%
   final=(p2dist/p1dist)*255;
}else{
// now solve to adj
   adj=fcos(theta)*p2dist;
   final=(adj/p1dist)*255;
}

// write the values back
if(doingProxy==false){
   if(ctl(6)==1){final=(final-ll)/2+128;}
   pset(x,y,0,final);
   pset(x,y,1,128);
   pset(x,y,2,128);
}else{

ll=blend(ll,final,0,0,ctl(9));
aa=blend(aa+128,128,0,0,ctl(9));
bb=blend(bb+128,128,0,0,ctl(9));

pset(x,y,0,ll);
pset(x,y,1,aa);
pset(x,y,2,bb);
}

}} // x y

return true;
} // for every pixel
With that code, I can create dichotomy between two colour values in 3d Lab space.

I originally wanted this for increasing contrast in fleshtones. As I got to playing with it, I was rather surprised at how well it works with a variety of photographs. For example, helping with desaturating photographs of sunsets with tricky hues.

Oh, I almost forgot. That code has some right-click functionality. Right click Preview to sample White. Ctrl + right click Preview to sample Black. Two other optional do-hickies which aren't too hard to figure out.
Reply With Quote top
  #66  
Old 03-19-2006, 07:15 AM
Stroker's Avatar
Stroker Stroker is offline
Senior Member
 
Join Date: Jan 2005
Posts: 370
Here's one to ponder.
Attached Images
File Type: jpg 3dgamma.jpg (9.3 KB, 13 views)
Reply With Quote top
  #67  
Old 03-19-2006, 08:10 PM
Cameraken's Avatar
Cameraken Cameraken is offline
Senior Member
 
Join Date: Feb 2005
Location: Lancashire (UK)
Posts: 1,158
The Rabbit hole gets deeper

Phew. You weren’t joking
There is some good stuff at the X-zone.
But I found this a little easier. Thanks to Philip Harrison
http://www.netsoc.tcd.ie/~jgilbert/m...t_product.html

When LW < LB the image goes negative (that’s understandable)
When LW > 200(approx) the image starts to get darker???

Right Click on Preview to sample White
Ctrl + right click Preview to sample Black
Alt + right click Preview seems to give threshold??
Sorry I can’t find another, I was expecting Mid Tones. And I can’t read the code
Oh dear. I’ve so much to learn.

Re the HSB thread.
I did read the follow up Addendums. It was good of you to add that. I don’t think many would have noticed

Vectors made easy
http://www.bbc.co.uk/schools/gcsebit...onshrev2.shtml
http://www.euclideanspace.com/maths/algebra/vectors/


Ken. (AKA March Hare)
Reply With Quote top
  #68  
Old 03-22-2006, 02:03 AM
Stroker's Avatar
Stroker Stroker is offline
Senior Member
 
Join Date: Jan 2005
Posts: 370
Vectors and things are cool, but can be hard to wrap around your head. I'm glad you found a link that makes more sense to you.

Visualize what's going on?

Imagine a sphere. This is the Lab sphere. In this sphere, pick two points. Between these two points in a vector and even a normal. If you can imagine it, visualize two planes in the sphere. Each of these planes are parallel to each other and will never touch each other. The two previously defined points are on these planes.
- between the planes, points closer to one plane will darker
- between the planes, points closer to the other plane will be brighter
- points not between the planes will be either black or white

It is a truly 3d gradient.

In the last code,
- right click sets the white point
- ctrl + right click sets the black point

However, alt + click will behave as right click and that probably explains the threshhold effect you are seeing. This is because the two points are rather close together. If you use Levels to set black and white really close together, what do you get? A threshhold effect.

Another little thing that I truly adore is Linear Light. Over 128 goes in one direction and less than 128 goes in the opposite direction. We can actually use the 3d gradient to push values away from each other in a linear 3d fashion. Use the vector/normal as a direction and the gradient as a magnitude. Using this method, it becomes almost trivial to boost contrast in subtle shades and things. Need a little more contrast between slightly red cheeks and slightly yellow jowel? Not a problem.

Early beta of just such a thing:

Code:
%ffp

SupportedModes: LabMode

dialog: size=(395,175)

ctl[CTL_OK]: MODIFY, pos=(315,155)
ctl[CTL_CANCEL]: MODIFY, pos=(355,155)

ctl(0):standard,"L",pos=(260,15),range=(0,255),val=25,track
ctl(1):standard,"a",pos=(260,25),range=(-127,127),val=-25,track
ctl(2):standard,"b",pos=(260,35),range=(-128,128),val=-25,track

ctl(3):standard,"L",pos=(260,65),range=(0,255),val=240,track
ctl(4):standard,"a",pos=(260,75),range=(-127,127),val=25,track
ctl(5):standard,"b",pos=(260,85),range=(-127,127),val=25,track

//ctl(6):checkbox,"LL against Lightness",pos=(260,105)

ctl(7):groupbox,"Black", pos=(240,5),size=(150,45)
ctl(8):groupbox,"White",pos=(240,55),size=(150,45)

//ctl(9):standard,"Offset",pos=(260,120),range=(-100,100),val=0,track
ctl(10):standard,"Expand",pos=(270,130),range=(-200,200),val=50,track

OnFilterStart:{
setPreviewCursor (32515);

return false;
}

OnCtl(n):{

if (e==FME_RIGHTCLICKED_DOWN && n==CTL_PREVIEW){
int x,y,ll,aa,bb;
x = getPreviewCoordX();//*scaleFactor;
y = getPreviewCoordY();//*scaleFactor;

ll=src(x,y,0);
aa=src(x,y,1)-128;
bb=src(x,y,2)-128;


if(getAsyncKeyState(VK_CONTROL)>=0){
// white
   setCtlVal(3,ll);
   setCtlVal(4,aa);
   setCtlVal(5,bb);
} else {
// black
   setCtlVal(0,ll);
   setCtlVal(1,aa);
   setCtlVal(2,bb);
}


doAction(CA_PREVIEW);
} // end right click

return false;
} // on ctl

ForEveryTile:{
int x,y,ll,aa,bb,c,a;
int final;
//float pi = 3.14159;

// p1 with normalization
int p1x,p1y,p1z;
float p1dist;
float p1nx,p1ny,p1nz;

//p2 without normalization
int p2x,p2y,p2z;
float p2dist;

// theta junk
float pretheta,theta;
float adj;

// can pre-calculate some junk before the loop

// do p1 with offset
p1x=ctl(3)-ctl(0);
p1y=ctl(4)-ctl(1);
p1z=ctl(5)-ctl(2);

// get length of p1
p1dist = sqrt( (float)p1x*p1x + p1y*p1y + p1z*p1z);

//normalize p1
p1nx=(float)p1x/p1dist;
p1ny=(float)p1y/p1dist;
p1nz=(float)p1z/p1dist;

for (y=y_start; y<y_end; y++){
//if(updateProgress(y,y_end)) abort();
for (x=x_start; x<x_end; x++){

c = srcp (x,y);

//Explode it into the color values
ll =  Rval(c); //c & 0xff;
aa =  Gval(c)-128; //c >> 8 & 0xff;
bb =  Bval(c)-128; //c >> 16 & 0xff;
//if (Z>3) a =  Aval(c); //c >> 24 & 0xff;

// p2
p2x=ll-ctl(0);
p2y=aa-ctl(1);
p2z=bb-ctl(2);

p2dist = sqrt( (float)p2x*p2x + p2y*p2y + p2z*p2z);

// get angle, aka theta
pretheta=(p1x*p2x + p1y*p2y + p1z*p2z) / (p1dist*p2dist);

// don't forget: float + radians
theta=acos(pretheta);

// solve for adj using theta
// conert to linear light form using *100-50
if(theta==0){ // theta hack, seems around 99.99%
   final=(p2dist/p1dist)*100-50;
}else{
// now solve to adj
   adj=fcos(theta)*p2dist;
   final=(adj/p1dist)*100-50;
}

// add it all up
ll=ll+p1nx*final*ctl(10)/100;
aa=aa+p1ny*final*ctl(10)/100;
bb=bb+p1nz*final*ctl(10)/100;

pset(x,y,0,ll);
pset(x,y,1,aa+128);
pset(x,y,2,bb+128);


}} // x y

return true;
} // for every pixel
I've been playing with that code for quite some time and it never ceases to amaze me.

Now, masking using trig in the Lab sphere is a lot of fun - doesn't have to be a point-to-point black-to-white gradient. I'll touch on this later.

(Roland, I got your message finally. I'll get back to you soon.)
Reply With Quote top
  #69  
Old 03-24-2006, 04:51 AM
Stroker's Avatar
Stroker Stroker is offline
Senior Member
 
Join Date: Jan 2005
Posts: 370
Meh. Getting sucked into other things. Some quick touchies from Uncle Stroker.

- Used Pythagoras to get distance from a point. Even did some pushing around.
- Used vectors/normals to get distance along a vector. Again, some pushing around.

To get the distance along the vector, used trig one way. However, you can get the distance from a vector using trig the other way. Instead of solving for adj, just solve for opp and go from there. Using this method, you can actually bore holes in the Lab sphere from one point to another. Instead of dichotomy, you are actually connecting. This is a good way of masking some vector operations.

Another good way to push values around or mask is to use theta. Instead of solving for adj or opp, just stop at theta and use that.

Once you start getting the hang of it, you can do some uber ChOps in 3d space. Do you want shades of orange that fade into magenta that are between the two? Not a problem. Harsh coloured lights causing extremely tinted highlights? Not a problem. That funky over-saturated event horizon? Not a problem.

(The event horizon thing is something that I had been wrestling with for quite some time. It's this funny space that exists between light and dark where the change takes place. I call it event horizon, but terminator might be more appropriate. Using trig in Lab, I have finally found a way to isolate it. So far just an annoying curiosity.)

Been getting sucked into several things. Of note, Hue and Sat in Lab space as Photoshop uses them. Been using theta and rho, but Photoshop cubes the sphere and things get funky. Haven't decided on a rampage yet. Another thing I've been messing with is manipulating Hue sort of like Levels. I've done this in RGB, but it is so much easier in Lab space with FM. It is very nice being able to manipulate tonal range in such a manner.

I haven't forgotten about you, Roland. I'm getting there.
Reply With Quote top
  #70  
Old 03-27-2006, 01:50 PM
Cameraken's Avatar
Cameraken Cameraken is offline
Senior Member
 
Join Date: Feb 2005
Location: Lancashire (UK)
Posts: 1,158
Thanks Stroker.

The effect of the Linear Light code can be quite subtle.

I am still having difficulty with this whole vector thing.
I am slowly working my way through this.
http://www.netcomuk.co.uk/~jenolive/vecfind.html


Ken.
Reply With Quote top
Reply

  RetouchPRO > Tools > Software


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Color Space conversions Reimar Photoshop Elements Help 4 01-16-2004 06:58 AM
Batch Raw conversions in PS CS okplayer Software 0 12-19-2003 01:03 PM


All times are GMT -6. The time now is 02:10 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
Copyright © 2016 Doug Nelson. All Rights Reserved