SRL Archive - OSR Advanced Scripting Tutorials

Introduction/Explanation of HSL color/Edge finding starter.


R0b0t1

2007-09-09 11:46:04

Welcome to the land of HSL!


You probably aren't asking "What is HSL color?" but anyway:

From: Wikiworld

The HSL color space, also called HLS or HSI, stands for Hue, Saturation, Lightness (also Luminance or Luminosity) / Intensity. While HSV (Hue, Saturation, Value) can be viewed graphically as a color cone or hexcone, HSL can be drawn as a double cone or double hexcone as well as a sphere. Both systems are non-linear deformations of the RGB colour cube.

The two apexes of the HSL double hexcone correspond to black and white. The angular parameter of the HSL double hexcone corresponds to hue, distance from the axis corresponds to saturation, and distance along the black-white axis corresponds to lightness.

HSL does not define colors exactly because, like RGB, it is not an absolute color space. Since the color of RGB depends on the exact shade of red, blue and green ("primaries") used, so HSL, which is a simple transformation of RGB, also depends on the primaries. Strictly speaking, it is not a color space but a color model. HSL can become an exact way to choose color when it is tied to a particular RGB color space, such as sRGB, perhaps specified with an RGB ICC profile. Another way to think about it is that each distinct RGB color space has its own HSL color space to accompany it.


Well… If you didn't get that:

From: r0b0t1

HSL color is just another way for defining color, almost like RGB, but much different. Hue is the base color (EX: Red, Green, Violet…), Saturation is the greyness (Basicly, how much color there is.), and Luminance, Light, or Lightness is how much white there is.


If you happen to like Wikipedia, type in "HSL color space" and you will be stupefied. So here is another of my spiels:

HSL is the main color space used by Adobe, the creator of PhotoShop, so it must be good. Other than that, you could use it for finding the ends of things, as the Hue (base color) will change drastically. Also you can use it for area detection (see Summilions post). You might want to think about it and find another use, but don't hurt yourself.

It is also the easiest way for me to comprehend color, besides CMYK (Different tutorial!). The last thing in this paragraph, is that it is the most commonly used color space, besides RGB, which is used commonly for auto coloring (Another tutorial!).


If you, the poor soul reading this, do not understand HSL still,


Hopefully that clears it up, if you still need help, PM me.


Now, the reason most people will read this, EDGE FINDING! YAY! Now then… This is the way we do things (This is my way, you can do it differently):

1). Find a color of an object to check for edges.
2). We make a "box" around that object (I will explain this).
3). Search the color again, with less tolerance, in that box.
4). Compare that color with some static numbers.
5). More boxes…
6). Say if it found and edge… (This would be the part where if it didn't, you would stop doing something or what ever)


Now, how we do this…


function FindMiddleObj(var ax1, ay1: Integer; TaColor, MinWid, MinHie: Integer):Boolean;
Declare a function.


Var
Cnt, x1, y1, x2, y2, sCnt, ssCnt: Integer;
ArrL: Array [0..1] of Extended;
Ho, So: Extended;
Declare variables…


If (ax1 < 10) Then ax1:= 10;
If (ay1 < 10) Then ay1:= 10;
Make sure our vairables are greater than ten.


If (FindColorSpiralTolerance(ax1, ay1, TaColor, ax1-10, ay1-10, ax1+10, 5)) and
(LoggedIn) Then
begin;
Search for the color in a box, around the color you specified.


For ssCnt:= 0 to 3 do
begin;
Cnt:= 0;
ColorToHSL(GetColor(ax1, ay1), Ho, So, ArrL[1]);
Make a loop, set one of our variables to zero, and turn the TaColor into HSL values.


If (ssCnt = 3) Then ax1:= x2 + x1 div 2;
repeat;
ArrL[0]:= ArrL[1];
Case ssCnt of
0: ColorToHSL(GetColor(ax1 - Cnt, ay1), Ho, So, ArrL[1]);
1: ColorToHSL(GetColor(ax1 + Cnt, ay1), Ho, So, ArrL[1]);
2: ColorToHSL(GetColor(ax1, ay1 - Cnt), Ho, So, ArrL[1]);
3: ColorToHSL(GetColor(ax1, ay1 + Cnt), Ho, So, ArrL[1]);
end;
Start a repeat loop, Make two values the same, and check the colors around our first color, depending on the loop number.


If (Hue > 14) and (Hue < 34) Then
begin;
If (ArrL[0] < ArrL[1] - 1.5) or
(ArrL[0] > ArrL[1] + 1.5) Then
sCnt:= 0;
else
inc(sCnt);
end else
inc(sCnt);
If the hues are similar, make sCnt zero, else, increment (add one) to sCnt.


If (sCnt = 3) Then
begin;
Case ssCnt of
0: x1:= ax1 - Cnt + 3;
1: x2:= ax1 + Cnt - 3;
2: y1:= ay1 - Cnt + 3;
3: y2:= ay1 + Cnt - 3;
end;
end;
inc(Cnt);
If sCnt is three, change the values of those variables.


until(Cnt = 60) or (sCnt = 3);
Now we end our repeat loop with a failsafe, and a "final" condition.


If (Cnt = 60) Then
begin;
Case ssCnt of
0: x1:= ax1 - Cnt;
1: x2:= ax1 + Cnt;
2: y1:= ay1 - Cnt;
3: y2:= ay1 + Cnt;
end;
end;
end;
If it stopped because of the failsafe ( Thats bad ), this will change the values… Again.


ay1:= y2 + y1 div 2;
If ((x2 - x1) * (y2 - y1) >= MinWid * MinHie) Then
Result:= True;
else
Result:= False;
end;
end;
This may be on of the more important parts, or more important for the user. If the edge is found outside of those parameters, then it will Result false, else, True.

Now for those that just want the code:


program New;
{.Include SRL/SRL.scar}

//You would want to call FindColorSpiralTolerance first and put the
//location of the color as "ax1" and "ay1".

function FindMiddleObj(var ax1, ay1: Integer; TaColor, MinWid, MinHie: Integer):Boolean;
Var
Cnt, x1, y1, x2, y2, sCnt, ssCnt: Integer;
ArrL: Array [0..1] of Extended;
Ho, So: Extended;
begin;
If (ax1 < 10) Then ax1:= 10;
If (ay1 < 10) Then ay1:= 10;
If (FindColorSpiralTolerance(ax1, ay1, TaColor, ax1-10, ay1-10, ax1+10, 5)) and
(LoggedIn) Then
begin;
For ssCnt:= 0 to 3 do
begin;
Cnt:= 0;
ColorToHSL(GetColor(ax1, ay1), Ho, So, ArrL[1]);
If (ssCnt = 3) Then ax1:= x2 + x1 div 2;
repeat;
ArrL[0]:= ArrL[1];
Case ssCnt of
0: ColorToHSL(GetColor(ax1 - Cnt, ay1), Ho, So, ArrL[1]);
1: ColorToHSL(GetColor(ax1 + Cnt, ay1), Ho, So, ArrL[1]);
2: ColorToHSL(GetColor(ax1, ay1 - Cnt), Ho, So, ArrL[1]);
3: ColorToHSL(GetColor(ax1, ay1 + Cnt), Ho, So, ArrL[1]);
end;
If (Hue > 14) and (Hue < 34) Then
begin;
If (ArrL[0] < ArrL[1] - 1.5) or
(ArrL[0] > ArrL[1] + 1.5) Then
sCnt:= 0;
else
inc(sCnt);
end else
inc(sCnt);
If (sCnt = 3) Then
begin;
Case ssCnt of
0: x1:= ax1 - Cnt + 3;
1: x2:= ax1 + Cnt - 3;
2: y1:= ay1 - Cnt + 3;
3: y2:= ay1 + Cnt - 3;
end;
end;
inc(Cnt);
until(Cnt = 60) or (sCnt = 3);
If (Cnt = 60) Then
begin;
Case ssCnt of
0: x1:= ax1 - Cnt;
1: x2:= ax1 + Cnt;
2: y1:= ay1 - Cnt;
3: y2:= ay1 + Cnt;
end;
end;
end;
ay1:= y2 + y1 div 2;
If ((x2 - x1) * (y2 - y1) >= MinWid * MinHie) Then
Result:= True;
else
Result:= False;
end;
end;

begin;
end.

I hope this helped you in some way… Although, that edge finding function may not be the best! (Its base stuff is from Lorax, I made it compatible with more than trees. i think…).


Please post!

Sumilion

2007-09-09 12:49:24

Hmm, is that based off SLFindMiddleOfTree ?

HSL can be used for more than just object finding.

First i thought it would be unstable to use it to detect if we are at the mine… but it seems quite stable actually :)

This is what i mean (this is meant for detecting if we are getting near the mine when walking from falador to rimmington mines) :

function SumFindMine: Boolean;
var
i: Integer;
arMinimapColors: TIntegerArray;
H, S, L, S2: Extended;
begin
arMinimapColors := GetColors(MinimapArray);
for i := 0 to Length(arMinimapColors) - 1 do
begin
ColorToHSL(arMinimapColors[i], H, S, L);
S2 := S2 + S;
end;
S2 := S2 / Length(arMiniMapColors);
Result := (S2 > 55.0);
end;

MinimapArray is a TPointArray of all MinimapPoints.

It detects if we are in the mine at almost the same point in every world. This made it very easy for me to make good autocoloring too since you know your near the rocks you want to autocolor.

The way it thinks is that when your getting near the mine the environment starts to get darker, more orangy… that is most constantly found in Saturation, so when S2 (the average Saturation of the entire minimap) is above 55.0 it thinks its near the mine.

R0b0t1

2007-09-09 13:00:44

Ahhh. Thats nice :). I guess I can add area detection to the list also!



EDIT: Yes, its based off of that. But it says that under the code :p.

GoF

2007-09-10 10:31:52

Awesome! Exactly what I was looking for ;) Cause Lorax' tut wasn't too clear :p

R0b0t1

2007-09-10 17:33:23

Your welcome GoF :).

n3ss3s

2007-09-12 12:09:31

Im trying to learn hsl, but the variable names in every tutorial are a bit confusing.

So what Im looking for is a function that, comments of everything, and clearer variable names ;)

R0b0t1

2007-09-12 21:04:41

Uhhh….

Do you know anything of cyptology? Lol.

You should be able to figure it out. If you want to, that is. I said PM or MSN me for help.