Détecteur de mouvements avec webcam

Programmation d'applications complexes
Avatar de l’utilisateur
DjPoke
Messages : 121
Inscription : mar. 02/nov./2010 13:53
Localisation : Corte, Corse, France
Contact :

Détecteur de mouvements avec webcam

Message par DjPoke »

Bonjour à tous,

Je viens de programmer un détecteur de mouvements à partir d'une webcam et de la lib/dll trouvée ici même sur le forum (escapi)
Je souhaiterai savoir si mon code peut fonctionner mieux.
Actuellement, les mouvements sont détectés, mais j'ai été obligé de réduire la sensibilité à cause du bruit généré par les webcams.
Du coup, un mouvement de la main est suivi, mais un mouvement de la bouche ou des yeux doit être exagéré pour être capté par le programme.

Merci d'avance de vos précieux conseils.

Code : Tout sélectionner

timeBeginPeriod_(1)
IncludeFile "escapi.pbi"
UseJPEGImageDecoder()

device = 0
Width = 320
Height = 240

dest = AllocateMemory(Width*Height)
destLen = MemorySize(dest)
count = setupESCAPI()

name$ = Space(1000)
getCaptureDeviceName(device, @name$, 1000)

scp.SimpleCapParams
scp\mWidth = Width
scp\mHeight = Height
scp\mTargetBuf = AllocateMemory(scp\mWidth*scp\mHeight*4)

fx=(Width/2)
fy=(Height/2)

dist=240       ; ================== champs de vision
seuil=70       ; ================== seuil à partir duquel une différence de lumière entre l'ancienne image et la nouvelle est détectée à un pixel donné
maxverif=200   ; ================== nombre de pixels dont le mouvement est testé pour chaque image
noisekiller=16 ; ================== ce parametre elimine le bruit

image3=CreateImage(#PB_Any,Width,Height)
StartDrawing(ImageOutput(image3))
Box(0,0,320,240,RGB(0,0,0))
StopDrawing()

If initCapture(device, @scp)
  
  image = CreateImage(#PB_Any, Width, Height)
  image4 = CreateImage(#PB_Any, Width, Height)
  
  OpenWindow(0, 0, 0, Width, Height, name$, #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
  ImageGadget(0, 0, 0, Width, Height, ImageID(image))
  wxl_EncodePixelFormat(#PB_PixelFormat_32Bits_BGR)

  Repeat
    Event = WindowEvent()
    
    doCapture(device)
    While isCaptureDone(device) = 0
      Delay(1)
    Wend
        
    len = wxl_JPEGEncode(scp\mTargetBuf, Width, Height, 50, dest, destLen)
    
    CatchImage(image2, dest, len)
    
    oldfx=fx
    oldfy=fy
    
    ; on met l'image en miroir, pour s'identifier dans l'image
    
    StartDrawing(ImageOutput(image2))
    For y=0 To Height-1
      For x=0 To (Width/2)-1
        col1=Point(x,y)
        col2=Point(Width-x-1,y)
        Plot(x,y,col2)
        Plot(Width-x-1,y,col1)
      Next
    Next
    StopDrawing()
    
    difftot=0
    For i=1 To maxverif
      
    StartDrawing(ImageOutput(image3))
    x=fx+Random(dist)-(dist/2)
    y=fy+Random(dist)-(dist/2)
    If x>Width-1
      x=Width-1
    EndIf
    If x<0
      x=0
    EndIf
    If y>Height-1
      y=Height-1
    EndIf
    If y<0
      y=0
    EndIf
   
    col1=Point(x,y)
    
    StopDrawing()
    
    StartDrawing(ImageOutput(image2))
    col2=Point(x,y)
    
    moy1=(Red(col1)+Green(col1)+Blue(col1))/3
    moy2=(Red(col2)+Green(col2)+Blue(col2))/3   
    
    ; on va comparer ici un pixel pris au hasard dans le champs de vision avec le pixel qui était précédement là aux même coordonnées
    ; si la couleur change, c'est qu'il y a mouvement... ou du bruit dans la webcam. d'où le besoin de filtrer le bruit et de mettre un seuil
    ; sous lequel rien n'est detecté.
    
    diff=noisekiller*Int(Abs(moy2-moy1)/noisekiller)
    If diff>seuil
      If diff>difftot
        fx=x
        fy=y
      EndIf
    EndIf
    
    StopDrawing()

    Next
       
    FreeImage(image3)
    image3=CopyImage(image2,#PB_Any)
    
    fx=(oldfx+fx)/2 ; pour un mouvement plus fluide, je fais toujours la moyenne entre les anciennes coordonnées de la fenetre de vision et les nouvelles coordonnées
    fy=(oldfy+fy)/2
    
    
    ; je calcule ma fenetre...
    
  StartDrawing(ImageOutput(image4))
  Box(0,0,320,240,RGB(0,0,0))
  StopDrawing()
  x1=fx-80
  y1=fy-80
  wh=160
  If x1<0
    x1=0
  EndIf
  If y1<0
    y1=0
  EndIf
  If x1+wh>320
    wh=320-x1
  EndIf
  If y1+wh>240
    wh=240-y1
  EndIf
  image5=GrabImage(image2,#PB_Any,x1,y1,wh,wh)
  
  StartDrawing(ImageOutput(image4))
  DrawImage(ImageID(image5),x1,y1)
  StopDrawing()
  
  FreeImage(image5)
        
  SetGadgetState(0, ImageID(image4))

    
  Until Event = #PB_Event_CloseWindow
  
  deinitCapture(device)
Else
  Debug "init capture failed!"
EndIf
timeEndPeriod_(1)
End
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Détecteur de mouvements avec webcam

Message par Backup »

DjPoke a écrit :Bonjour à tous,

Je viens de programmer un détecteur de mouvements à partir d'une webcam et de la lib/dll trouvée ici même sur le forum (escapi)
un lien vers ce PBI aurai été plus pratique non ?
Avatar de l’utilisateur
Ulix
Messages : 315
Inscription : ven. 04/juin/2004 14:27
Localisation : Frontignan

Re: Détecteur de mouvements avec webcam

Message par Ulix »

Bonjour a tous !

J'ai trouver (merci Google) où la téléchargée, le lien :

http://sol.gfxile.net/escapi/index.html

Apparemment il y a un (ou des) exemples en PB.

A+ :wink:
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Détecteur de mouvements avec webcam

Message par Backup »

Merci Ulix :)

toutefois le
Pbi n'est pas dans l'archive

voici le fameux escapi.Pbi qui manque

Code : Tout sélectionner

;/* Extremely Simple Capture API */

Structure SimpleCapParams
  *mTargetBuf ; Must be at least mWidth * mHeight * SizeOf(int) of size!
  mWidth.l
  mHeight.l
EndStructure

;/* Return the number of capture devices found */
PrototypeC countCaptureDevicesProc()

; /* initCapture tries To open the video capture device.
;  * Returns 0 on failure, 1 on success.
;  * Note: Capture parameter values must Not change While capture device
;  *       is in use (i.e. between initCapture And deinitCapture).
;  *       Do *Not* free the target buffer, Or change its pointer!
;  */
PrototypeC initCaptureProc(deviceno, *aParams.SimpleCapParams)

;/* deinitCapture closes the video capture device. */
PrototypeC deinitCaptureProc(deviceno)

;/* doCapture requests video frame To be captured. */
PrototypeC doCaptureProc(deviceno)

;/* isCaptureDone returns 1 when the requested frame has been captured.*/
PrototypeC isCaptureDoneProc(deviceno)


;/* Get the user-friendly name of a capture device. */
PrototypeC getCaptureDeviceNameProc(deviceno, *namebuffer, bufferlength)


;/* Returns the ESCAPI DLL version. 0x200 For 2.0 */
PrototypeC ESCAPIDLLVersionProc()

; marked as "internal" in the example
PrototypeC initCOMProc()

Global countCaptureDevices.countCaptureDevicesProc
Global initCapture.initCaptureProc
Global deinitCapture.deinitCaptureProc
Global doCapture.doCaptureProc
Global isCaptureDone.isCaptureDoneProc
Global getCaptureDeviceName.getCaptureDeviceNameProc
Global ESCAPIDLLVersion.ESCAPIDLLVersionProc


Procedure setupESCAPI()
  
  ; load library
  capdll = OpenLibrary(#PB_Any, "escapi.dll")
  If capdll = 0
    ProcedureReturn 0
  EndIf
  
  ;/* Fetch function entry points */
  countCaptureDevices  = GetFunction(capdll, "countCaptureDevices")
  initCapture          = GetFunction(capdll, "initCapture")
  deinitCapture        = GetFunction(capdll, "deinitCapture")
  doCapture            = GetFunction(capdll, "doCapture")
  isCaptureDone        = GetFunction(capdll, "isCaptureDone")
  initCOM.initCOMProc  = GetFunction(capdll, "initCOM")
  getCaptureDeviceName = GetFunction(capdll, "getCaptureDeviceName")
  ESCAPIDLLVersion     = GetFunction(capdll, "ESCAPIDLLVersion")
  
  If countCaptureDevices = 0 Or initCapture = 0 Or deinitCapture = 0 Or doCapture = 0 Or isCaptureDone = 0 Or initCOM = 0 Or getCaptureDeviceName = 0 Or ESCAPIDLLVersion = 0
    ProcedureReturn 0
  EndIf
  
  ;/* Verify DLL version */
  If ESCAPIDLLVersion() < $200
    ProcedureReturn 0
  EndIf
  
  ;/* Initialize COM.. */
  initCOM(); 
  
  ; returns number of devices found
  ProcedureReturn countCaptureDevices()
EndProcedure

@DjPoke : maintenant pour que ton code fonctionne
il faut nous donner la lib qui manque !!

celle qui fait appel aux fonctions :

Code : Tout sélectionner

wxl_EncodePixelFormat(#PB_PixelFormat_32Bits_BGR) 

ps: lorsque tu partage un code , verifie que l'on puisse l'utiliser ...
oublier une lib ça arrive, mais en plus ne pas donner de liens, pour recuperer les dll
et autre fichier , ça deviens un casse tete... :roll:

enfin.. Merci quand meme
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Re: Détecteur de mouvements avec webcam

Message par GeBonet »

Bonjour et bonne fêtes,

Le lien vers ce site permet de charger un ensemble avec un code PB entre autres et il y a là ".dll"
http://sol.gfxile.net/escapi/index.html
Avec un original PB fait par "'Freak'" qui se trouve a :
http://www.purebasic.fr/english/viewtopic.php?t=25412
Voilà, voilà... :)

Note : @Dobro : Il n'y a pas de PBI c'est un include de ".pb"
Windows 7 et Windows 8.1 Pb 5.0 jusque 5.24 Lts 64 et 5.3 (64)/b]
“Ceux qui rêvent éveillés ont conscience de mille choses qui échappent à ceux qui ne rêvent qu’endormis.”
-Edgar Allan Poe-
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Détecteur de mouvements avec webcam

Message par Backup »

GeBonet a écrit :
Note : @Dobro : Il n'y a pas de PBI c'est un include de ".pb"
ben oui PBI ça veux dire PureBasic Include ...
et le code que j'ai posté viens du forum anglais , et est a sauvé sous le nom
"escapi.pbi" ....

de plus tu redonne les liens qu'on viens de mettre ;)



le teste de base avec escapi.pbi c'est :

Code : Tout sélectionner

XIncludeFile "escapi.pb"

device = 0

count = setupESCAPI()
Debug "init: " + Str(count)

If count = 0
  End
EndIf

name$ = Space(1000)
getCaptureDeviceName(device, @name$, 1000)
Debug "name: " + name$

scp.SimpleCapParams
scp\mWidth = 320
scp\mHeight = 240
scp\mTargetBuf = AllocateMemory (scp\mWidth * scp\mHeight * 4)

If initCapture(device, @scp)
  Debug "cap init successful" 
  
  image = CreateImage(#PB_Any, 320, 240)
  
  OpenWindow(0, 0, 0, 320, 240, name$, #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  CreateGadgetList(WindowID(0))
  ImageGadget(0, 0, 0, 320, 240, ImageID(image))
  
  Quit = 0
  Repeat
    
    doCapture(device)
    While isCaptureDone(device) = 0
      If WaitWindowEvent(1) = #PB_Event_CloseWindow
        Quit = 1
        Break
      EndIf       
    Wend
    
    If StartDrawing(ImageOutput(image))   
        For Y = 0 To scp\mHeight - 1
          For X = 0 To scp\mWidth - 1
            pixel = PeekL(scp\mTargetBuf + (Y*scp\mWidth + X) * 4)
            rgb   = RGB((pixel >> 16) & $FF, (pixel >> 8) & $FF, pixel & $FF)
            Plot(X, Y, rgb)
          Next
        Next
        
      StopDrawing()
      SetGadgetState(0, ImageID(image))
    EndIf
    
    
  Until quit
  
  deinitCapture(device)
Else
  Debug "init capture failed!"
EndIf

End
ps: ce code fonctionne tres bien ...
il ne fait pas appel a une lib non disponible ;)
Avatar de l’utilisateur
GeBonet
Messages : 453
Inscription : ven. 29/févr./2008 16:17
Localisation : Belgique

Re: Détecteur de mouvements avec webcam

Message par GeBonet »

Dobro a écrit : de plus tu redonne les liens qu'on viens de mettre ;)
Oui....... Mais au moment ou je post... Il n'y était pas...
Sorry, excuse moi, humm, quoi encore... Ah, oui, svp. :wink:
Dobro a écrit :ps: ce code fonctionne tres bien ...
il ne fait pas appel a une lib non disponible ;)
Effectivement, fonctionne bien sans autre chose... :wink:
Je sais aussi que "pbi" est pour les includes... Tout comme je sais que toi aussi tu sais :wink:
Mais là, l'appel se faisait sur un "escapi.pb" comme tu l'as bien remarqué...
D'où ma remarque pour une chose inhabituelle !
Mais, bon... Une autre fois j'attendrais jusque l'année prochaine pour être certain que quelqu'un d'autre n'ai pas répondu ! :oops:
La dessus à l'année prochaine et Image malgré tout !
Windows 7 et Windows 8.1 Pb 5.0 jusque 5.24 Lts 64 et 5.3 (64)/b]
“Ceux qui rêvent éveillés ont conscience de mille choses qui échappent à ceux qui ne rêvent qu’endormis.”
-Edgar Allan Poe-
Avatar de l’utilisateur
DjPoke
Messages : 121
Inscription : mar. 02/nov./2010 13:53
Localisation : Corte, Corse, France
Contact :

Re: Détecteur de mouvements avec webcam

Message par DjPoke »

Joyeux Noel.
Désolé de ne pas vous avoir fourni le pbi et la dll. Je croyais l'avoir trouvé ici, mais peut-être l'ai je trouvée sur le forum anglais de PB.
Répondre