Seite 1 von 1

Das LEGO-Stein-Orakel

Verfasst: 13.04.2006 14:34
von Xaby
Hallo Fans,

Zutaten:

Man nehme ein helles weißes Blatt Papier. in einem Abstand zum Blatt von ca. 10 cm positioniert man eine LEGO-WebCam oder eine andere WebCam. Auf das Blatt legt man einen LEGO-Stein. Schwarz sollte er sein.

Dann schaltet man mein Programm an ...
Und es kann mit eurer Hilfe sagen, welcher Lego-Stein da liegt. Welchen Winkel er besitzt, wie groß er ist, welche Noppen er hat. Wie die Maße sind. ... Aber es ist halt noch nicht ganz fertig ... vielleicht könnt ihr es euch ansehen und hier und da eine Idee zu einem schnellen Algorithmus für die Objekterkennung beisteuern. :?

Code: Alles auswählen

;{- Information
; Folker Linstedt 2006
;  Stand   13.04.2006
;  Anfang: 11.04.2006
;}/
;aus "capture.pb" und "inc.pb"
Enumeration
#Link2
#Link3


#Sprite3D
#Sprite3D2
EndEnumeration

Dim Farbe.b(4)

Dim Feld.b(15,15)
Dim Sprites.l(15,15)
Dim Sp3D.l(15,15)


;- 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)


For b=0 To 15
For a=0 To 15

  Sprites(a,b)=b*16+a+1000
  Sprites(a,b)=b*16+a+2000
  CreateSprite(Sprites(a,b),8,8,#PB_Sprite_Texture)
  StartDrawing(SpriteOutput(Sprites(a,b)))
    Box(0,0,7,7,RGB(127,127,127))
  StopDrawing()
  CreateSprite3D(Sp3D(a,b),Sprites(a,b))
Next
Next




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
          
          v0=70
          v1=35
          v2=0
          ; If Farbe(0) <v0 And Farbe(1)<v1 And Farbe(2)<v2 ; Kantenfinden, wenn v2=50
            If (Farbe(0) <v0 And Farbe(1)<v1 And Farbe(2)>v2)<>1
             
              Farbe(0)=0
              Farbe(1)=0
              Farbe(2)=0
             
              Else  
              Farbe(0)=255
              Farbe(1)=255
              Farbe(2)=255
            EndIf
            
          For f=0 To 3  
            PokeB(*Pointer2+i2*128*4+i*4+f, Farbe(f))
          Next
          
          ;PokeB(*Pointer2+i2*128*4+i*4+3, Farbe(3)) ; Alpha
          
          
        Next i
        Next i2
        
        
        For b=0 To 15
        For a=0 To 15
        q=0
        
          For y=0 To 7
          For x=0 To 7
          
            xa=8*a+x
           ; Debug xa
            ya=8*b+y
            If  PeekB(*Pointer2+ya*128*4+xa*4) < 0 ; Gibt ja nur Schwarz und Weiß ... aber krisselt
              q=q+1
            EndIf
        
          Next
          Next
          If q>15 ; Mehr als ... bestimmt Anzahl der roten Punkte indirekt
            Feld(a,b)=1
          Else 
            Feld(a,b)=0
          EndIf
        
        Next
        Next
        
        ;/ Berechnungen zur Positionsbestimmung
        
        
        
        ;}- 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)
         
         For b=0 To 15
           For a=0 To 15
              StartDrawing(SpriteOutput(Sprites(a,b)))
               If Feld(a,b)=1
                Box(0,0,7,7,RGB(255,0,0))
                Else
                Box(0,0,7,7,RGB(127,127,127)) 
                EndIf 
              StopDrawing()
              CreateSprite3D(Sp3D(a,b),Sprites(a,b))
             
            
            DisplaySprite3D(Sp3D(a,b),5+8*a,200+8*b) 
           Next
         Next
         
        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
Ich hätte ja auch gern ein Bild von dem Expirimentenaufbau mit reingestellt, aber sowas wie Bild hochladen gibts ja leider nicht.
:allright:
Also dann, bin auf eure Mithilfe gespannt

Verfasst: 13.04.2006 20:38
von DarkDragon
Ähm ja, das ganze hast du schonmal Verfasst:

http://www.purebasic.fr/german/viewtopi ... highlight=

Verfasst: 14.04.2006 10:33
von Batze
Dann könnte ich mal meine 200000 Legosteine sortieren.
So in Kisten durcheinander geworfen bekommt man auf Flomärkten nämlich dummerweise nix dafür :freak:

Verfasst: 14.04.2006 10:56
von Kaeru Gaman
@Batze

:lol:

...ich fürchte nur, die vom robot angesteuerte sortieranlage zu bauen nimmt mehr zeit in anspruch, als die steine per hand zu sortieren...

Verfasst: 14.04.2006 11:35
von onny
mein pc hat hämmungslos einen neustart durchgeführt, nachdem ich das programm gestartet habe :roll:

Verfasst: 14.04.2006 11:42
von Kaeru Gaman
onny hat geschrieben:mein pc hat hämmungslos einen neustart durchgeführt, nachdem ich das programm gestartet habe :roll:
hattest du denn ebenso hemmungslos eine lego-cam angeschlossen?

Verfasst: 15.04.2006 11:07
von Batze
ich kann dazu nur eins sagen, die Legocam auf XP läuft abselut sch.... :freak:
ich weiß schon ohne testen dass das Prog bei mir abstürzt, wegen AVICAP.

Verfasst: 15.04.2006 11:24
von DarkDragon
Batze hat geschrieben:ich kann dazu nur eins sagen, die Legocam auf XP läuft abselut sch.... :freak:
ich weiß schon ohne testen dass das Prog bei mir abstürzt, wegen AVICAP.
Es gibt 2 Avicap libraries: 1 Wrapper für PureBasic und 1 richtiges("AviCap32.dll" aus dem system).

Verfasst: 15.04.2006 15:36
von onny
löl, hab keine LEGO-CAM angeschlossen gehabt, aber muss der PC gleich neustarten? na ja, er ist eher abgestürzt... :oops:

Verfasst: 16.04.2006 11:30
von Batze
DarkDragon hat geschrieben:Es gibt 2 Avicap libraries: 1 Wrapper für PureBasic und 1 richtiges("AviCap32.dll" aus dem system).
Geht beides nicht, hab auch schon etliche male versucht es doch hin zu bekommen, aber ohne Erfolg :(