Moore Neighborhood tracing help needed
Monkey Forums/Monkey Programming/Moore Neighborhood tracing help needed
| ||
| I have made an PNG outline tracer a week ago, but that was not good enough for what I want to do with it. Now I'm trying for more then a week to get the coordinates clockwise and I know how. But I can't create the correct monkey code for it :( Its this solution http://en.wikipedia.org/wiki/Moore_neighborhood http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/contour_tracing_Abeer_George_Ghuneim/moore.html What I have - does check if the next pixel is not alpha 0 What I don't have - loop needs to stop when its find the first pixel again - find the whole outline Thanks very much :)
Strict
Import mojo
Import opengl.gles11
Function Main:Int()
New MyApp()
Return 0
End
Class MyApp Extends App
Field thing:Sprite
Method OnCreate:Int()
SetUpdateRate(60)
thing = New Sprite()
Return 0
End
Method OnUpdate:Int()
thing.Update()
Return 0
End
Method OnRender:Int()
Cls(255,255,255)
thing.Draw()
Return 0
End
End
Class PNGTracer
Field startX:Int = 93
Field startY:Int = 0
Field size:Int[2]
Field _w:Int
Field _h:Int
Field db:DataBuffer
Field xy:Stack<Point> = New Stack<Point>()
Field data:Int[]
Function Get:Int[] (_db:DataBuffer,_w:Int,_h:Int)
Local data:Int[_w * _h]
For Local y:Int = 0 Until _h
For Local x:Int = 0 Until _w
Local j:Int = _db.PeekInt( ( y * _w + x) * 4)
data[y * _w + x] = (j & $ff000000) | ( (j & $00ff0000) Shr 16) | (j & $0000ff00) | ( (j & $000000ff) Shl 16)
Next
Next
Return data
End Function
Method neighbor:Void(_x:Int,_y:Int)
'' Print _data.Length()
Print "Start:"+_x+","+_y
Local check:Bool[8]
Local calc:Point[8]
check[0] = (_y-1)*_w+(_x-1)>=0 And (data[(_y-1)*_w+(_x-1)] shr 24) & $FF
calc[0] = New Point(_x-1,_y-1)
check[1] = (_y-1)*_w+_x>=0 And (data[(_y-1)*_w+_x] shr 24) & $FF
calc[1] = New Point(_x,_y-1)
check[2] = (_y-1)*_w+(_x+1)>=0 And (data[(_y-1)*_w+(_x+1)] shr 24) & $FF
calc[2] = New Point(_x+1,_y-1)
check[3] = _y*_w+(_x+1)>=0 And (data[_y*_w+(_x+1)] shr 24) & $FF
calc[3] = New Point(_x+1,_y)
check[4] = (_y+1)*_w+(_x+1)>=0 And (data[(_y+1)*_w+(_x+1)] shr 24) & $FF
calc[4] = New Point(_x+1,_y+1)
check[5] = (_y+1)*_w+_x>=0 And (data[(_y+1)*_w+_x] shr 24) & $FF
calc[5] = New Point(_x,_y+1)
check[6] = (_y+1)*_w+(_x-1)>=0 And (data[(_y+1)*_w+(_x-1)] shr 24) & $FF
calc[6] = New Point(_x-1,_y+1)
check[7] = _y*_w+(_x-1)>=0 And (data[_y*_w+(_x-1)] shr 24) & $FF
calc[7] = New Point(_x-1,_y)
Local index:Int = 0
For Local hit:Bool = Eachin check
If hit Then
' FOUND THE NEXT GOOD PIXEL !
Print "hit:"+index
Print "add:"+calc[index].x+","+calc[index].y
xy.Push(New Point(calc[index].x,calc[index].y))
'' neighbor(calc[index].x,calc[index].y)
' uncomment and there is a crash
Exit
End
index+=1
Next
End
Method Trace:Stack<Point>(_img:String)
db = LoadImageData(_img, size)
data = Get(db,size[0],size[1])
_w = size[0] 'helper var
_h = size[1] 'helper var
neighbor(startX,startY)
Return xy
End
Function toPolyData:Float[](_data:Stack<Point>)
Local verts:Float[_data.Length*2]
Local tmpI:Int = 0
For Local point:Point = Eachin _data
verts[tmpI] = point.x
tmpI=tmpI+1
verts[tmpI] = point.y
tmpI=tmpI+1
Next
Return verts
End
End
Class Point
Field x:Int
Field y:Int
Method New(_x:Int,_y:Int)
x=_x
y=_y
End
End
Class Sprite
Field image:Image
Field tmp:Image
Field outline_xy:Stack<Point> = New Stack<Point>()
Field verts:Float[]
Method New()
Local PNGTrace:PNGTracer = New PNGTracer()
outline_xy = PNGTrace.Trace("monkey://data/test-thing2.png")
'' verts = PNGTracer.toPolyData(outline_xy)
End
Method Draw:Void()
SetColor(255,0,0)
For Local point:Point = Eachin outline_xy
DrawPoint(point.x,point.y)
Next
'' DrawPoly(verts)
End
Method Update:Void()
'' If PointInPoly(MouseX(),MouseY(),verts) Then
'' Print "Hit"
'' Else
'' Print "no"
'' End
End
Function PointInPoly:Bool(x:Float, y:Float, poly:Float[])
Local i:Int, j:Int, c:Bool
Local v1:Bool, v2:Bool, v3:Bool, v4:Bool, v5#, v6#, v7#
c = False
Local p_count% = (poly.Length() / 2)
For i = 0 To p_count-1
j = (i+1) Mod p_count
v1 = (poly[i*2+1] <= y)
v2 = (y < poly[j*2+1])
v3 = (poly[j*2+1] <= y)
v4 = (y < poly[i*2+1])
v5 = (poly[j*2]-poly[i*2]) * (y-poly[i*2+1])
v6 = (poly[j*2+1]-poly[i*2+1])
If v6 = 0.0 Then v6 = 0.0001
v7 = poly[i*2]
If (((v1 And v2) Or (v3 And v4)) And (x < v5 / v6 + v7)) Then c = Not c
Next
Return c
End
End
Still using this image: |