1 (изменено: Malcev, 2023-03-10 16:22:19)

Тема: AHK: libfacedetection - библиотека для определения лица

https://autoit.de/thread/86499-facedetection-udf/
На автохотки запускать так:

Global libfacedetect_path := A_ScriptDir "\libfacedetect-x" 8*A_PtrSize ".dll"
image_path := "G:\B0001824-Edit.jpg"
libfacedetect(image_path, result)
iFaces := NumGet(result, 0, "int")
msgbox % "Number of faces detected: " iFaces
loop % ifaces
{
   x := NumGet(result, 4 + 284*(A_Index - 1), "short")
   y := NumGet(result, 6 + 284*(A_Index - 1), "short")
   width := NumGet(result, 8 + 284*(A_Index - 1), "short")
   height := NumGet(result, 10 + 284*(A_Index - 1), "short")
   confidence := NumGet(result, 12 + 284*(A_Index - 1), "short")
   angle := NumGet(result, 14 + 284*(A_Index - 1), "short")
   msgbox % "x: " x "`ny: " y "`nwidth: " width "`nheight: " height "`nconfidence: " confidence "`nangle: " angle
}
msgbox done
return


libfacedetect(image_path, byref tResult, iMode := 4, fScale := 1.2, iMin_Neighbors := 1, iMin_Object_Width := 20, iMax_Object_Width := 0, bDoLandmark := 1)
{
   ; ###############################################################################################################################
   ; # iMode = 1:
   ; #    frontal face detection / 68 landmark detection
   ; #    it's fast, but cannot detect side view faces
   ; #
   ; # iMode = 2:
   ; #    frontal face detection designed for video surveillance / 68 landmark detection
   ; #    it can detect faces with bad illumination.
   ; #
   ; # iMode = 3:
   ; #    multiview face detection / 68 landmark detection
   ; #    it can detect side view faces, but slower than facedetect_frontal.
   ; #
   ; # iMode = 4:
   ; #    reinforced multiview face detection / 68 landmark detection
   ; #    it can detect side view faces, better but slower than facedetect_multiview.
   ; #
   ; # fScale:              scale factor for scan windows
   ; # iMin_Neighbors:      how many neighbors each candidate rectangle should have to retain it
   ; # iMin_Object_Width:   Minimum possible face size. Faces smaller than that are ignored.
   ; # iMax_Object_Width:   Maximum possible face size. Faces larger than that are ignored. It is the largest posible when max_object_width=0.
   ; # bDoLandmark:         landmark detection
   ; ###############################################################################################################################

   static _sFDDLL1, _sFDDLL2, _sFDDLL3, _sFDDLL4, _pFD_ASM_8BitGray, pToken
   if !_sFDDLL1
   {
      DllCall("LoadLibrary", "str", libfacedetect_path, "ptr")
      if (A_PtrSize = 8)
      {
         hex := "5657534889CF4889D6450FAFC141B9555500008B1688D0660FB6DEC1EA086601D8660FB6DE6601D841F7E1C1E81088074883C6044883C7014183E80177D55B5F5EC3"
         _sFDDLL1 := "?facedetect_frontal@@YAPEAHPEAE0HHHMHHHH@Z"
         _sFDDLL2 := "?facedetect_frontal_surveillance@@YAPEAHPEAE0HHHMHHHH@Z"
         _sFDDLL3 := "?facedetect_multiview@@YAPEAHPEAE0HHHMHHHH@Z"
         _sFDDLL4 := "?facedetect_multiview_reinforce@@YAPEAHPEAE0HHHMHHHH@Z"
      }
      else
      {
         hex := "555657538B7C24148B7424188B4C241C0FAF4C2420BD555500008B1688D0660FB6DEC1EA086601D8660FB6DE6601D8F7E5C1E810880783C60483C70183E90177D95B5F5E5DC21000"
         _sFDDLL1 := "?facedetect_frontal@@YAPAHPAE0HHHMHHHH@Z"
         _sFDDLL2 := "?facedetect_frontal_surveillance@@YAPAHPAE0HHHMHHHH@Z"
         _sFDDLL3 := "?facedetect_multiview@@YAPAHPAE0HHHMHHHH@Z"
         _sFDDLL4 := "?facedetect_multiview_reinforce@@YAPAHPAE0HHHMHHHH@Z"
      }
      _pFD_ASM_8BitGray := DllCall("kernel32.dll\VirtualAlloc", "ptr", 0, "ptr", 88-(A_PtrSize*3-12)/2, "uint", MEM_COMMIT := 0x1000, "uint", PAGE_EXECUTE_READWRITE := 0x40, "ptr")
      _pFD_ASM_8BitGray := _pFD_ASM_8BitGray + 16 - Mod(_pFD_ASM_8BitGray, 16)
      loop, parse, hex
      {
         if ((A_Index & 1) != 0)
            num := "0x" A_LoopField
         else
            NumPut(num A_LoopField, _pFD_ASM_8BitGray+0, A_Index/2-1, "char")
      }

      DllCall("LoadLibrary", "str", "gdiplus")
      VarSetCapacity(si, 8+2*A_PtrSize, 0)
      NumPut(0x1, si, "uint")
      DllCall("gdiplus\GdiplusStartup", "ptr*", pToken, "ptr", &si, "ptr", 0)
   }

   ; Get scan0 of bitmap
   DllCall("gdiplus\GdipCreateBitmapFromFile", "wstr", image_path, "ptr*", needlePbitmap)
   DllCall("gdiplus\GdipGetImageWidth", "ptr", needlePbitmap, "uint*", needleWidth)
   DllCall("gdiplus\GdipGetImageHeight", "ptr", needlePbitmap, "uint*", needleHeight)
   VarSetCapacity(needleRect, 16, 0)
   NumPut(needleWidth, needleRect, 8, "uint")
   NumPut(needleHeight, needleRect, 12, "uint")
   VarSetCapacity(needleBitmapData, 16+2*A_PtrSize, 0)
   DllCall("gdiplus\GdipBitmapLockBits", "ptr", needlePbitmap, "ptr", &needleRect, "uint", ReadWrite := 3, "int", Format32bppRgb := 139273, "ptr", &needleBitmapData)
   needleStride := NumGet(needleBitmapData, 8, "int")
   needleScan := NumGet(needleBitmapData, 16, "ptr")

   ; convert scan0 to gray (single-channel)
   VarSetCapacity(_tFD_BmpG, needleWidth*needleHeight, 0)
   DllCall(_pFD_ASM_8BitGray, "ptr", &_tFD_BmpG, "ptr", needleScan, "int", needleWidth, "int", needleHeight)

   ; find faces
   VarSetCapacity(tResult, 0x20000, 0)
   DllCall(libfacedetect_path "\" _sFDDLL%iMode%, "ptr", &tResult, "ptr", &_tFD_BmpG, "int", needleWidth, "int", needleHeight, "int", needleWidth, "float", fScale, "int", iMin_Neighbors, "int", iMin_Object_Width, "int", iMax_Object_Width, "int", bDoLandmark, "cdecl")

   ; clear resources
   DllCall("gdiplus\GdipBitmapUnlockBits", "ptr", needlePbitmap, "ptr", &needleBitmapData)
   DllCall("gdiplus\GdipDisposeImage", "ptr", needlePbitmap)
   return
}

Тема для обсуждения