SRL Archive - General Botting Help

TPA Question


caused

2014-05-02 15:38:37

Hi.

Is there a function that Removes Points from a TPA that are not within reach of x amount of Points ?

Example:


d Is the CLuster I'm wanting to keep.
abd a,b,c is to be removed.

Hope you can help :)

~caused

Kasi

2014-05-02 15:48:00

Best thing to do IMO is Change the TPA to an ATPA, then select the biggest ATPA in terms of width * height.

caused

2014-05-02 16:47:47

Hmn. I thought about that.

Is there a function That Converts ATPA to TPA ?

If not it'd be pretty easy to make one :D

masterBB

2014-05-02 16:51:41

program new;

procedure DrawCrosses(bmp:Integer; tpa: TPointArray; color: Integer);
var
i: Integer;
begin
for i := 0 to High(tpa) do
begin
FastSetPixel(bmp, tpa[i].x, tpa[i].y, color);
FastSetPixel(bmp, tpa[i].x+1, tpa[i].y, color);
FastSetPixel(bmp, tpa[i].x-1, tpa[i].y, color);
FastSetPixel(bmp, tpa[i].x, tpa[i].y+1, color);
FastSetPixel(bmp, tpa[i].x, tpa[i].y-1, color);
FastSetPixel(bmp, tpa[i].x+2, tpa[i].y, color);
FastSetPixel(bmp, tpa[i].x-2, tpa[i].y, color);
FastSetPixel(bmp, tpa[i].x, tpa[i].y+2, color);
FastSetPixel(bmp, tpa[i].x, tpa[i].y-2, color);
end;
end;

procedure DrawBoxes(bmp:Integer; tpa: TPointArray; w, h, color: Integer);
var
i, bmpW, bmpH: Integer;
boxPts: TPointArray;
begin
GetBitmapSize(bmp, bmpW, bmpH);
for i := 0 to High(tpa) do
begin
EdgeFromBoxWrap(IntToBox(tpa[i].x-w, tpa[i].y-h, tpa[i].x+w, tpa[i].y+h), boxPts);
FilterPointsBox(boxPts, 0, 0, bmpW-1, bmpH-1);
DrawTPABitmap(bmp, boxPts, color);
end;
end;

function getPoints(tpa: TPointArray): TPointArray;
var
ptsATPA: Array of TPointArray;
i: Integer;
begin
splitTPAExWrap(tpa, 3, 3, ptsATPA);
SetLength(Result, Length(ptsATPA));

for i := 0 to High(ptsATPA) do
begin
Result[i] := MiddleTPA(ptsATPA[i]);
end;
end;

var
initBmp, w, h: Integer;
basicBmp, iterator: Integer;
pts: TPointArray;
ptsSplitUp: Array of TPointArray;

begin
initBmp := LoadBitmap('D:\test.bmp');

GetBitmapSize(initBmp, w, h);
DisplayDebugImgWindow(w, h);
DrawBitmapDebugImg(initBmp);

SetTargetBitmap(initBmp);
FindColors(pts, 2367212, 0, 0, w-1, h-1);
pts := getPoints(pts);

basicBmp := CreateBitmap(w, h);
FastDrawClear(basicBmp, $FFFFFF);
DrawCrosses(basicBmp, pts, 0);
DrawBitmapDebugImg(basicBmp);

//From here on:
// pts -> the points we got
splitTPAExWrap(pts, 30, 30, ptsSplitUp); //<- this line

for iterator := 0 to High(ptsSplitUp) do
DrawBoxes(basicBmp, ptsSplitUp[iterator], 30, 30, RandomRange(0, $FFFFFF));

DrawBitmapDebugImg(basicBmp);
end.

Assuming test.bmp is saved on your D drive. One sec, will add explanation.

e:
This is the image I started with. Your image without the chars.

I changed it into a TPointArray and drawn crosses at the points. Kinda reduced the amount of points slightly.

Drawn a box around every point. If two points got each other in their boxes they are in the same group.


[INDENT]splitTPAExWrap(inputTPA, 30, 30, outputATPA);[/INDENT]
30, 30 is the size of the boxes used to split them with. This is the function used to split them up.

You can then simply loop through it. Only picking hte ATPA[x] with a high enough length.
for i := 0 to High(outputATPA) do
if(Length(outputATPA[i]) > yourThreshHold) then
theGoodTPA := outputATPA[i];

e2:
You can also visual represent it by using boxes half the size:
If they touch each other squares, they are in the same group.

You can also use circles by sorting them in groups based on the distance. You have to use splitTPAWrap instead of splitTPAExWrap though.
If the circles touch each other they are in the same group. Note how 30 is no longer enough.

caused

2014-05-03 06:35:20

Wow thank you for this detailed post.
I already did something similar :D.

Anyways thanks alot for your effort :). Maybe me/you/we could come up with a function for srl that does this, since it seems to be oftentimes quit usefull. Maybe an overload for Splittpaex.

bonsai

2014-05-03 09:27:59

From: caused
Wow thank you for this detailed post.
I already did something similar :D.

Anyways thanks alot for your effort :). Maybe me/you/we could come up with a function for srl that does this, since it seems to be oftentimes quit usefull. Maybe an overload for Splittpaex.


These are part of the TPointArray and T2DPointArray types.

See split() cluster() toATPA() etc.

rj

2014-05-03 09:31:49

Can't this be accomplished with cluserTPA?

function findPoints():T2DPointarray;
var
tpa:TPointarray;
begin
findColorsTolerance(tpa, color, x1, y1, x2, y2, tol);
result := clustertpa(tpa, 30); //; distance of 30
filtertpasbetween(result, 0, 5); //all atpa that have between 0-5 points are removed
end;

[spoiler=SRL 6]

SRL6 would be this I think:

function findPoints():T2DPointarray;
var
tpa:TPointarray;
begin
findColorsTolerance(tpa, color, x1, y1, x2, y2, tol);
result := tpa.cluster(30).filterBeween(0, 5);
end;
[/spoiler]

Kasi

2014-05-03 10:16:06

@Robert;

Did not even know about ClusterTPA.

slacky

2014-05-03 21:29:38

From: Kasi
Did not even know about ClusterTPA.

ClusterTPA offers the same functionality as SplitTPA, and ClusterTPAEx offers the same functionality as SplitTPAEx. Order of the ATPA, and the points inside each TPA may not be the same. ClusterTPA is optimized for large data-sets / arrays. It's able to cluster huge amounts of points in much much less time. For small arrays/TPA SplitTPA(Ex) is just as good.

tiffanygraff

2014-06-03 03:09:02

Nice thread you have to share here,, thanks