Face Detection (fdlib)

    • Offizieller Beitrag

    Moin,

    Ich bin grad dabei ein Projekt zu machen, wo ich gucken will, wie viele Leute an einem PC waren.
    Dies will ich mit einer Gesichtserkennungssoftware (schönes Wort :D) und einer WebCam relalisieren. Hab mir dann auch direkt was rausgesucht, von OpenCV:
    http://www.kyb.mpg.de/bs/people/kienzle/fdlib/fdlib.htm

    Gut, die Frage ist jetzt nur, wie in AutoIt einbinden?
    Ich hätte es so ca gedacht, dies Funktioniert aber leider nicht :(

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <WinAPI.au3>
    #include <Array.au3>
    $hOpen = DllOpen("fdlib.dll")
    _GDIPlus_Startup()
    $hbBMP = _GDIPlus_BitmapCreateFromFile(@ScriptDir&"\geeks.jpg")
    $iWidth = _GDIPlus_ImageGetWidth($hbBMP)
    $iHeight = _GDIPlus_ImageGetHeight($hbBMP)
    $hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hbBMP)
    $iThreshold = 1
    $vBMP = _GDIPlus_BitmapToStructByte($hBMP,$iWidth,$iHeight)

    [/autoit] [autoit][/autoit] [autoit]

    ;fdlib_detectfaces(byte *imagedata, int imagewidth, int imageheight, int threshold);
    $aFace = DllCall($hOpen,"int","fdlib_detectfaces","ptr",DllStructGetPtr($vBMP),"int",$iWidth,"int",$iHeight,"int",$iThreshold)
    ;~ $aFace = DllCall($hOpen,"int","fdlib_detectfaces","byte",DllStructGetData($hbBMP,1),"int",$iWidth,"int",$iHeight,"int",$iThreshold)
    _ArrayDisplay($aFace)

    [/autoit] [autoit][/autoit] [autoit]

    DllClose($hOpen)

    [/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_BitmapToStructByte($hBMP,$iW,$iH)
    Local $x,$y,$z,$sErrorHandlerString,$hDC,$hDC_tmp,$hBitmap,$vStruct_Byte,$vStruct_BMPInfo

    [/autoit] [autoit][/autoit] [autoit]

    Local $hBitmap = DllCall("User32.dll", "hwnd", "CopyImage", "hwnd", $hBMP, "int", 0, "int", 160, "int", 43, "int", 1);LR_MONOCHROME
    If @error Then Return SetError(1,0,_WinAPI_GetLastErrorMessage())
    $hBitmap = $hBitmap[0]

    $vStruct_Byte = DllStructCreate("byte graydata["&$iW*$iH&"]")

    Local $vStruct_BMPInfo = DllStructCreate("dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword;dword RGBQuad[256];")
    $hDC_tmp = _WinAPI_GetDC(0)
    $hDC = _WinAPI_CreateCompatibleDC($hDC_tmp)
    _WinAPI_ReleaseDC(0, $hDC_tmp)
    Local $hBitmapOld = _WinAPI_SelectObject($hDC,$hBitmap)

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($vStruct_BMPInfo,1,DllStructGetSize(DllStructCreate("dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword;",1)))
    DllStructSetData($vStruct_BMPInfo,2,$iW)
    DllStructSetData($vStruct_BMPInfo,3,$iH*-1)
    DllStructSetData($vStruct_BMPInfo,4,1)
    DllStructSetData($vStruct_BMPInfo,5,1)

    _WinAPI_GetDIBits($hDC,$hBitmap,0,$iH,DllStructGetPtr($vStruct_Byte),DllStructGetPtr($vStruct_BMPInfo),0)

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_DeleteDC ($hDC)
    _WinAPI_DeleteObject(_WinAPI_SelectObject($hDC,$hBitmapOld))

    Return $vStruct_Byte
    EndFunc

    [/autoit]

    Hier ist ein Beispiel mit DLL in C++:
    http://www.kyb.mpg.de/bs/people/kien…lib_windows.zip

    Hier ein Beispiel Bild:
    http://demo.pittpatt.com/images/sample.jpg

    Wäre echt super, wenn hier jemand weiter wissen würde :)
    Vielen Dank schon mal.

    Mfg Spider

  • Theoretisch geht es so, aber ob die Ergebnisse stimmen?

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <WinAPI.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $hOpen = DllOpen("fdlib.dll")

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $hbBMP = _GDIPlus_BitmapCreateFromFile(@ScriptDir&"\geeks.jpg")
    $iWidth = _GDIPlus_ImageGetWidth($hbBMP)
    $iHeight = _GDIPlus_ImageGetHeight($hbBMP)
    $hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hbBMP)
    $iThreshold = Number(InputBox("Threshold","Threshold"))
    If $iThreshold<1 Then $iThreshold = 1
    $vBMP = _GDIPlus_BitmapToStructByte($hBMP,$iWidth,$iHeight)

    [/autoit] [autoit][/autoit] [autoit]

    ;fdlib_detectfaces(byte *imagedata, int imagewidth, int imageheight, int threshold);
    ;~ $aFace = DllCall($hOpen,"int:cdecl","fdlib_detectfaces","byte",DllStructGetData($hbBMP,1),"int",$iWidth,"int",$iHeight,"int",$iThreshold)

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($hOpen,"int:cdecl","fdlib_detectfaces","ptr",DllStructGetPtr($vBMP),"int",$iWidth,"int",$iHeight,"int",$iThreshold)

    [/autoit] [autoit][/autoit] [autoit]

    $nFace = DllCall($hOpen,"int:cdecl","fdlib_getndetections")
    If Not @error Then
    MsgBox(0,"",$nFace[0])
    $nFace = $nFace[0]

    [/autoit] [autoit][/autoit] [autoit]

    Else
    MsgBox(0,"",@error)
    Exit
    EndIf
    Dim $aFaces
    If $nFace>0 Then
    Dim $aFaces[$nFace][4]
    For $i= 0 To $nFace-1
    $nextFace = DllCall($hOpen,"int:cdecl","fdlib_getdetection" , "int", $i, "int*",0, "int*",0 , "int*",0)
    if Not @error Then
    $aFaces[$i][0] = $i
    $aFaces[$i][1] = $nextFace[2]
    $aFaces[$i][2] = $nextFace[3]
    $aFaces[$i][3] = $nextFace[4]
    EndIf
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    _ArrayDisplay($aFaces)

    [/autoit] [autoit][/autoit] [autoit]

    DllClose($hOpen)

    [/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_BitmapToStructByte($hBMP,$iW,$iH)
    Local $x,$y,$z,$sErrorHandlerString,$hDC,$hDC_tmp,$hBitmap,$vStruct_Byte,$vStruct_BMPInfo

    [/autoit] [autoit][/autoit] [autoit]

    Local $hBitmap = DllCall("User32.dll", "hwnd", "CopyImage", "hwnd", $hBMP, "int", 0, "int", 0, "int", 0, "int", 1);LR_MONOCHROME
    If @error Then Return SetError(1,0,_WinAPI_GetLastErrorMessage())
    $hBitmap = $hBitmap[0]

    $vStruct_Byte = DllStructCreate("byte graydata["&$iW*$iH&"]")

    Local $vStruct_BMPInfo = DllStructCreate("dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword;dword RGBQuad[256];")
    $hDC_tmp = _WinAPI_GetDC(_WinAPI_GetDesktopWindow())
    $hDC = _WinAPI_CreateCompatibleDC($hDC_tmp)
    _WinAPI_ReleaseDC(0, $hDC_tmp)
    Local $hBitmapOld = _WinAPI_SelectObject($hDC,$hBitmap)

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($vStruct_BMPInfo,1,DllStructGetSize(DllStructCreate("dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword;",1)))
    DllStructSetData($vStruct_BMPInfo,2,$iW)
    DllStructSetData($vStruct_BMPInfo,3,$iH*-1)
    DllStructSetData($vStruct_BMPInfo,4,1)
    DllStructSetData($vStruct_BMPInfo,5,1)

    _WinAPI_GetDIBits($hDC,$hBitmap,0,$iH,DllStructGetPtr($vStruct_Byte),DllStructGetPtr($vStruct_BMPInfo),0)

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_DeleteObject(_WinAPI_SelectObject($hDC,$hBitmapOld))
    _WinAPI_DeleteDC ($hDC)

    Return $vStruct_Byte
    EndFunc

    [/autoit]
    • Offizieller Beitrag

    Hallo

    ProgAndy, war ja klar :D Vielen Dank.
    Funktioniert immerhin mehr als meine Version ;)
    Leider zeigt er bei dem Angehängten Bild 10 statt 11 Gesichter. Auf der Homepage wurde aber das Bild als Beispiel genannt. Bei dem Sample was im ersten Post ist (jetzt als Graustufe im Anhang) funktioniert es garnicht (0 Gesichter)
    Die Positionen währen relativ egal, es geht mir halt nur um die Anzahl der Gesichter.

    Es ist aber wahr, eigentlich müsste alles so richtig sein ?(
    Kennt sonst vielleicht jemand noch eine andere Möglichkeit, Gesichtserkennung durchzuführen? (Vlt ne andere DLL?)

    Danke auf jedenfall schonmal für deine Mühe, ProgAndy :thumbup:

    Mfg Spider