Bewegungserkennung bei WebCam

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
coder
Beiträge: 204
Registriert: 25.09.2005 17:53
Computerausstattung: Intel Core2Quad Q8200 @ 2.33GHz
ASUS P5Q3, 2GB DDR3-1066 RAM, ATi Raedeon HD 4850
Wohnort: Deutschland
Kontaktdaten:

Beitrag von coder »

Gibt immer noch einen IMA an der selben Stelle :(

kann mir keiner helfen? ich selbst habe keine Ahnung warum was durch einen Pointer geteilt werden muss...
Windows 7 x64 | PureBasic 4.60 4.50 4.02
Ja verdammt, meine Eltern wohnen immer noch bei mir!
Benutzeravatar
X360 Andy
Beiträge: 1206
Registriert: 11.05.2008 00:22
Wohnort: Bodensee
Kontaktdaten:

Beitrag von X360 Andy »

Hat jemand noch eine Lösung für das Probem (siehe über mir)

Wäre wirklich Super !!!
Andesdaf
Moderator
Beiträge: 2671
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Beitrag von Andesdaf »

So dürftes gehen:

Code: Alles auswählen

UseJPEGImageEncoder()

#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

Enumeration
  #G_Modus1
  #G_Modus2
  #G_Modus3
  #G_Modus4
  #G_Color
  #G_Grid
  #G_Stepping
  #G_SteppingText
  #G_Tolerance
  #G_ToleranceText
  #G_Time
  #G_TimeText
  #G_Starttime
  #G_StarttimeText
  #G_Start
  #G_Stop
  #G_Quaders
  #G_Pics
  #G_Log
EndEnumeration


Tolerance = 70
Stepping = 10
time = 1000
starttime = 10000
SteppingDivide = Stepping * Stepping
Color = $FFFFFF
LastTime = ElapsedMilliseconds()

#ImgPerSec = 50 ; HIER EDITIEREN^^
#Time = 1000 / #ImgPerSec

If OpenLibrary(0, "AVICAP32.DLL") = 0
  MessageRequester("Error", "Cannot find AVICAP32.DLL!", 16)
  End
EndIf


Structure RGB
  Red.c
  Green.c
  Blue.c
EndStructure

Global NewList LastAverage.RGB()
Global NewList NewAverage.RGB()


OpenWindow(1, 0, 0, 240, 40, "Cam Motion Detectiv", #PB_Window_TitleBar | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(1))
  TextGadget(#PB_Any, 10, 12, 220, 20, "Initialisierung, bitte warten...")


OpenWindow(0, 0, 0, 368, 650, "Cam Motion Detectiv", #PB_Window_SystemMenu | #PB_Window_Invisible | #PB_Window_ScreenCentered)

CreateGadgetList(WindowID(0))
Frame3DGadget(#PB_Any, 10, 10, 348, 330, "Vorschau")
OptionGadget(#G_Modus1, 34, 280, 60, 20, "Modus 1")
  SetGadgetState(#G_Modus1, 1)
OptionGadget(#G_Modus2, 114, 280, 60, 20, "Modus 2")
OptionGadget(#G_Modus3, 194, 280, 60, 20, "Modus 3")
OptionGadget(#G_Modus4, 274, 280, 60, 20, "Modus 4")

ButtonGadget(#G_Color, 30, 305, 100, 22, "Farbe")

CheckBoxGadget(#G_Grid, 150, 307, 100, 20, "Gitter anzeigen")
  SetGadgetState(#G_Grid, 1)

TextGadget(#PB_Any, 10, 350, 348, 20, "Toleranz:")
TrackBarGadget(#G_Tolerance, 10, 370, 318, 22, 0, 255, %00100000)
  SetGadgetState(#G_Tolerance, Tolerance)
TextGadget(#G_ToleranceText, 328, 370, 30, 20, Str(Tolerance), #PB_Text_Right)

TextGadget(#PB_Any, 10, 400, 348, 20, "Testgröße:")
TrackBarGadget(#G_Stepping, 10, 420, 318, 22, 2, 32, %00100000)
  SetGadgetState(#G_Stepping, Stepping)
TextGadget(#G_SteppingText, 328, 420, 30, 20, Str(Stepping) + " px", #PB_Text_Right)

TextGadget(#PB_Any, 10, 450, 348, 20, "Time:")
TrackBarGadget(#G_Time, 10, 470, 318, 22, 1, 10, %00100000)
  SetGadgetState(#G_Time, time/1000)
TextGadget(#G_TimeText, 328, 470, 30, 20, Str(time/1000), #PB_Text_Right)

TextGadget(#PB_Any, 10, 500, 348, 20, "Starttime:")
TrackBarGadget(#G_Starttime, 10, 520, 318, 22, 10, 60, %00100000)
  SetGadgetState(#G_Starttime, starttime/1000)
TextGadget(#G_StarttimeText, 328, 520, 30, 20, Str(starttime/1000), #PB_Text_Right)

ButtonGadget(#G_Start, 10, 550, 50, 20, "Start")
ButtonGadget(#G_Stop , 70, 550, 50, 20, "Stop" )
CheckBoxGadget(#G_Quaders, 130, 550, 60, 20, "Quaders")
CheckBoxGadget(#G_Pics, 200, 550, 40, 20, "Pics")
CheckBoxGadget(#G_Log, 250, 550, 40, 20, "Log")

;hCaptureWnd = CallFunction(0, "capCreateCaptureWindowA", "Test", #WS_VISIBLE | #WS_CHILD, 0, 0, 320, 240, WindowID(0), 0)
hCaptureWnd = CallFunction(0, "capCreateCaptureWindowA", "Test", #WS_VISIBLE | #WS_CHILD, 1, 1, 1, 1, WindowID(0), 0)
If hCaptureWnd = 0
  MessageRequester("Error", "Cannot open device!", 16)
  End
EndIf

SendMessage_(hCaptureWnd, #WM_CAP_DRIVER_CONNECT, 0 , 0)

CloseWindow(1)

HideWindow(0, 0)

elapsed = ElapsedMilliseconds() + starttime

DisableGadget(#g_stop,1)

Repeat
  EventID = WaitWindowEvent(#Time / 2) ; Um "doppelte" Überschneidungen zu verhindern...
 
  If EventID = #PB_Event_Gadget
    Select EventGadget()
    Case #G_Tolerance
      Tolerance = GetGadgetState(#G_Tolerance)
      SetGadgetText(#G_ToleranceText, Str(Tolerance))
     
    Case #G_Stepping
      Stepping = GetGadgetState(#G_Stepping)
      SteppingDivide = Stepping * Stepping
      SetGadgetText(#G_SteppingText, Str(Stepping) + " px")
      ClearList(LastAverage())
     
    Case #G_Time
      time = GetGadgetState(#G_Time)*1000
      SetGadgetText(#G_TimeText, Str(time/1000))
     
    Case #G_Starttime
      starttime = GetGadgetState(#G_Starttime)*1000
      SetGadgetText(#G_StarttimeText, Str(starttime/1000))
     
    Case #G_Color
      NewColor = ColorRequester(Color)
      If NewColor <> -1
        Color = NewColor
      EndIf
     
    Case #G_Start
      Start = 1
      DisableGadget(#G_Start,1)
      DisableGadget(#G_Stop ,0)
      elapsed = ElapsedMilliseconds() + starttime - time
      DisableGadget(#G_Modus1,1)
      DisableGadget(#G_Modus2,1)
      DisableGadget(#G_Modus3,1)
      DisableGadget(#G_Modus4,1)
      DisableGadget(#G_Color,1)
      DisableGadget(#G_Grid,1)
      DisableGadget(#G_Stepping,1)
      DisableGadget(#G_Tolerance,1)
      DisableGadget(#G_Time,1)
      DisableGadget(#G_Starttime,1)
      DisableGadget(#G_Quaders,1)
      DisableGadget(#G_Pics,1)
      DisableGadget(#G_Log,1)
     
    Case #G_Stop
      Start = 0
      DisableGadget(#G_Start,0)
      DisableGadget(#G_Stop ,1)
      elapsed = ElapsedMilliseconds() + starttime - time
      DisableGadget(#G_Modus1,0)
      DisableGadget(#G_Modus2,0)
      DisableGadget(#G_Modus3,0)
      DisableGadget(#G_Modus4,0)
      DisableGadget(#G_Color,0)
      DisableGadget(#G_Grid,0)
      DisableGadget(#G_Stepping,0)
      DisableGadget(#G_Tolerance,0)
      DisableGadget(#G_Time,0)
      DisableGadget(#G_Starttime,0)
      DisableGadget(#G_Quaders,0)
      DisableGadget(#G_Pics,0)
      DisableGadget(#G_Log,0)
     
     
    EndSelect
  EndIf
 
  If EventID = #WM_CLOSE
    SendMessage_(hCaptureWnd, #WM_CAP_SET_PREVIEW, 0, 0)
    SendMessage_(hCaptureWnd, #WM_CAP_DRIVER_DISCONNECT, "Test", 0)
    DestroyWindow_(hCaptureWnd)
    CloseLibrary(0)
    End
  EndIf
 
 
  If ElapsedMilliseconds() - LastTime > #Time
    SendMessage_(hCaptureWnd, #WM_CAP_GRAB_FRAME, 0, 0)
    SendMessage_(hCaptureWnd, #WM_CAP_EDIT_COPY, 0, 0)
    hImg = GetClipboardImage(0, 24)
   
   
    If hImg
      If GetObject_(ImageID(0), SizeOf(BITMAP), @ImageInfo.BITMAP) And StartDrawing(ImageOutput(0))
        If GetGadgetState(#G_Modus1)
          DrawingMode(#PB_2DDrawing_Default)
        ElseIf GetGadgetState(#G_Modus2)
          DrawingMode(#PB_2DDrawing_Outlined)
        ElseIf GetGadgetState(#G_Modus3)
          DrawingMode(#PB_2DDrawing_XOr)
        ElseIf GetGadgetState(#G_Modus4)
          DrawingMode(#PB_2DDrawing_XOr | #PB_2DDrawing_Outlined)
        EndIf
       
        ResetList(LastAverage())
       
        X = 0
        Repeat
          Y = 0
          Repeat
            CountRed.l = 0
            CountGreen.l = 0
            CountBlue.l = 0
           
            For PixelX = X To X + Stepping
              For PixelY = Y To Y + Stepping
                *ImgPointer.RGB = ImageInfo\bmBits + PixelX + PixelY * ImageInfo\bmWidthBytes
               
                CountRed + *ImgPointer\Blue
                CountGreen + *ImgPointer\Green
                CountBlue + *ImgPointer\Red
              Next
            Next
           
            AddElement(NewAverage())
            NewAverage()\Red = CountRed / SteppingDivide
            NewAverage()\Green = CountRed / SteppingDivide
            NewAverage()\Blue = CountRed / SteppingDivide
           
            If NextElement(LastAverage())
              If Abs(LastAverage()\Red - NewAverage()\Red) > Tolerance
                If GetGadgetState(#G_Quaders) = 1
                  Box(X, Y, Stepping, Stepping, Color)
                EndIf
                motion = 1
              ElseIf Abs(LastAverage()\Green - NewAverage()\Green) > Tolerance
                If GetGadgetState(#G_Quaders) = 1
                  Box(X, Y, Stepping, Stepping, Color)
                EndIf
                motion = 1
              ElseIf Abs(LastAverage()\Blue - NewAverage()\Blue) > Tolerance
                If GetGadgetState(#G_Quaders) = 1
                  Box(X, Y, Stepping, Stepping, Color)
                EndIf
                motion = 1
              EndIf
            EndIf
           
            Y + Stepping
          Until Y >= ImageInfo\bmHeight - Stepping
         
          X + Stepping
        Until X >= ImageInfo\bmWidth - Stepping
       
       
        If GetGadgetState(#G_Grid)
          For PixelX = 0 To ImageInfo\bmWidth-1 Step 4
            For PixelY = 0 To ImageInfo\bmHeight-1 Step 32
              *ImgPointer.RGB = ImageInfo\bmBits + PixelX + PixelY * ImageInfo\bmWidthBytes
              *ImgPointer\Red = 255 - *ImgPointer\Red
              *ImgPointer\Green = 255 - *ImgPointer\Green
              *ImgPointer\Blue = 255 - *ImgPointer\Blue
            Next
          Next
         
          For PixelX = 0 To ImageInfo\bmWidth-1 Step 32
            For PixelY = 0 To ImageInfo\bmHeight-1 Step 4
              *ImgPointer.RGB = ImageInfo\bmBits + PixelX + PixelY * ImageInfo\bmWidthBytes
             
              *ImgPointer\Red = 255 - *ImgPointer\Red
              *ImgPointer\Green = 255 - *ImgPointer\Green
              *ImgPointer\Blue = 255 - *ImgPointer\Blue
            Next
          Next
        EndIf
       
        StopDrawing()
      EndIf
     
     
      ClearList(LastAverage())
     
      ForEach NewAverage()
        AddElement(LastAverage())
        LastAverage()\Red = NewAverage()\Red
        LastAverage()\Green = NewAverage()\Green
        LastAverage()\Blue = NewAverage()\Blue
      Next
     
      ClearList(NewAverage())
     
      If motion = 1 And ElapsedMilliseconds() >= elapsed + time And start = 1
        If Day(Date()) < 10
          Day$ = "0"+Str(Day(Date()))
        Else
          Day$ = Str(Day(Date()))
        EndIf
        If Month(Date()) < 10
          Month$ = "0"+Str(Month(Date()))
        Else
          Month$ = Str(Month(Date()))
        EndIf
        If Hour(Date()) < 10
          Hour$ = "0"+Str(Hour(Date()))
        Else
          Hour$ = Str(Hour(Date()))
        EndIf
        If Minute(Date()) < 10
          Minute$ = "0"+Str(Minute(Date()))
        Else
          Minute$ = Str(Minute(Date()))
        EndIf
        If Second(Date()) < 10
          Second$ = "0"+Str(Second(Date()))
        Else
          Second$ = Str(Second(Date()))
        EndIf
        Debug "move"
        If GetGadgetState(#G_Pics) = 1
          CreateDirectory("MotionPics")
          CreateDirectory("MotionPics/"+Day$+Month$)
          SaveImage(0,"MotionPics/"+Day$+Month$+"/"+Hour$+Minute$+Second$+".jpg",#PB_ImagePlugin_JPEG)
        EndIf
        If GetGadgetState(#G_Log) = 1
          CreateDirectory("MotionLogs")
          OpenFile(0,"MotionLogs/"+Day$+Month$+".log")
          FileSeek(0,Lof(0))
          WriteStringN(0, "New Motion @ "+Hour$+":"+Minute$+":"+Second$)
        EndIf
        motion = 0
        elapsed = ElapsedMilliseconds()
      EndIf
     
      If StartDrawing(WindowOutput(0))
        DrawImage(ImageID(0), 24, 32, 320, 240)
        StopDrawing()
      EndIf
     
     
     
    EndIf
   
   
    LastTime = ElapsedMilliseconds()
  EndIf
 
ForEver 
Win11 x64 | PB 6.20
gpphjs
Beiträge: 11
Registriert: 07.07.2006 13:35
Wohnort: 18374 Seeheilbad Zingst

Beitrag von gpphjs »

Versucht es doch mal hiermit, die Webcam beobachtet bei mir den Sandboden bei Winderosion aus 8 cm Entfernung und zählt fast jedes Sandkorn, dass sich in der letzten 1/10 Sekunde bewegt hat (Panasonic CF-30). Schwelle=170 sollte bei einer besseren Webcam auch niedriger sein können (Trustmaster TM507A, USB 1.1 aber mit LED für die Nacht). Mit einer USB 2.0 Webcam sollte alles noch viel schneller gehen, kann also beim Proggen im Hintergrund laufen. Achtung, Path$ anpassen!

Code: Alles auswählen

Structure cBGR
  b.c
  g.c
  r.c
EndStructure
 
#Breite =320
#Hoehe  =240
#Tiefe  =  3
#Laenge =  1
#SIZE = #Breite*#Hoehe*#Tiefe*#Laenge

Global  *bild1    = AllocateMemory(#SIZE)
Global  *bild2    = AllocateMemory(#SIZE)
Global Wert.l
Global schwelle.f = 170
Global hbmp.l=CreateImage(3,320,240,24)
Global zeit.s=""
Global hWebcam.l

Path$ ="C:\pc\sediment\zingst09\"
Datei$=FormatDate("%yy%mm%dd_%hh%ii%ss.txt", Date())

CreateFile (0,Path$+Datei$)
      WriteStringN(0,"Programm: Cam_test.pb")   

Procedure BildAbs(hWebcam)
    Protected *Color1.cBGR
    Protected *Color2.cBGR
    Protected k.l, x.l, ausgabe.s=""
    Protected start.l,laenge.l=#SIZE
    Protected stop.l
    Wert=0
    *Color1   = *bild1
    *Color2   = *bild2
  start=ElapsedMilliseconds()
    SendMessage_(hWebcam, #WM_CAP_GRAB_FRAME, 0 , 0) 
    SendMessage_(hWebcam, #WM_CAP_EDIT_COPY, 0, 0)
    GetClipboardImage(3,24)
    GetBitmapBits_(ImageID(3),#SIZE,*bild1)
   For k=0 To #SIZE-3 Step 3 ; 
       x=  *Color1\r +*Color1\g+*Color1\b - *Color2\r -*Color2\g-*Color2\b
   If x > schwelle Or -x > schwelle     ; das ist eine ABS Konstruktion!
      Wert+1
    EndIf
    *Color1 + 3
    *Color2 + 3
  Next
  
  ClearClipboard() 
        StartDrawing( WindowOutput(0) )
        DrawText(30, 400,"                                                               ")      
        DrawText(30, 400,"Differenz "+  Str(Wert))      
        DrawText(30, 450,"Schwellwert "+  StrF(schwelle))      
        StopDrawing()
    CopyMemory(*bild1,  *bild2, #SIZE)
  stop=ElapsedMilliseconds()
    zeit.s=FormatDate("%hh:%ii:%ss", Date())
    ausgabe+"Cam "+FormatDate("%hh:%ii:%ss", Date())  
    ausgabe+" "+  Str(Wert)+" "+" CPU Zeit "+Str(stop-start)+" Zeit "+zeit
       WriteStringN(0,ausgabe)   
EndProcedure



hWnd = OpenWindow(0, 0, 0, 1000, 600, "SandCam_COM", #PB_Window_SystemMenu)

                    
If OpenLibrary(0, "AVICAP32.DLL")
  hWebcam = CallFunction(0, "capCreateCaptureWindowA", "BLUBBER", #WS_VISIBLE + #WS_CHILD, 10, 30, 320, 240, hWnd, 0)

 
 If SendMessage_(hWebcam, #WM_CAP_DRIVER_CONNECT          , 0 , 0)  ; connect driver, KameraID.l=0
  Else
  MessageRequester("Webcam","Webcam ist in Benutzung oder nicht angeschlossen")
 EndIf

 Repeat
       BildAbs(hWebcam)  
    Event = WaitWindowEvent(10) ;hier noch ein Delay wenn es langsamer gehen soll
    Select Event
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
  Until Quit = 1
  SendMessage_(hWebcam, #WM_CAP_SET_PREVIEW       , 0, 0)
  SendMessage_(hWebcam, #WM_CAP_DRIVER_DISCONNECT, "BLUBBER", 0)
  CloseWindow(0)
  CloseLibrary(0)
  CloseFile(0)
 EndIf
End

super_castle
Beiträge: 557
Registriert: 29.11.2005 15:05

Beitrag von super_castle »

Bei Purebasic 4.4 Beta 2 wird darin derText beanstandet: "SandCam_COM"

hWnd = OpenWindow(0, 0, 0, 1000, 600, "SandCam_COM", #PB_Window_SystemMenu)

mfg
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

Bei mir läuft die Zeile ohne Fehler durch. Allerdings

Code: Alles auswählen

hWebcam = CallFunction(0, "capCreateCaptureWindowA", "BLUBBER", #WS_VISIBLE + #WS_CHILD, 10, 30, 320, 240, hWnd, 0)
geht so nicht mehr, muss jetzt

Code: Alles auswählen

hWebcam = CallFunction(0, "capCreateCaptureWindowA", @"BLUBBER", #WS_VISIBLE + #WS_CHILD, 10, 30, 320, 240, hWnd, 0)
heißen, da der Parameter Typ von CallFunction() von ANY auf INTEGER geändert wurde.

Gruß, Alex
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
super_castle
Beiträge: 557
Registriert: 29.11.2005 15:05

Re: Bewegungserkennung bei WebCam

Beitrag von super_castle »

auh...man...
..mit der Beta7 erscheint jetzt der Text nicht in den 2 Zeilen.
Antworten