Negaal
03-04-2008, 06:42 PM
ColorToleranceSpeed 2
Ok, here we go.
ColorToleranceSpeed 2 is used to find colors between several colors.
The color itself is bit special aswell.
It's been combined using 2 or more colors picked from object.
ColorToleranceSpeed is called as CTS in further.
These are CTS2 procedures
procedure ColorToleranceSpeed(x: Integer);
Sets the speed of tolerance comparisons.
ColorToleranceSpeed(1) is a little slower then 0 but more accurate.
ColorToleranceSpeed(0) is faster but not as accurate as 1.
ColorToleranceSpeed(2) uses Hue, Saturation and Lightness to determine color similarity.
function GetColorToleranceSpeed: Integer;
Returns the current tolerancespeed.
procedure SetColorspeed2Modifiers(huemodifier, saturationmodifier: Extended);
These work when ColorToleranceSpeed(2) has been set.
Normally Tolerance parameter in this mode applies to Luminance directly.
For an example, SimilarColors(c1, c2, 10) would work if both colors differ by 10 max luminance.
After calling SetColorspeed2Modifiers(0.2, 2) it would mean that SimilarColors(c1, c2, 10) would
check for Hue in range of 2 and Saturation in range of 20. Default huemodifier and saturationmodifier is 0.2.
First one speaks for itself.
Second one is needed to set back original CTS.
Example, IsUpText doesn't work when CTS is 2.
Or you can simply set it to 1 after your colorfinding.
Example
function FindC(x, y, Color : integer) : boolean;
var
CTS, I, L : Integer;
TPA : TpointArray;
begin
CTS := GetColorToleranceSpeed;
Colortolerancespeed(2)
SetColorspeed2Modifiers(0.123, 0.321);
FindColorsTolerance(TPA, Color, 0, 0, 100, 100, 10);
SetColorspeed2Modifiers(0.2, 0.2);
Colortolerancespeed(CTS)
L := High(TPA)
For I := 0 to L do
begin
MMouse(TPA[i].x, TPA[i].y, 5, 5)
if IsUpText('blah') then
begin
x := TPA[i].x;
y := TPA[i].y;
Result := True
Exit;
end;
end;
end;
If we will remove "Colortolerancespeed(CTS)" then this function will never return true.
Also set the CTS2 modifiers back to default, both 0,2.
Third, sets the saturation and hue modifier.
Now there is a question how to set? Which ones are best?
It all depends about differance of colors.
Some sort of max, min and differ HSL(Hue, Sat, Luminance) writelner is needed now.
Let's take mastaraymonds one. Also let's hope he won't kill me:eek:.
Edit: Or use that one what Mastaraymond posted below.
program New;
//By Mastaraymond
//0 = Min
//1 = Max
var
I,II : integer;
RGBColor : Array[1..3] of Integer;
RGB : Array[0..1] of Array[1..3] of Integer;
XYZColor, HSLColor : Array[1..3] of Extended;
HSL,XYZ : Array[0..1] of Array[1..3] of Extended;
Colors : TIntegerArray;
Strings : Array[0..9] of String;
Procedure Init;
begin;
Colors := [];
end;
begin
Init;
For I:= 1 to 3 do
begin;
Writeln('');
RGB[0][i] := 255;
HSL[0][i] := 255; //Max is 240?
XYZ[0][i] := 255; //Max is ...?
end;
Strings[1] := 'R: ';
Strings[0] := ' ';
Strings[2] := 'G: ';
Strings[3] := 'B: ';
Strings[4] := 'H: ';
Strings[5] := 'S: ';
Strings[6] := 'L: ';
Strings[7] := 'X: ';
Strings[8] := 'Y: ';
Strings[9] := 'Z: ';
For I:= 0 to High(Colors) do
begin;
Strings[0] := Strings[0] + Padr('Color: '+inttostr(Colors[i]),16) +' | ';
ColortoRGB(Colors[i],RGBColor[1],RGBColor[2],RGBColor[3]);
ColortoHSL(Colors[i],HSLColor[1],HSLColor[2],HSLColor[3]);
ColortoXYZ(Colors[i],XYZColor[1],XYZColor[2],XYZColor[3]);
For II:= 1 to 3 do
begin;
RGB[0][II] := Min(RGBColor[II],RGB[0][II]);
RGB[1][II] := Max(RGBColor[II],RGB[1][II]);
HSL[0][II] := MinE(HSLColor[II],HSL[0][II]);
HSL[1][II] := MaxE(HSLColor[II],HSL[1][II]);
XYZ[0][II] := MinE(XYZColor[II],XYZ[0][II]);
XYZ[1][II] := MaxE(XYZColor[II],XYZ[1][II]);
end;
For II := 1 to 3 do
Strings[II] := Strings[II] +Padr(IntToStr (RGBColor[II]),16) +' | ';
For II := 4 to 6 do
Strings[II] := Strings[II] +Padr(FloatToStr(HSLColor[II-3]),16) +' | ';
For II := 7 to 9 do
Strings[II] := Strings[II] +Padr(FloatToStr(XYZColor[II-6]),16) +' | ';
end;
For I:= 0 to 9 do
Delete(Strings[i],Length(Strings[i])-2,3);
For I:= 0 to 9 do
begin;
if (I = 1) or (I = 4)or (I = 7) then Writeln('');
Writeln(Strings[i]);
end;
Writeln('');
Writeln('Highest RGB values = R: '+ Padr(FloatToStr(RGB[1][1]),3) + ' | ' +'G: '+ Padr(FloatToStr(RGB[1][2]),3) + ' | ' +'B: '+ Padr(FloatToStr(RGB[1][3]),3) );
Writeln('Lowest RGB values = R: '+ Padr(FloatToStr(RGB[0][1]),3) + ' | ' +'G: '+ Padr(FloatToStr(RGB[0][2]),3) + ' | ' +'B: '+ Padr(FloatToStr(RGB[0][3]),3) );
Writeln('Differ RGB values = R: '+ Padr(IntToStr(RGB[1][1] - RGB[0][1]),3) + ' | G: '+ Padr(inttostr(RGB[1][2] - RGB[0][2]) ,3) + ' | B: '+Padr(inttostr(RGB[1][3] - RGB[0][3]),3));
Writeln('Middle RGB values = R: '+ Padr(IntToStr((RGB[1][1] + RGB[0][1]) div 2),3) + ' | G: '+ Padr(inttostr((RGB[1][2] + RGB[0][2]) div 2),3) + ' | B: '+Padr(inttostr((RGB[1][3] + RGB[0][3]) div 2),3));
Writeln('Middle RGB color = ' + IntToStr(RGBToColor((RGB[1][1] + RGB[0][1]) div 2,(RGB[1][2] + RGB[0][2]) div 2,(RGB[1][3] + RGB[0][3]) div 2)));
Writeln('');
Writeln('Highest HSL values = H: '+ Padr(FloatToStr(HSL[1][1]),16) + ' | ' +'S: '+ Padr(FloatToStr(HSL[1][2]),16) + ' | ' +'L: '+ Padr(FloatToStr(HSL[1][3]),16) );
Writeln('Lowest HSL values = H: '+ Padr(FloatToStr(HSL[0][1]),16) + ' | ' +'S: '+ Padr(FloatToStr(HSL[0][2]),16) + ' | ' +'L: '+ Padr(FloatToStr(HSL[0][3]),16) );
Writeln('Differ HSL values = H: '+ Padr(FloatToStr(HSL[1][1] - HSL[0][1]),16) + ' | S: '+ Padr(FloatToStr(HSL[1][2] - HSL[0][2]) ,16) + ' | L: '+Padr(FloatToStr(HSL[1][3] - HSL[0][3]),16));
Writeln('Middle HSL values = H: '+ FloatToStr((HSL[1][1] + HSL[0][1]) div 2) + ' | S: '+ FloatToStr((HSL[1][2] + HSL[0][2]) div 2) + ' | L: '+FloatToStr((HSL[1][3] + HSL[0][3]) div 2));
Writeln('Middle HSL color = ' + IntToStr(HSLToColor((HSL[1][1] + HSL[0][1]) div 2,(HSL[1][2] + HSL[0][2]) div 2,(HSL[1][3] + HSL[0][3]) div 2)));
Writeln('');
Writeln('Highest XYZ values = X: '+ Padr(FloatToStr(XYZ[1][1]),16) + ' | ' +'Y: '+ Padr(FloatToStr(XYZ[1][2]),16) + ' | ' +'Z: '+ Padr(FloatToStr(XYZ[1][3]),16) );
Writeln('Lowest XYZ values = X: '+ Padr(FloatToStr(XYZ[0][1]),16) + ' | ' +'Y: '+ Padr(FloatToStr(XYZ[0][2]),16) + ' | ' +'Z: '+ Padr(FloatToStr(XYZ[0][3]),16) );
Writeln('Differ XYZ values = X: '+ Padr(FloatToStr(XYZ[1][1] - XYZ[0][1]),16) + ' | Y: '+ Padr(FloatToStr(XYZ[1][2] - XYZ[0][2]) ,16) + ' | Z: '+Padr(FloatToStr(XYZ[1][3] - XYZ[0][3]),16));
Writeln('Middle XYZ values = X: '+ FloatToStr((XYZ[1][1] + XYZ[0][1]) div 2) + ' | Y: '+ FloatToStr((XYZ[1][2] + XYZ[0][2]) div 2) + ' | Z: '+FloatToStr((XYZ[1][3] + XYZ[0][3]) div 2));
Writeln('Middle XYZ color = ' + IntToStr(XYZToColor((XYZ[1][1] + XYZ[0][1]) div 2,(XYZ[1][2] + XYZ[0][2]) div 2,(XYZ[1][3] + XYZ[0][3]) div 2)));
WritelN('');
end.
"Colors := [];"
See this? Here you need to enter the colors you pick from object. Seperate with comma.
e.g. "Colors := [123,1234,12345];"
Try to pick much different colors as you can if there are not same coloured object nearby.
Try to pick 5 or more if possible.
Enter them and press run.
Scroll up where are HSL ranges.
We find hue, saturation and tolerance using differ.
Tolerance = luminance differ
Huemod = hue differ / lum difffer
Satmod = sat differ / lum differ
Color - Hue * Sqrt(Luminance) / Sat... No for god sake! It's middle HSL color
See the example.
Highest HSL values = H: 55,9523820877075 | S: 29,1666656732559 | L: 35,2941185235977
Lowest HSL values = H: 55,0505042076111 | S: 19,2052990198135 | L: 9,41176488995552
Differ HSL values = H: 0,901877880096436 | S: 9,96136665344238 | L: 25,8823536336422
Middle HSL values = H: 55,5014431476593 | S: 24,1859823465347 | L: 22,3529417067766
Middle HSL color = 4668971
Hue mod - 0.9 = 0.036 - Thats not good if it's under 0.1 or so.
I suggest you to just make it to 0.1 if it's lower than that.
Sat - 9.961 = 0,4
Tolerance = 25
Color - 4668971
Here, try this one some rune item(s).
function FindIt(var x, y : integer) : Boolean;
var
TPA : TPointArray;
ATPA : T2DPointArray;
I, CTS, L : integer;
begin
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.1, 0.4);
FindColorsTolerance(TPA, 4668971, MSX1, MSY1, MSX2, MSY2, 25);
SetColorspeed2Modifiers(0.2, 0.2);
ColorToleranceSpeed(CTS);
ATPA := SplitTPAEx(TPA, 5, 5);
SortATPAFrom(ATPA, IntToPoint(MSCX, MSCY));
L := High(ATPA)
For i := 0 to L do
if Length(ATPA[i]) >= 100 then
begin
MiddleTPAEx(ATPA[i], x, y);
MMouse(x, y, 5, 5);
Wait(50 + random(50));
if (pos('une', rs_GetUpText) > 0) then
begin
GetMousePos(x, y);
Result := True;
Exit;
end;
end;
end;
Result:
http://i28.tinypic.com/2a9aeko.jpg
Instead of finding some few pixels it finds all of them.
Edit: Also note that I didn't do it in MS Paint, Wizzup's DebugATPA ftw!
So this is all.
Note that I didn't learned this myself.
Main helpers were Nielsie and Markus,
I'd wish to thank them now:)
Oh, also when I finished this tutorial I noticed Nielsie and Sumilion released ACA2 what turned my tutorial kinda pointless. Hope that someone still gets something out of it.
Have fun ;)
Ok, here we go.
ColorToleranceSpeed 2 is used to find colors between several colors.
The color itself is bit special aswell.
It's been combined using 2 or more colors picked from object.
ColorToleranceSpeed is called as CTS in further.
These are CTS2 procedures
procedure ColorToleranceSpeed(x: Integer);
Sets the speed of tolerance comparisons.
ColorToleranceSpeed(1) is a little slower then 0 but more accurate.
ColorToleranceSpeed(0) is faster but not as accurate as 1.
ColorToleranceSpeed(2) uses Hue, Saturation and Lightness to determine color similarity.
function GetColorToleranceSpeed: Integer;
Returns the current tolerancespeed.
procedure SetColorspeed2Modifiers(huemodifier, saturationmodifier: Extended);
These work when ColorToleranceSpeed(2) has been set.
Normally Tolerance parameter in this mode applies to Luminance directly.
For an example, SimilarColors(c1, c2, 10) would work if both colors differ by 10 max luminance.
After calling SetColorspeed2Modifiers(0.2, 2) it would mean that SimilarColors(c1, c2, 10) would
check for Hue in range of 2 and Saturation in range of 20. Default huemodifier and saturationmodifier is 0.2.
First one speaks for itself.
Second one is needed to set back original CTS.
Example, IsUpText doesn't work when CTS is 2.
Or you can simply set it to 1 after your colorfinding.
Example
function FindC(x, y, Color : integer) : boolean;
var
CTS, I, L : Integer;
TPA : TpointArray;
begin
CTS := GetColorToleranceSpeed;
Colortolerancespeed(2)
SetColorspeed2Modifiers(0.123, 0.321);
FindColorsTolerance(TPA, Color, 0, 0, 100, 100, 10);
SetColorspeed2Modifiers(0.2, 0.2);
Colortolerancespeed(CTS)
L := High(TPA)
For I := 0 to L do
begin
MMouse(TPA[i].x, TPA[i].y, 5, 5)
if IsUpText('blah') then
begin
x := TPA[i].x;
y := TPA[i].y;
Result := True
Exit;
end;
end;
end;
If we will remove "Colortolerancespeed(CTS)" then this function will never return true.
Also set the CTS2 modifiers back to default, both 0,2.
Third, sets the saturation and hue modifier.
Now there is a question how to set? Which ones are best?
It all depends about differance of colors.
Some sort of max, min and differ HSL(Hue, Sat, Luminance) writelner is needed now.
Let's take mastaraymonds one. Also let's hope he won't kill me:eek:.
Edit: Or use that one what Mastaraymond posted below.
program New;
//By Mastaraymond
//0 = Min
//1 = Max
var
I,II : integer;
RGBColor : Array[1..3] of Integer;
RGB : Array[0..1] of Array[1..3] of Integer;
XYZColor, HSLColor : Array[1..3] of Extended;
HSL,XYZ : Array[0..1] of Array[1..3] of Extended;
Colors : TIntegerArray;
Strings : Array[0..9] of String;
Procedure Init;
begin;
Colors := [];
end;
begin
Init;
For I:= 1 to 3 do
begin;
Writeln('');
RGB[0][i] := 255;
HSL[0][i] := 255; //Max is 240?
XYZ[0][i] := 255; //Max is ...?
end;
Strings[1] := 'R: ';
Strings[0] := ' ';
Strings[2] := 'G: ';
Strings[3] := 'B: ';
Strings[4] := 'H: ';
Strings[5] := 'S: ';
Strings[6] := 'L: ';
Strings[7] := 'X: ';
Strings[8] := 'Y: ';
Strings[9] := 'Z: ';
For I:= 0 to High(Colors) do
begin;
Strings[0] := Strings[0] + Padr('Color: '+inttostr(Colors[i]),16) +' | ';
ColortoRGB(Colors[i],RGBColor[1],RGBColor[2],RGBColor[3]);
ColortoHSL(Colors[i],HSLColor[1],HSLColor[2],HSLColor[3]);
ColortoXYZ(Colors[i],XYZColor[1],XYZColor[2],XYZColor[3]);
For II:= 1 to 3 do
begin;
RGB[0][II] := Min(RGBColor[II],RGB[0][II]);
RGB[1][II] := Max(RGBColor[II],RGB[1][II]);
HSL[0][II] := MinE(HSLColor[II],HSL[0][II]);
HSL[1][II] := MaxE(HSLColor[II],HSL[1][II]);
XYZ[0][II] := MinE(XYZColor[II],XYZ[0][II]);
XYZ[1][II] := MaxE(XYZColor[II],XYZ[1][II]);
end;
For II := 1 to 3 do
Strings[II] := Strings[II] +Padr(IntToStr (RGBColor[II]),16) +' | ';
For II := 4 to 6 do
Strings[II] := Strings[II] +Padr(FloatToStr(HSLColor[II-3]),16) +' | ';
For II := 7 to 9 do
Strings[II] := Strings[II] +Padr(FloatToStr(XYZColor[II-6]),16) +' | ';
end;
For I:= 0 to 9 do
Delete(Strings[i],Length(Strings[i])-2,3);
For I:= 0 to 9 do
begin;
if (I = 1) or (I = 4)or (I = 7) then Writeln('');
Writeln(Strings[i]);
end;
Writeln('');
Writeln('Highest RGB values = R: '+ Padr(FloatToStr(RGB[1][1]),3) + ' | ' +'G: '+ Padr(FloatToStr(RGB[1][2]),3) + ' | ' +'B: '+ Padr(FloatToStr(RGB[1][3]),3) );
Writeln('Lowest RGB values = R: '+ Padr(FloatToStr(RGB[0][1]),3) + ' | ' +'G: '+ Padr(FloatToStr(RGB[0][2]),3) + ' | ' +'B: '+ Padr(FloatToStr(RGB[0][3]),3) );
Writeln('Differ RGB values = R: '+ Padr(IntToStr(RGB[1][1] - RGB[0][1]),3) + ' | G: '+ Padr(inttostr(RGB[1][2] - RGB[0][2]) ,3) + ' | B: '+Padr(inttostr(RGB[1][3] - RGB[0][3]),3));
Writeln('Middle RGB values = R: '+ Padr(IntToStr((RGB[1][1] + RGB[0][1]) div 2),3) + ' | G: '+ Padr(inttostr((RGB[1][2] + RGB[0][2]) div 2),3) + ' | B: '+Padr(inttostr((RGB[1][3] + RGB[0][3]) div 2),3));
Writeln('Middle RGB color = ' + IntToStr(RGBToColor((RGB[1][1] + RGB[0][1]) div 2,(RGB[1][2] + RGB[0][2]) div 2,(RGB[1][3] + RGB[0][3]) div 2)));
Writeln('');
Writeln('Highest HSL values = H: '+ Padr(FloatToStr(HSL[1][1]),16) + ' | ' +'S: '+ Padr(FloatToStr(HSL[1][2]),16) + ' | ' +'L: '+ Padr(FloatToStr(HSL[1][3]),16) );
Writeln('Lowest HSL values = H: '+ Padr(FloatToStr(HSL[0][1]),16) + ' | ' +'S: '+ Padr(FloatToStr(HSL[0][2]),16) + ' | ' +'L: '+ Padr(FloatToStr(HSL[0][3]),16) );
Writeln('Differ HSL values = H: '+ Padr(FloatToStr(HSL[1][1] - HSL[0][1]),16) + ' | S: '+ Padr(FloatToStr(HSL[1][2] - HSL[0][2]) ,16) + ' | L: '+Padr(FloatToStr(HSL[1][3] - HSL[0][3]),16));
Writeln('Middle HSL values = H: '+ FloatToStr((HSL[1][1] + HSL[0][1]) div 2) + ' | S: '+ FloatToStr((HSL[1][2] + HSL[0][2]) div 2) + ' | L: '+FloatToStr((HSL[1][3] + HSL[0][3]) div 2));
Writeln('Middle HSL color = ' + IntToStr(HSLToColor((HSL[1][1] + HSL[0][1]) div 2,(HSL[1][2] + HSL[0][2]) div 2,(HSL[1][3] + HSL[0][3]) div 2)));
Writeln('');
Writeln('Highest XYZ values = X: '+ Padr(FloatToStr(XYZ[1][1]),16) + ' | ' +'Y: '+ Padr(FloatToStr(XYZ[1][2]),16) + ' | ' +'Z: '+ Padr(FloatToStr(XYZ[1][3]),16) );
Writeln('Lowest XYZ values = X: '+ Padr(FloatToStr(XYZ[0][1]),16) + ' | ' +'Y: '+ Padr(FloatToStr(XYZ[0][2]),16) + ' | ' +'Z: '+ Padr(FloatToStr(XYZ[0][3]),16) );
Writeln('Differ XYZ values = X: '+ Padr(FloatToStr(XYZ[1][1] - XYZ[0][1]),16) + ' | Y: '+ Padr(FloatToStr(XYZ[1][2] - XYZ[0][2]) ,16) + ' | Z: '+Padr(FloatToStr(XYZ[1][3] - XYZ[0][3]),16));
Writeln('Middle XYZ values = X: '+ FloatToStr((XYZ[1][1] + XYZ[0][1]) div 2) + ' | Y: '+ FloatToStr((XYZ[1][2] + XYZ[0][2]) div 2) + ' | Z: '+FloatToStr((XYZ[1][3] + XYZ[0][3]) div 2));
Writeln('Middle XYZ color = ' + IntToStr(XYZToColor((XYZ[1][1] + XYZ[0][1]) div 2,(XYZ[1][2] + XYZ[0][2]) div 2,(XYZ[1][3] + XYZ[0][3]) div 2)));
WritelN('');
end.
"Colors := [];"
See this? Here you need to enter the colors you pick from object. Seperate with comma.
e.g. "Colors := [123,1234,12345];"
Try to pick much different colors as you can if there are not same coloured object nearby.
Try to pick 5 or more if possible.
Enter them and press run.
Scroll up where are HSL ranges.
We find hue, saturation and tolerance using differ.
Tolerance = luminance differ
Huemod = hue differ / lum difffer
Satmod = sat differ / lum differ
Color - Hue * Sqrt(Luminance) / Sat... No for god sake! It's middle HSL color
See the example.
Highest HSL values = H: 55,9523820877075 | S: 29,1666656732559 | L: 35,2941185235977
Lowest HSL values = H: 55,0505042076111 | S: 19,2052990198135 | L: 9,41176488995552
Differ HSL values = H: 0,901877880096436 | S: 9,96136665344238 | L: 25,8823536336422
Middle HSL values = H: 55,5014431476593 | S: 24,1859823465347 | L: 22,3529417067766
Middle HSL color = 4668971
Hue mod - 0.9 = 0.036 - Thats not good if it's under 0.1 or so.
I suggest you to just make it to 0.1 if it's lower than that.
Sat - 9.961 = 0,4
Tolerance = 25
Color - 4668971
Here, try this one some rune item(s).
function FindIt(var x, y : integer) : Boolean;
var
TPA : TPointArray;
ATPA : T2DPointArray;
I, CTS, L : integer;
begin
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.1, 0.4);
FindColorsTolerance(TPA, 4668971, MSX1, MSY1, MSX2, MSY2, 25);
SetColorspeed2Modifiers(0.2, 0.2);
ColorToleranceSpeed(CTS);
ATPA := SplitTPAEx(TPA, 5, 5);
SortATPAFrom(ATPA, IntToPoint(MSCX, MSCY));
L := High(ATPA)
For i := 0 to L do
if Length(ATPA[i]) >= 100 then
begin
MiddleTPAEx(ATPA[i], x, y);
MMouse(x, y, 5, 5);
Wait(50 + random(50));
if (pos('une', rs_GetUpText) > 0) then
begin
GetMousePos(x, y);
Result := True;
Exit;
end;
end;
end;
Result:
http://i28.tinypic.com/2a9aeko.jpg
Instead of finding some few pixels it finds all of them.
Edit: Also note that I didn't do it in MS Paint, Wizzup's DebugATPA ftw!
So this is all.
Note that I didn't learned this myself.
Main helpers were Nielsie and Markus,
I'd wish to thank them now:)
Oh, also when I finished this tutorial I noticed Nielsie and Sumilion released ACA2 what turned my tutorial kinda pointless. Hope that someone still gets something out of it.
Have fun ;)