Seite 1 von 9

VideoAnalyse; Schaust du weiter

Verfasst: 13.04.2006 09:43
von Xaby
Mein Code:

Code: Alles auswählen

{- Information
; Folker Linstedt
; 
;}/
;aus "capture.pb" und "inc.pb"
Enumeration
#Link2
#Link3
#Sprite3D
#Sprite3D2
EndEnumeration

Dim Farbe.b(4)


;- Window Constants 
Global hWnd 
Enumeration 
  #Window_0 
EndEnumeration 

;- Gadget Constants 
Enumeration 
  #Button_0 
EndEnumeration 

Procedure Open_Window_0() 
  hWnd=OpenWindow(#Window_0, 0, 0, 410, 410,  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "(c) Folker Linstedt 2006 - Desktop muss: 32 Bit BGR sein") 
  
EndProcedure 


#WM_CAP_START = #WM_USER 
#WM_CAP_SET_CALLBACK_ERROR = #WM_CAP_START + 2 
#WM_CAP_SET_CALLBACK_STATUS = #WM_CAP_START + 3 
#WM_CAP_SET_CALLBACK_YIELD = #WM_CAP_START + 4 
#WM_CAP_SET_CALLBACK_FRAME = #WM_CAP_START + 5 
#WM_CAP_SET_CALLBACK_VIDEOSTREAM = #WM_CAP_START + 6 
#WM_CAP_SET_CALLBACK_WAVESTREAM = #WM_CAP_START + 7 
#WM_CAP_DRIVER_CONNECT = #WM_CAP_START + 10 
#WM_CAP_DRIVER_DISCONNECT = #WM_CAP_START + 11 
#WM_CAP_DRIVER_GET_CAPS = #WM_CAP_START + 14 
#WM_CAP_DLG_VIDEOFORMAT = #WM_CAP_START + 41 
#WM_CAP_DLG_VIDEOSOURCE = #WM_CAP_START + 42 
#WM_CAP_DLG_VIDEODISPLAY = #WM_CAP_START + 43 
#WM_CAP_SET_PREVIEW = #WM_CAP_START + 50 
#WM_CAP_SET_PREVIEWRATE = #WM_CAP_START + 52 
#WM_CAP_GET_STATUS = #WM_CAP_START + 54 
#WM_CAP_FILE_SAVEDIB = #WM_CAP_START + 25 
#WM_CAP_SET_SCALE = #WM_CAP_START + 53 
#WM_CAP_SET_CALLBACK_CAPCONTROL = #WM_CAP_START + 85 

#WM_CAP_EDIT_COPY = #WM_CAP_START + 30 
#WM_CAP_GRAB_FRAME = #WM_CAP_START+60 

InitSprite() 
InitSprite3D()
Rotate=0

Open_Window_0() 
OpenWindowedScreen(WindowID(),0,0,400,400,0,0,0)

OpenLibrary(0, "AVICAP32.DLL") 

hRobby = CallFunction(0, "capCreateCaptureWindowA", "Test",  #WS_CHILD, 0, 0, 384, 288, hWnd, 0) 
SendMessage_(hRobby, #WM_CAP_DRIVER_CONNECT, 0 , 0) 

Sprite3DQuality(1)

CreateSprite(#Link2,128,128,#PB_Sprite_Texture)
 
*Pointer =AllocateMemory(128*128*4)
*Pointer2=AllocateMemory(128*128*4)

Rausch=20
Repeat
  
  Event = WindowEvent() ; This line waits until an event is received from Windows 
  ; WaitWindowEvent()
  WindowID = EventWindowID() ; The Window where the event is generated, can be used in the gadget procedures 
  GadgetID = EventGadgetID() ; Is it a gadget event? 
  EventType = EventType() ; The event type 
  
  Link = GetClipboardData(#PB_ClipboardImage) 
       
      If Link <> 0        
       ClearScreen(0,0,0) ; Schwarz
        
        StartDrawing(SpriteOutput(#Link2))
        DrawImage(Link,0,0,128, 128)
         
        *Bild=DrawingBuffer()
        CopyMemory(*Bild, *Pointer, 128*128*4)
        If DrawingBufferPixelFormat() =  #PB_PixelFormat_32Bits_BGR : DrawText("32 Bit BGR") : EndIf
        
        StopDrawing()
        
        CopySprite(#Link2, #Link3, #PB_Sprite_Texture)
        CreateSprite3D(#Sprite3D, #Link3)
        
        ;{- Berechnungen
        ;R=-10+Random(Rausch)
        For i2=0 To 126 ; Bei 127 gibts noch ungeklärte Probleme
        For i=0 To 127
        
          P=127-i
          Farbe(0)=PeekB(*Pointer+i2*128*4+P*4+0)
          Farbe(1)=PeekB(*Pointer+i2*128*4+P*4+1)
          Farbe(2)=PeekB(*Pointer+i2*128*4+P*4+2)
          Farbe(3)=PeekB(*Pointer+i2*128*4+P*4+3)
        
          Farbe(4)=(Farbe(0)+Farbe(1)+Farbe(2))/3 ; Grau ... aber irgendwie nicht richtig
           ;R=Random(Rausch) 
          PokeB(*Pointer2+i2*128*4+i*4+0, Farbe(2)+R) ; Blue
          PokeB(*Pointer2+i2*128*4+i*4+1, Farbe(2)+R); Green
          PokeB(*Pointer2+i2*128*4+i*4+2, Farbe(2)+R); Red ... Rot ist am hellsten
          PokeB(*Pointer2+i2*128*4+i*4+3, Farbe(3)) ; Alpha
          
        Next i
        Next i2
        ;}- Ende Berechnungen
        
        CopyMemory(*Pointer2, *Bild, 128*128*4)
        
        CreateSprite3D(#Sprite3D2, #Link2)
        
        Rotate=(Rotate+3)%360
        ZoomSprite3D(#Sprite3D2,192,144)
       ; RotateSprite3D(#Sprite3D,Rotate,0)
        Start3D()
         DisplaySprite3D(#Sprite3D, 60, 60)
         DisplaySprite3D(#Sprite3D2, 180, 180)
        Stop3D()
    
      EndIf 
 ;/ 
  SendMessage_(hRobby, #WM_CAP_GRAB_FRAME, 0 , 0) 
  SendMessage_(hRobby, #WM_CAP_EDIT_COPY, 0 , 0) ; SendMessage_(hRobby, #WM_CAP_EDIT_COPY   ,0,0); kopiert Bild ins Clipboard
  
  Delay(10) ; Prozessorauslastung verhindern ... vielleicht ;-) 
  FlipBuffers()
  
Until Event = #PB_Event_CloseWindow ; End of the event loop 

SendMessage_(hRobby, #WM_CAP_SET_PREVIEW, 0, 0) 
SendMessage_(hRobby, #WM_CAP_DRIVER_DISCONNECT, "Test", 0) 
CloseWindow(0) 
CloseLibrary(0) 

End
Noch kann er nicht viel und ist noch sehr unflexibel.
Aber das Grundgerüst für schnellen Zugriff ist gegeben.
Mag jemand vielleicht mit mir zusammen einen Algorithmus entwickeln, der aus der VideoQuelle ... geometrische Formen erkennen kann ...
selbstverständlich mit einer gewissen Tolleranz.
Linienstärke, Winkel, Längen ...

Ziel soll sein: Oh, ich sehe einen roten Kreis
Ah, da ist ein Quadrat mit einem Winkel relativ zur unteren Bildschirmkante von 45° ... (oder auch ein Karo :roll: )

Und das Quadrat besteht selbst aus Linien.

Ich würde mich schon freuen, wenn ich überhaupt eine schwarze Linie auf weißen Untergrund ermitteln kann und vielleicht noch ihre Drehung errechnen kann. :shock:

Verfasst: 13.04.2006 20:23
von Froggerprogger
Ich würde mich schon freuen, wenn ich überhaupt eine schwarze Linie auf weißen Untergrund ermitteln kann und vielleicht noch ihre Drehung errechnen kann.
Stichworte, nach denen es vielleicht lohnt zu googlen:
Dilatationen, Erosionen, Sobel-Operator, Morphologische Operationen, Bild-Segmentierung, (Point, Line, Edge Detection), Maximum-Likelihood-classification, Watershed Segmentation, Gradienten, Pattern Matching, Klassifizierung mit neuronalen Netzen (Perceptron, Adaline, Madaline), Fuzzy-Logik, Kalmann-Filter. Oberbegriff: Image Processing oder sowas wie Bildverarbeitung und -analyse.

Ich kenne nur die unspektakuläreren und einfacheren der obigen Konzepte, und habe gerade nur einige Stichworte aus guten Büchern dazu erwähnt. Z.B. "Computergrafik und Bildverarbeitung von Nischwitz, Haberäcker", sowie "Digital Image Processing von Gonzales, Woods, Eddins"
Bei Bildern gilt wie bei Worten aus dem anderen Teil deines Projekts. Reine farbwertbezogene Algorithmen, oder Verzerrung, etc. sind relativ einfach. Schwierig wird es bei Objekterkennung und ggf. Wiedererkennen derselben, etc. Da wird es wieder so krass, dass man hier weder in ein paar Zeilen funktionierden Source hinschreiben könnte, noch dass wahrscheinlich überhaupt jemand hier die guten davon jemals verstanden oder angewendet hat. Ich hoffe ich irre mich, dann meldet euch mal.

Ich will ja nicht als Spielverderber dastehen, aber deine zahlreichen Threads hier im Forum erinnern langsam daran:
Ich möchte eine richtig geniale KI bauen, die all die besten Dateninterpretationsalgorithmen aus allen Bereichen unter einer Haube vereint. Wer macht mit und hat da Ideen ?
Viel Glück und Ausdauer!
:allright:

Verfasst: 18.04.2006 10:21
von Xaby
Ich werde nicht aufgeben, hätte mir zwar gewünscht, etwas mehr Unterstützung zu erhalten, aber braucht ihr ja nicht machen.

Wird es zwar länger dauern, aber irgendwas werd ich schon hinbekommen.

/:->

Verfasst: 20.04.2006 00:23
von inc.
Du solltest mal bei avisynth.org nachsehen.
Dort gibt es eine Filter-Sektion. Jene Filter kommen fast alle mit c++ sourcen daher. Da hast du eine Menge an Vorlagen für alle Arten von Videobearbeitungen.

Verfasst: 20.04.2006 13:47
von mk-soft
@xaby:

finde ich gut das du dich damit beschäftigst. Ist ein sehr komplexer bereich und beinhaltet noch sehr viel arbeit. Aus der Praxis weiss ich das gute Software und Hardware erst ab ca 6000€ zu erhalten ist. Aber bis dahin ist noch ein langer weg. Möchte dir aber nicht die Lust daran zu arbeiten nicht nehmen. Werde ich auf jeden fall verfolgen.

FF :wink:

Ich weiß, wie's geht

Verfasst: 22.04.2006 14:32
von Xaby
:allright: Mir ist gestern ein Gedanke zugefallen
ich hab so ein bisschen auf meinem Karopapier gemalt und da ist mir ne Simple Idee eingefallen.

Ich bin gerade dabei, es zu visualisieren, Bilder sagen ja mehr als Worte und mein Programm, das dies für mich erledigen soll, ist ja noch nicht fertig :roll:

Beschreibung:

Wir stellen uns vor, wir haben Objeke auf einer Fläche liegen. Nehmen wir mal ein Bild (mit Pixeln und son Zeug), sagen wir mal, das Blatt ist weiß, der Rest ist anders farbig.

Code: Alles auswählen

  ____________
|            |
|  [##]  ___ |
|       |   ||
|        \_/ |
|____________| 
Das ist also mein Blatt mit den zwei Objekten. Wenn man nun von links nach rechts immer von oben nach unten versucht linien zu zeichnen, dann stößt man mit der Linie nicht immer auf die Gegenseite.
Also die Linie trifft auf etwas anderes als die untere Seite des Bildes.
Somit ist bei einer nicht durch gezogenen Linie ein Hindernis ...
Man merkt sich nun den Punkt, wo die Linie auf das NichtPapierBlatt gekommen ist. Und wenn man das weiter führt, kommt die Linie irgendwann wieder an der Gegenseite an.
Und zwischen den Positionen, wo die Linien nicht durchgezogen werden konnten, muss also ein Objekt sein (ein zusammenhängendes gezeichnetes etwas)
Das reciht natürlich nicht aus. Danach wenn die TeilObjeke ermittelt worden sind, muss man wieder Linien ziehen. Diesmal aber nicht von Oben nach unten, sondern von links nach rechts.
Und man teilt die Objekte wieder, diesmal genauso nur halt um 90° gedreht. ...
Wenn nicht mehr geteilt werden kann, hat man ein Objekt vollständig ermittelt.

:shock: Ich glaube, keiner weiß, was ich meine :? Ich bin noch nicht fertig, aber kann mal meine Gedanken als Animation zeigen.

Code: Alles auswählen

;{- Information
; Autor : Folker Linstedt
; Programm zur Vorbereitung auf komplexe Videoanalyse
; Seit  : 21.04.2006
; Stand : 21.04.2006

;}/ Ende Information

Enumeration
#HauptFenster

#Sprite

#Ball
#Wand

EndEnumeration

Procedure MachFenster() 
  hWnd=OpenWindow(#HauptFenster, 0, 0, 1010, 710,  #PB_Window_SystemMenu | #PB_Window_WindowCentered | #PB_Window_SizeGadget | #PB_Window_TitleBar , "(c) Folker Linstedt 2006 :::: Best View 1024 x 768 and higher") 
  
EndProcedure 

;{/ initZeugs

InitSprite() 
InitSprite3D()
;}/

MachFenster() 
OpenWindowedScreen(WindowID(),0,0,1000,700,0,0,0)

Sprite3DQuality(1)


CreateSprite(#Sprite,256,256,#PB_Sprite_Memory)
StartDrawing(SpriteOutput(#Sprite))
  Box(0,0,256,256,RGB(60,60,60))
  Box(10,10,40,40,RGB(255,0,0))
  Box(70,10,40,40,RGB(255,0,0))
  Box(10,70,80,40,RGB(255,0,0))
  Box(0,200,180,56,RGB(255,0,0))
  Box(86,130,230,56,RGB(255,0,0))
  Box(200,0,56,56,RGB(255,0,0))
StopDrawing()
TransparentSpriteColor(#Sprite,60,60,60)

CreateSprite(#Ball,8,8,#PB_Sprite_Memory)
StartDrawing(SpriteOutput(#Ball))
  Circle(3,3,3,RGB(0,255,0))
StopDrawing()


CreateSprite(#Wand,16,16,#PB_Sprite_Memory)
StartDrawing(SpriteOutput(#Wand))
  Box(0,0,16,16,RGB(0,0,255))
StopDrawing()


Global x.l
Global y.l
Procedure Bewegung ()

EndProcedure



x= 90
y=103

 
Repeat
  
  Event = WindowEvent() 


  
  
  StartSpecialFX()
    DisplayTranslucideSprite(#Sprite,100,100,255)
    DisplayTranslucideSprite(#Ball,x,y,255)
    
    For a=0 To 15
      DisplaySprite(#Wand,356,100+16*a)
    Next
  StopSpecialFX()
  
  If SpritePixelCollision(#Ball,x,y,#Sprite,100,100)
  
   StartDrawing(ScreenOutput())
     DrawText("Jepp")
   StopDrawing()
  Else
    x=x+3
  
  EndIf
  
  

 
  FlipBuffers()
  
Until Event = #PB_Event_CloseWindow
Wenn es der grüne Punkt einmal von links nach rechts schafft, dann kann da ein TeilObjekt geschnitten werden.

:allright: Diese Methode hat Grenzen, aber sie ist schon relativ gut und müsste auch einfach zu realisieren sein.

/:-> Wie findet ihr die Idee? Und wenn ihr wollt, könnt ihr meinen Ansatz gern ausarbeiten. Bin leider etwas unter Zeitmangel leidend.

Und wenn man die TeilObjekte bzw. die einzelnen Objekte analysiert hat, kann man diese genauer betrachten und mit einer anderen Methode, wo ich auch schon eine Idee habe ... :allright: als Linien, Ecken, Vierecken, Kreise ... deklarieren ...

Meine Methode kurz erklärt. Ein Pixel wird betrachtet und beim ersten seine acht Freunde drumherrum. Die folgenden Pixel werden zwar auch alle betrachtet, aber wenn sich der RichtungsVektor zu stark ändert, ist es keine gerade Linie mehr ...
Dann könnte es eine Ecke oder eine Kurve sein ...

Mehr dazu, wenn das hier erstmal mit den TeilObjeken funzt.

Gruß, Folker :D

Die Antwort noch mal etwas genauer dargestellt

Verfasst: 22.04.2006 21:43
von Xaby
Hier die Halbe Lösung visuell Dargestellt.
Nach dem der Grüne Punkt das blaue Feld erreicht hat ist das Objekt quer zu teilen. Nach dem der Grüne Punkt unten das letzte Mal rübergehuscht ist, muss nun die Prozedur senkrecht wiederholt werden.
Um die TeilObjekte wieder in kleinere zu teilen.

/:-> Gut, das kann die Demo noch nicht, aber soll sie ja auch nicht.
Ich werd wohl irgendwas mit dynamischen Arrays oder LinkedList oder so machen müssen, um die Felder der Objekte zu erfassen

Schaut einfach mal und lasst euch inspirieren

Code: Alles auswählen

;{- Information
; Autor : Folker Linstedt
; Programm zur Vorbereitung auf komplexe Videoanalyse
; Seit  : 21.04.2006
; Stand : 21.04.2006

;}/ Ende Information

Enumeration
#HauptFenster
#Sprite
#Ball
#Wand
#Bild
EndEnumeration

Procedure MachFenster() 
  hWnd=OpenWindow(#HauptFenster, 0, 0, 1010, 710,  #PB_Window_SystemMenu | #PB_Window_WindowCentered | #PB_Window_SizeGadget | #PB_Window_TitleBar , "(c) Folker Linstedt 2006 :::: Best View 1024 x 768 and higher") 
  
EndProcedure 

;{/ initZeugs
InitSprite() 
InitSprite3D()
;}/

MachFenster() 
OpenWindowedScreen(WindowID(),0,0,1000,700,0,0,0)

Sprite3DQuality(1)

CreateImage(#Bild,1000,700)

CreateSprite(#Sprite,256,256,#PB_Sprite_Memory)
StartDrawing(SpriteOutput(#Sprite))
  Box(0,0,256,256,RGB(60,60,60))
  Box(10,10,40,40,RGB(255,0,0))
  Box(70,10,40,40,RGB(255,0,0))
  Box(10,70,80,40,RGB(255,0,0))
  Box(0,200,180,56,RGB(255,0,0))
  Box(86,130,230,56,RGB(255,0,0))
  Box(200,0,56,56,RGB(255,0,0))
StopDrawing()
TransparentSpriteColor(#Sprite,60,60,60)

CreateSprite(#Ball,16,16,#PB_Sprite_Memory)
StartDrawing(SpriteOutput(#Ball))
  Box(0,0,4,4,RGB(60,60,60))
  Circle(7,3,3,RGB(255,255,0))
StopDrawing()

CreateSprite(#Wand,16,16,#PB_Sprite_Memory)
StartDrawing(SpriteOutput(#Wand))
  Box(0,0,16,16,RGB(0,0,255))
StopDrawing()

Global x.l
Global y.l

Procedure Bewegung ()

  If y>260+100
    StartDrawing(ImageOutput())
      DrawText("Fertig")
    StopDrawing()
  Else
  If SpritePixelCollision(#Ball,x,y,#Sprite,100,100)
     x= 90
     y=y+3
  Else
    x=x+3
    If x>260+90
      StartDrawing(ImageOutput()) ; Keine Ahnung ??? Weiß wohl nicht, welches Image ...
        LineXY(90,y,300,y,RGB(255,255,255)) 
      StopDrawing()
      x=90
      y=y+3
    EndIf
  EndIf
  EndIf
  
EndProcedure

x= 90
y=103

DisplayTranslucideSprite(#Sprite,100,100,255)
Repeat
  
  Event = WindowEvent() 
 
  StartDrawing(ScreenOutput()) ; geht wohl nicht, keine Ahnung
    DrawImage(#Bild,0,0)
  StopDrawing()
  
  StartSpecialFX()
    DisplayTranslucideSprite(#Ball,x,y,255)
  
    For a=0 To 15
      DisplaySprite(#Wand,356,100+16*a)
    Next
    
  StopSpecialFX()
  
  Bewegung()

  FlipBuffers()
  
Until Event = #PB_Event_CloseWindow
Viel Spaß :allright:

Verfasst: 25.04.2006 07:28
von Xaby
Ich bin kurz davor einen Durchbruch zu erlangen.
Meine Methoden funktionieren und sind gut.
Werd sie aber noch verbessern, damit hier nicht wieder rumgemekelt wird.

Bis dahin schaut euch mal folgende Seite an.

http://www.mathematische-basteleien.de/herz.htm

Netten Gruß, Folker :shock:

Verfasst: 25.04.2006 15:25
von DeltaG
Xaby hat geschrieben:Ich bin kurz davor einen Durchbruch zu erlangen.
Meine Methoden funktionieren und sind gut.
Werd sie aber noch verbessern, damit hier nicht wieder rumgemekelt wird.

Bis dahin schaut euch mal folgende Seite an.

http://www.mathematische-basteleien.de/herz.htm

Netten Gruß, Folker :shock:
Der Tip mit dem Link zu den mathematischen Basteleien ist super. :allright:
Den hätte ich früher brauchen können, hätte mir manche Knobelei erspart. /:->

Wobei?
Hier: http://www.purebasic.fr/german/viewtopic.php?t=8072
und
hier: http://www.purebasic.fr/german/viewtopic.php?t=7783.

DeltaG

Verfasst: 27.04.2006 20:59
von Xaby
Heho, ich kenn mich mit Linked Lists noch noch nicht aus ...
vielleicht hat ja mal jemand Lust, mich zu unterstützen, ich würd mich freuen.
Ihr solltet ein schwarzes Bild nehmen und da ein paar Sachen rein malen.
Das Bild sollte 400 x 300 Pixel sein.
Die richtige Ausarbeitung und mit Kantenfinden und so, kommt noch.
Ist erstmal die Grundidee. Und mit LinkedList geht's besser.
Aber muss ich schauen. Würde halt schneller gehen, wenn ihr was dazu schreibt. /:->

Code: Alles auswählen

Enumeration
#HauptFenster
#Sprite
#Ball
#Wand
#Bild
EndEnumeration

Global x.l
Global y.l
Global xmax.l
Global ymax.l


Procedure MachFenster() 
  hWnd=OpenWindow(#HauptFenster, 0, 0, 410, 310,  #PB_Window_SystemMenu | #PB_Window_WindowCentered | #PB_Window_SizeGadget | #PB_Window_TitleBar , "(c) Folker Linstedt 2006 :::: Best View 1024 x 768 and higher  ;-)") 
EndProcedure 

;{/ initZeugs


;}/
; sprite$="Zeugs.bmp"
sprite$=OpenFileRequester("Bild auswählen","c:\","BMP|*.bmp;",-1) 


MachFenster() 
;OpenWindowedScreen(WindowID(),0,0,1000,700,0,0,0)
LoadImage(1,sprite$) 

Procedure.l LineSearchS(xx.l,yy.l,l.l)
  
  Ereignis=0
  
  For i=0 To l-2
   Punkt=Point(xx,yy+i) ; Punkt/Farbe könnte hier später gleich gespeichert werden
   ;  Plot(x,y+i,RGB(0,0,255))
     
   If Punkt=0 
      Ereignis=0
    Else
      Ereignis=yy+i ; Also hier mein ich
      Break
    EndIf
  Next
  

  ProcedureReturn Ereignis
EndProcedure



Dim Dinglis(100,1)
Global Anz.l

Procedure FindDenScheisz()

StartDrawing(WindowOutput())
LineSearchS(x,y,ymax)
While s=0 And x<xmax
  x+1
  s=LineSearchS(x,y,ymax)
  
Wend
  ; Erster Punkt des Objektes x,s
  If x<xmax
  Circle(x+2,s,2,RGB(0,255,0))
  Dinglis(Anz*2,  0)=x
  Dinglis(Anz*2,  1)=s
  Dinglis(Anz*2+1,1)=s
  EndIf 
 
Repeat
  x+1
  s=LineSearchS(x+1,y,ymax)
  ; Ausdehnung des Rechtecks soweit wie möglich, einzelne schräge Linien eignen sich am besten
  ; einzelne Kreise werden knapp halbiert
  If s>Dinglis(Anz*2+1,1) : Dinglis(Anz*2+1,1)=s : EndIf
  If s<>0 : If s<Dinglis(Anz*2  ,1) : Dinglis(Anz*2,1)=s : EndIf : EndIf
  
  ; jedes X, S müsste in eine Liste gespeichert werden
  ; anschließend muss die Methode noch waagerecht angewandt werden
  ; zusammenhängende Objekte werden dadurch geteilt ...
  ; dies muss so oft wiederholt werden, bis kein Objekt mehr teilbar ist
  
  ; Zurzeit findet nur ein Durchlauf statt von oben nach unten.
  ; die Durchläufe könnten so optimiert sein, dass kein Punkt doppelt abgefragt werden müsste
  

Until s=0 Or x+1>xmax
  s=LineSearchS(x,y,ymax)
  ; Letzter Punkt des Objekts
  If x+1<xmax
    Circle(x-2,s,2,RGB(255,0,0))
    Dinglis(Anz*2+1,0)=x
    
    Anz+1 
    
  EndIf
  
StopDrawing()
EndProcedure

  StartDrawing(WindowOutput()) ; geht wohl nicht, keine Ahnung
    DrawImage(UseImage(1),0,0)
  StopDrawing()
  
  
xmax=399 ; Bildgröße  X 400
ymax=299 ; Bildgröße  Y 300
x=0
y=0
Anz=0
 
While x<xmax
  FindDenScheisz() 
Wend
 
 Procedure Rectangle(x1.l,y1.l,x2.l,y2.l,f.l)
   LineXY(x1,y1,x1,y2,f)
   LineXY(x1,y2,x2,y2,f)
   LineXY(x2,y2,x2,y1,f)
   LineXY(x2,y1,x1,y1,f)
 EndProcedure
 
 For i=0 To Anz-1
   StartDrawing(WindowOutput())
     Rectangle(Dinglis(i*2,0),Dinglis(i*2,1),Dinglis(i*2+1,0),Dinglis(i*2+1,1),RGB(255,255,255))
   StopDrawing()
 Next
 
 
Repeat
  Event = WindowEvent() 
  
  Delay(10)
Until Event=#PB_Event_CloseWindow