Тема: 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
}