SRL Archive - Discussions and Debates

Fast & Efficient


BenLand100

2007-09-24 15:29:55

Someone suggested to me that I should make a plugin for scar that could do generic tasks really fast. For instance, array sorts and stuff like that. I've already written an edge detector for it that can do the entire client screen in ~125 ms. Had to write it from scratch, and I must admit, its MUCH better than the last one I wrote. This is the line that takes 125ms, so its not just the algorithm, its everything that must be done to go from a raw image->edges.
CannyCore(GetBitmapCanvas(bmp).Handle,765,503,250,150);

So, If you'd like me to write a really fast implementation of an algorithm and add it to the plugin, post [the algorithm/description] here. I'm writing in c++ in case you're interested.

mastaraymond

2007-09-24 16:09:37

From: BenLand100
Someone suggested to me that I should make a plugin for scar that could do generic tasks really fast. For instance, array sorts and stuff like that. I've already written an edge detector for it that can do the entire client screen in ~125 ms. Had to write it from scratch, and I must admit, its MUCH better than the last one I wrote. This is the line that takes 125ms, so its not just the algorithm, its everything that must be done to go from a raw image->edges.
CannyCore(GetBitmapCanvas(bmp).Handle,765,503,250,150);

So, If you'd like me to write a really fast implementation of an algorithm and add it to the plugin, post [the algorithm/description] here. I'm writing in c++ in case you're interested.
Cool stuff! You have got something that makes TPAs of each line? I've done something similar except i didn't rewrite the algorithm, just used a pre-made function ^^.
Keep 'em going,

~Raymond

the scar noob

2007-09-24 16:11:27

It's very dumb to sy this, but I just don't understand a single word that's written above:p
Can someone explain it in easy english plz:)
Btw I speak dutch for dutch people who can explain me if they want to ;)

mastaraymond

2007-09-24 16:19:12

From: the scar noob
It's very dumb to sy this, but I just don't understand a single word that's written above:p
Can someone explain it in easy english plz:)
Btw I speak dutch for dutch people who can explain me if they want to ;)

All right its pretty simple: Canny is a algorithm that detects the edges of a 'shape'. Benland wrote a program in C that uses the canny algorithm on a image\bitmap. When you apply this algorithm it outputs a image that only contains the edges of the original image..
Thats it i think,

~Raymond

WT-Fakawi

2007-09-24 16:48:32

Of course we would like you to do that :)

Special Ed

2007-09-24 17:22:08

Oh snap, also I could have sworn that I was just talking to someone about this that said that they had made something like this… am I crazy?

In any case, good work… would you mind posting the Canny algorithm or do I have to google it?

Bourdou!

2007-09-24 17:26:45

Sorry for the noobie question, but how do you use plugins?

BenLand100

2007-09-24 17:37:16

From: Special Ed
Oh snap, also I could have sworn that I was just talking to someone about this that said that they had made something like this… am I crazy?

In any case, good work… would you mind posting the Canny algorithm or do I have to google it?

The Scar test:
var
bmp, w, h: integer;
begin
GetClientDimensions(w,h);
bmp:= BitmapFromString(w,h,'');
CopyClientToBitmap(bmp,0,0,w,h);
writeln(inttostr(GetSystemTime));
CannyCore(GetBitmapCanvas(bmp).Handle,w,h,200,50);
writeln(inttostr(GetSystemTime));
DisplayDebugImgWindow(w,h);
CopyCanvas(GetBitmapCanvas(bmp),GetDebugCanvas,0,0,w,h,0,0,w,h);
FreeBitmap(bmp);
end.
The algorithm (in c++):
Where image is an array of pixels, w is width, h is height, upper is the upper tolerance, and lower is the lower tolerance
    int i, x, y;
int color;
//Convert to grayscale
for (i = 0; i < w*h; i++) {
color = image[i];
image[i] = (((color & 0xFF000000) >> 24) + ((color & 0xFF0000) >> 16) + ((color & 0xFF00) >> 8)) / 3;
}
int size = w*h;
int* buffer = (int*)malloc(size*4*3);
int* mags = buffer;
int* dir = buffer + size;
int we = w - 1;
int he = h - 1;
i = w + 1;
//Gradient magnitude/direction loop
for (y = 1; y < he; y++) {
for (x = 1; x < we; x++) {
int xmag = (image[i-w-1] - image[i])*5;
int ymag = (image[i-w] - image[i-1])*5;
mags[i] = (int)sqrt(xmag*xmag+ymag*ymag);
dir[i] = (int)ceil(atan2(ymag,xmag) / 1.570796326794); //No round...?
i++;
}
i+=2;
}
int* supr = buffer + size*2;
i = w + 1;
//Nonmaxima supression loop
for (y = 1; y < he; y++) {
for (x = 1; x < we; x++) {
switch (dir[i]) {
case 0:
case 2:
case -2:
//left-right
if (mags[i] >= (mags[i+w-1] + mags[i+w] + mags[i+w+1]) / 3.15 && mags[i] >= (mags[i-w-1] + mags[i-w] + mags[i-w+1]) / 3.15)
supr[i] = mags[i];
break;
case 1:
case -1:
//up-down
if (mags[i] >= (mags[i-w+1] + mags[i+1] + mags[i+w+1]) / 3.15 && mags[i] >= (mags[i-w-1] + mags[i-1] + mags[i+w-1]) / 3.15)
supr[i] = mags[i];
}
i++;
}
i+=2;
}
memset((void*)image,0,size*4); //Clear the image
int* stack = buffer; //It can use the first two segments
i = w + 1;
//Thresholding tracer loop
for (y = 1; y < he; y++) {
for (x = 1; x < we; x++) {
if (image[i] == 0 && supr[i] > upper) {
*stack++ = i;
while (stack > buffer) {
int n = *--stack;
if (image[n] == 0 && supr[n] > lower) {
image[n] = 0xFFFFFF;
*stack++ = n-1;
*stack++ = n+1;
*stack++ = n-w;
*stack++ = n+w;
*stack++ = n-w+1;
*stack++ = n+w+1;
*stack++ = n-w-1;
*stack++ = n+w-1;
}
}
}
i++;
}
i+=2;
}
free(buffer);

And the edges plugin attached for good measure.

Special Ed

2007-09-24 17:42:42

Thanks, although I was just asking for the general mathematical formula for it, I didn't mean the coding, although that is still very interesting.

If I could get the mathematic formula for it I would say that maybe if I made it in SCAR we could truly test the efficiency of SCAR comparatively although I'm sure we could test it some other way. (loop of addition!)

pwnaz0r

2007-09-24 18:28:56

Could you sort a TPA from a TPoint and space it out so that every box (l * w) has i point maximum? I know this is in wizzy's plugin but it doesnt seem to work.

BenLand100

2007-09-24 18:43:08

From: pwnaz0r
Could you sort a TPA from a TPoint and space it out so that every box (l * w) has i point maximum? I know this is in wizzy's plugin but it doesnt seem to work.


That doesn't sound like a very good algorithm to me. You sure there isn't more logic than just 1 point per every grid segment?

From: Special Ed
Thanks, although I was just asking for the general mathematical formula for it, I didn't mean the coding, although that is still very interesting.

If I could get the mathematic formula for it I would say that maybe if I made it in SCAR we could truly test the efficiency of SCAR comparatively although I'm sure we could test it some other way. (loop of addition!)

Well, there isn't much math. There are three components: gradient magnitude/direction, nonmaxima suppression, and thresholding. For the gradient, I recommend Roberts Cross or Sobel algorithms. The idea is to detect the probability that a point is an edge at this step. Nonmaxima suppression works by finding all points that have a greater magnitude than the points perpendicular to the direction of the gradient, and setting the others to 0. Here you are trying to determine actual edges from probabilities. This is the hardest part, most people try thinning instead of suppression, but suppression is far superior. Lastly, the thresholding step finds all pixels that are greater than the upper threshold and traces along any edges connected to it that are greater than the lower threshold (to provide continuous lines) and set them to white, all else black. In this step you are removing edges that are not strong enough (since you still have the probabilities) to count as an "edge" in the final image. Its not hard to implement once you know how it works, sadly there are almost no resources that explain the nonmaxima suppression well, so if you have any questions, ask.

I omitted the Gaussian blur step in this implementation for two reasons. First, its slow; second, its not needed in Runescape where there is no noise anyway. But a Gaussian blur is easy to apply to the image before edge detection anyway, so its not a big deal.

pwnaz0r

2007-09-24 18:48:53

From: BenLand100
That doesn't sound like a very good algorithm to me. You sure there isn't more logic than just 1 point per every grid segment?


Well, there isn't much math. There are three components: gradient magnitude/direction, nonmaxima suppression, and thresholding. For the gradient, I recommend Roberts Cross or Sobel algorithms. The idea is to detect the probability that a point is an edge at this step. Nonmaxima suppression works by finding all points that have a greater magnitude than the points perpendicular to the direction of the gradient, and setting the others to 0. Here you are trying to determine actual edges from probabilities. This is the hardest part, most people try thinning instead of suppression, but suppression is far superior. Lastly, the thresholding step finds all pixels that are greater than the upper threshold and traces along any edges connected to it that are greater than the lower threshold (to provide continuous lines) and set them to white, all else black. In this step you are removing edges that are not strong enough (since you still have the probabilities) to count as an "edge" in the final image. Its not hard to implement once you know how it works, sadly there are almost no resources that explain the nonmaxima suppression well, so if you have any questions, ask.


ok, well if you would want to make it more advanced, you could make the minumum box-space around them and delete all points within that box (set-able by user).

juessx

2007-09-24 18:53:24

It's like a bitmap mask of your desktop, so cool. :p

Make a function like FollowRock into C++ ? =O

pwnaz0r

2007-09-24 18:59:52

or a createbitmapmask from bitmap (color, bitmap: integer)

juessx

2007-09-24 19:02:10

From: pwnaz0r
or a createbitmapmask from bitmap (color, bitmap: integer)


Certain objects are darker than others though I don't think it's accurate to make one function like that.

BenLand100

2007-09-24 19:09:20

From: pwnaz0r
ok, well if you would want to make it more advanced, you could make the minumum box-space around them and delete all points within that box (set-able by user).


So, take every point in the array that is no more than x pixels from another point, put them in groups, and then return the center point of each group? That I can do ;)

From: juessx
It's like a bitmap mask of your desktop, so cool. :p

Make a function like FollowRock into C++ ? =O


Couldn't really do that, plugins are for processing, not script control. They do the grunt work :)

From: pwnaz0r
or a createbitmapmask from bitmap (color, bitmap: integer)

So, say it makes the bitmap into black, and then fills the areas that are = to color with white? Possibly with tolerance thrown into the mix? That I can do :)

juessx

2007-09-24 19:12:07

mkay. Functions like that are generally so sloww though. It's more of Scar can't handle so many functions getting looped over and over again though, and you can't fix that. x[

Tim0suprem0

2007-09-24 22:55:48

Is it just me? Or does anyone else not understand all these Gaussian blur step's and shtuff? :p

I'm about to embark on a wild ride of Wikipedia and Google searches.

[offtopic] juessx nice to see our female population is up by 50% again ;) [/offtopic]

nielsie95

2007-09-25 01:56:33

Maybe corner detection / corner count? Shape recognizing? :)

mastaraymond

2007-09-25 09:52:56

I was planning to make something that puts each separate line in a TPAA. Then filter out the small ones and the big ones. Then could do some TPA functions, to determine what objects they are, or what the middle of the line is. If you could make that ^^.

EDIT: If lower is to low, you get quit big edges ^^:

Hugolord

2007-09-25 09:58:11

From: Bourdou!
Sorry for the noobie question, but how do you use plugins?


u make thme and call them i think

n3ss3s

2007-09-25 10:00:35

Nice job, but I just realized something, UpText checking can sometimes mess with the background of quite same color rite?

EdgeUpTextDetection FTW!?

mastaraymond

2007-09-25 10:14:14

From: n3ss3s
Nice job, but I just realized something, UpText checking can sometimes mess with the background of quite same color rite?

EdgeUpTextDetection FTW!?
Eh? FindBitmapMaskTolerance pl0x ^^. I think its fixed in scar 3.12 tho..

Changelog:
- function rs_GetUpText: string; (Increased to 99% accuracy in all situations and speed to an average 10ms from 480ms)

The Claw

2007-09-25 10:15:05

Uptext has been made a lot better in scar 3.12 ;)

Ive got one for you ben -

Say I do a FindColorsTolerance, on the main screen. From the TPointArray that I get from that, I want to be able to find the minimum and maximum points of positive results, in a given area. For example, if I get 10 hits somewhere, and 20 hits somewhere else, in the given range of 50 pixels (10 hits in a 50 pixel box, 20 hits in another 50 pixel box), I want to be able to find out the box in which the highest amount of hits was found in. Then I want to be able to split that box up, evenly, into a given number.

So ultimately I could do this:

FindColorsSpiralTol(..., zzz);
FindHighestConcentration(box in which to search for the highest concentrations in - say 50, zzz): TBoxArray;
DividePoints(number of points i want - say 10, TBox gotten from the FindHighestConcentration): TPointArray;

so i findcolorstolerance, using that tpa i find the 50 x 50 box in which the most hits are, then divide that tbox into a given amount of points, so that i can move the mouse to each one and check for uptext.

come to think of it, i could probably do it myself lol but meh :p

nielsie95

2007-09-25 10:45:37

From: The Claw
Uptext has been made a lot better in scar 3.12 ;)

Ive got one for you ben -

Say I do a FindColorsTolerance, on the main screen. From the TPointArray that I get from that, I want to be able to find the minimum and maximum points of positive results, in a given area. For example, if I get 10 hits somewhere, and 20 hits somewhere else, in the given range of 50 pixels (10 hits in a 50 pixel box, 20 hits in another 50 pixel box), I want to be able to find out the box in which the highest amount of hits was found in. Then I want to be able to split that box up, evenly, into a given number.

So ultimately I could do this:

FindColorsSpiralTol(..., zzz);
FindHighestConcentration(box in which to search for the highest concentrations in - say 50, zzz): TBoxArray;
DividePoints(number of points i want - say 10, TBox gotten from the FindHighestConcentration): TPointArray;

so i findcolorstolerance, using that tpa i find the 50 x 50 box in which the most hits are, then divide that tbox into a given amount of points, so that i can move the mouse to each one and check for uptext.

come to think of it, i could probably do it myself lol but meh :p


TPAtoATPA and/or SplitTPAEx? Concetration is the length of the returned result.
I don't exactly understand what you mean by DividePoints…

The Claw

2007-09-25 11:08:01

i mean, split up the TBox into 10 (or whatever) TPA's, evenly spaced

Starblaster100

2007-09-25 11:49:57

From: Special Ed
Oh snap, also I could have sworn that I was just talking to someone about this that said that they had made something like this… am I crazy?

In any case, good work… would you mind posting the Canny algorithm or do I have to google it?


That was me, but i made mine in SCAR so it takes ~3-5 seconds to convert the whole MS. I just made it for fun though, 3-5 seconds is very impractical

BenLand100

2007-09-25 12:52:54

From: The Claw
Uptext has been made a lot better in scar 3.12 ;)

Ive got one for you ben -

Say I do a FindColorsTolerance, on the main screen. From the TPointArray that I get from that, I want to be able to find the minimum and maximum points of positive results, in a given area. For example, if I get 10 hits somewhere, and 20 hits somewhere else, in the given range of 50 pixels (10 hits in a 50 pixel box, 20 hits in another 50 pixel box), I want to be able to find out the box in which the highest amount of hits was found in. Then I want to be able to split that box up, evenly, into a given number.

So ultimately I could do this:


ScarScript:By Drunkenoldma[LEFT]FindColorsSpiralTol(…, zzz);</p><p>FindHighestConcentration(box in which to search for the highest concentrations in - say 50, zzz): TBoxArray;</p><p>DividePoints(number of points i want - say 10, TBox gotten from the FindHighestConcentration): TPointArray; [/LEFT]



so i findcolorstolerance, using that tpa i find the 50 x 50 box in which the most hits are, then divide that tbox into a given amount of points, so that i can move the mouse to each one and check for uptext.

come to think of it, i could probably do it myself lol but meh :p

So, you give it an array of points, it finds the 50x50 area that contains the most points and returns the points in that area? That fits in with another algorithm I'm writing. This point analysis is getting kind of popular :) The other algorithm finds the center points of areas with high concentration.

Wizzup?

2007-09-25 13:02:05

From: BenLand100
So, take every point in the array that is no more than x pixels from another point, put them in groups, and then return the center point of each group? That I can do ;))


findcolorstolerance(rocks);
arocks := tpatoatpaex(rocks, 25, 25);
setlength(rockmids, length(arocks));
for i := 0 to length (arocks) - 1 do
rockmids[i] := middletpa(arocks[i]);

n3ss3s

2007-09-25 13:22:05

That was me, but i made mine in SCAR so it takes ~3-5 seconds to convert the whole MS. I just made it for fun though, 3-5 seconds is very impractical


Are you going to release that somewhere?

If people dont like the 3-5 seconds, atleast people could learn a lot from it..

nielsie95

2007-09-25 13:33:39

From: nielsie95
Maybe corner detection / corner count? Shape recognizing? :)


:)?

Starblaster100

2007-09-25 14:32:34

From: n3ss3s
Are you going to release that somewhere?

If people dont like the 3-5 seconds, atleast people could learn a lot from it..


Might do sometime

BenLand100

2007-09-25 16:45:50

From: Wizzup?
findcolorstolerance(rocks);
arocks := tpatoatpaex(rocks, 25, 25);
setlength(rockmids, length(arocks));
for i := 0 to length (arocks) - 1 do
rockmids[i] := middletpa(arocks[i]);


findcolorstolerance(rocks);
SetLength(rocks, centerGroups(rocks,25,[minimum pixels per rock]));
Plus I'm looking at speed and efficiency, not just satisfying the "faster cause its in a plugin" clause.

@nielsie95 Shape and corner detection is really specific, but I might write an interest point and line detector ;)

The Claw

2007-09-26 04:37:29

From: BenLand100
So, you give it an array of points, it finds the 50x50 area that contains the most points and returns the points in that area? That fits in with another algorithm I'm writing. This point analysis is getting kind of popular :) The other algorithm finds the center points of areas with high concentration.


basically :)

BenLand100

2007-09-26 21:48:08

procedure CannyCore(dc, width, height, upper, lower: integer);
function MaxGroupCenter(points: TPointArray; Length, MaxDist: Integer): Integer
function GroupCentersMin(points: TPointArray; Length, MaxDist, MinPts: Integer): Integer;
function GroupCenters(points: TPointArray; Length, MaxDist: Integer): Integer;
function FindColorsFast(dc, sx, sy, ex, ey: Integer; points: TPointArray; Length, Color, Tolerance: Integer): Integer
function FindBlobs(dc, sx, sy, ex, ey: Integer; points: TPointArray; Length, Color, Tolerance, MaxDist, MinPts: Integer): Integer;
CannyCore edge detects a bitmap.
MaxGroupCenter finds the group with the highest number of points in it whose points are no greater than MaxDist apart.
GroupCentersMin finds groups whose points are no greater than MaxDist apart, and have at least MinPts points in them.
GroupCenters finds groups whose points are no greater than MaxDist apart.
FindColorsFast does exactly what it says it does.
FindBlobs is a blob detection algorithm, essentially FindColorsFast + GroupCentersMin but faster than using them separately.

Since the plugin is in c++ I can't create delphi arrays, so you allocate an array on the script side, and the procedure returns the number of indexes used, so you do this:
function FindColors(sx,sy,ex,ey,color,tolerance: integer): TPointArray;
var
w, h: integer;
begin
w:= ex-sx;
h:= ey-sy;
SetLength(Result, w*h);
SetLength(Result, FindColorsFast(GetClientCanvas.handle,0,0,w,h,Result,w*h,color,tolerance));
end;
And, on that topic, this FindColors took 12.03 ms on average (at any tolerance) to find colors over a 765x503 area. Comparatively, the Scar FindColors method took 47.5ms at 5 tolerance, 121.57ms at 255, and 130.31ms at 442 tolerance… I have no idea why the Scar procedure changes time taken at different tolerances, but thats what I observed…
Also, I tested the blob detector looking for Mith rocks and it averaged out 29.37ms per search. Ironically, thats FASTER than Scar can return an array of the Mith colors XD. I'll try to upload this after I finish my homework or tomorrow perhaps, just an update. And, please come up with some more stuff, I'm having fun :) That in mind, I might write a corner detector, but I believe a Line detector is a wast of time. I've got one written, and I might include it anyway if I can get it working faster.

BTW: The edge detector is down to 50ms for the entire process from Raw Image -> Edge Detected Image :D

Smartzkid

2007-09-26 22:06:09

Line detector would help for finding bankbooths.

Bobarkinator

2007-09-26 22:28:12

This whole project would be helpful for finding any object

The Claw

2007-09-26 23:54:27

wow nice times, is there any chance of this plugin becoming part of srl? it would be great for these to be used by everyone, they look much better than current functions

Wizzup?

2007-09-27 02:52:38

From: BenLand100
findcolorstolerance(rocks);
SetLength(rocks, centerGroups(rocks,25,[minimum pixels per rock]));
Plus I'm looking at speed and efficiency, not just satisfying the "faster cause its in a plugin" clause.

@nielsie95 Shape and corner detection is really specific, but I might write an interest point and line detector ;)


You lose the rest of your points there. ;)

Ben, I think you should (first, just MO) really try to transfer Arrays. :)

BenLand100

2007-09-27 04:24:21

From: Wizzup?
You lose the rest of your points there. ;)

Ben, I think you should (first, just MO) really try to transfer Arrays. :)

Want me to make an array copy procedure? :garfield: I can transfer arrays, but the fact that delphi uses its own allocation system to manage a segment of dynamic memory and controls how large segments of memory are in that dynamic memory (and keeps track of it) makes it extreemly hard to modify the size, or create new, arrays from another language. Even, really, from another modual (plugin) unless you implement the FastSharedMem unit, which is impossible (afaik) to implement in C++. I will however look into it.

But really, if you use the CenterGroupsMin function, it lets you set a minimum number of points per group, what other analysis do you need, a maximum also?

The Claw

2007-09-27 05:16:53

So you're saying that its hard to edit the stored arrays data in the RAM using C++, that delphi has made? Which is why we need to allocate an array script-side?

BenLand100

2007-09-27 05:49:29

From: The Claw
So you're saying that its hard to edit the stored arrays data in the RAM using C++, that delphi has made? Which is why we need to allocate an array script-side?

No… its hard to change the size of the array since Delphi manages the sizes itself…

The Claw

2007-09-27 06:48:24

ah ok, i wasnt sure so i thought i would ask. ty :p

BenLand100

2007-09-28 21:18:44

As a general speed tip, try to allocate arrays (SetArrayLength) in the beginning of the script and use the array throughout the script without calling SetArrayLength again, its HUGELY inefficient. for a 765x503 index array, it takes about 30ms to call SetArrayLength. With that being said, I'm looking at between 7ms and 8ms for a FindColorsFast that copies into an existing array :D

EDIT: GetColorsFast - 4ms to 5ms to fill an array with all colors on the client screen

n3ss3s

2012-01-12 21:36:44

M-M-M-MEGADIG

How r i use diz for simba?

Brandon

2012-01-12 22:45:19

I've tried.. :S Doesn't work I have no clue why.. if only I knew how to go from MufasaBitmap To Integer then it might work or at least how to copybitmapcanvas to another debugwindow canvas.. :S Guess that's where u got stuck too huh?

Well I tried.. See what you can do with the below or else someone who knows how can probably try it.


program new;
{$LoadLib Edges}

{$i srl/srl.simba}
{$I srl/srl/misc/debug.simba}

var
w, h: integer;
BMP: TMufasaBitmap;
TBMP: TBitmap;
BMPX: Integer;
begin
GetClientDimensions(w,h);
BMPX:= CreateBitmap(w, h);
CopyClientToBitmap(BMPX, 0, 0, w -1, h -1);
BMP:= GetMufasaBitmap(BMPX);
TBMP:= BMP.ToTBitmap;
BMP.Free
//Now we have just a TBitmap of the Client.

writeln(inttostr(GetSystemTime));
CannyCore(TBMP.Handle, w - 1, h - 1, 200, 50); //Pass the Bitmap's Canvas Handle.
writeln(inttostr(GetSystemTime));

BMPX:= CreateBitmap(w, h);
BMP.LoadFromTBitmap(TBMP);
BMPX:= BitmapFromString(w, h, BMP.ToString);

DebugBitmap(BMPX);
BMP.Free;
TBMP.Free;
FreeBitmap(BMPX);
end.

n3ss3s

2012-01-12 23:33:55

O, didn't know I have to do LoadLib. I shall probe at it tomorrow.

bg5

2012-01-15 12:24:30

Varock at parameters 0,0
Varock mine at parameters 250,150
Bank screen at parameters 250,150

Quite impressive ,but how it can be used in object finding? If you zoom objects in inventory you will see that it is less accurate then bounding black outline.

And it is very important -if you want to see object shape - to setup proper parameters or you will see a lot of unecessery things or shape will be incomplete.

Main

2012-01-15 13:32:33

From: beginner5

Quite impressive ,but how it can be used in object finding? If you zoom objects in inventory you will see that it is less accurate then bounding black outline.

And it is very important -if you want to see object shape - to setup proper parameters or you will see a lot of unecessery things or shape will be incomplete.


Oo… SO did you just use

CannyCore(GetBitmapCanvas(bmp).Handle,765,503,250,150);
?

There are plenty of ue for the boundary because if you can have a color of an object and you know its boundary (if you can find both very very fast). You can generate a clickable area. Sort of like my post here
http://villavu.com/forum/showthread.php?t=67748
But it would be have to be much effective than the ones I've posted.

Wizzup?

2012-01-15 14:15:45

I think Raymond made this once, for Simba.

Richard

2012-01-15 14:24:41

Okay, that's creepy how I was just looking over this old thread a couple of days ago and was tempted to post, and then n3ss3s digs it…

Quite impressive ,but how it can be used in object finding? If you zoom objects in inventory you will see that it is less accurate then bounding black outline.


When I was last looking at this, I had the idea of making a TPA for each area separated by the white line. And then you could sort the areas generated by size, and if you were looking for certain objects (trees, rocks, bankers etc.) you could find the areas that have a number of points within a specified range, then check for the colours in that area of points. It would mean that tolerances would have to be as high, and you wouldn't have to click the veins in the rock, it would have the whole rock, far more human like.

I was thinking of doing something similar using HSL, so you can see the point where brightness changes dramatically, and there's the edge of your object.

What are other people's thoughts on this?

bg5

2012-01-15 17:28:43

Oo… SO did you just use
Simba Code:

CannyCore(GetBitmapCanvas(bmp).Handle,765,503,250,150);

?


I lost about 2h trying to replace this function (getbitmapcanvas)in Simba with no effect. So yes ,i used this function ,but in Scar divi :P

BTW.

Are these parameters 250 ,150 upper and lower treshold?

Wizzup?

2012-01-15 18:12:51

Simba doesn't really work with Handles like those because they are not cross platform. However, you can use a TBitmap and get its handle.


var
bmp: TBitmap;
mufbmp: Integer;
begin
mufbmp := BitmapFromClient(...)
bmp := GetMufasaBitmap(mufbmp).ToTBitmap();

// bmp.handle
// canny core stuff here

// back to mufasabitmap:
GetMufasaBitmap(bmp).LoadFromTBitmap(bmp);
end.

@ Richard: Sounds interesting. We mainly need a way to actually make edge detection useful - as in, a way to use it properly. How do you represent it in a way that it is useful, etc.

Killerdou

2012-01-16 10:16:20

http://en.wikipedia.org/wiki/Hough_transform maybe? Though no clue if we could do it at any usefull speed. Or maybe we could splittpa the edges?

bg5

2012-04-15 18:35:11

Anyone is able to fix that plugin? It would be great to use this tool :)

SKy Scripter

2012-04-18 18:29:14

http://villavu.com/forum/showthread.php?p=993635#post993635


Also i have a line detector using hough transformation if anyone is interested in that.

my corner counter will count lines too…


problem with hough transformation is when you have an image it will
will detect the line with in the same slop/angle

i.e

realistically there is 10 lines - the *blue lines
according to hough it would only detect 5 lines because the *red lines are on the same slope

[ATTACH]15474[/ATTACH]

bg5

2012-04-25 13:38:36

Cheers

procedure CannyCore_wrap(var bmp:integer;upper,lower:integer);
var
M : TMufasabitmap;
b : tbitmap;
w,h :integer;
begin
GetBitmapSize(bmp,w,h);
M := GetMufasaBitmap(bmp);
B := Tbitmap.Create;
B := M.ToTBitmap;
M.DrawToCanvas(1,1,B.Canvas);
try
CannyCore(B.Canvas.Handle,w,h,upper,lower);
except
writeln('CannyCore - Access violation , Param: w' + tostr(w) + ' h' + tostr(h));
end;
M.LoadFromTBitmap(B);
bmp := bitmapfromstring(w,h,M.ToString);
M.Free;
end;
:garfield: