-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The initial version has been implemented.
- Loading branch information
1 parent
ba11c0c
commit e7ffeec
Showing
31 changed files
with
114,390 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
|
||
__pycache__/facebox.cpython-38.pyc | ||
__pycache__/facesdk.cpython-38.pyc | ||
*.bin | ||
lib/facesdk1.dll |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from ctypes import * | ||
|
||
class FaceBox(Structure): | ||
_fields_ = [("x1", c_int32), ("y1", c_int32), ("x2", c_int32), ("y2", c_int32), | ||
("liveness", c_float), | ||
("yaw", c_float), ("roll", c_float), ("pitch", c_float), | ||
("face_quality", c_float), ("face_luminance", c_float), ("eye_dist", c_float), | ||
("left_eye_closed", c_float), ("right_eye_closed", c_float), | ||
("face_occlusion", c_float), ("mouth_opened", c_float), | ||
("landmark_68", c_float * 136) | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import os | ||
|
||
from ctypes import * | ||
from numpy.ctypeslib import ndpointer | ||
from facebox import FaceBox | ||
|
||
libPath = os.path.abspath(os.path.dirname(__file__)) + '/lib/facesdk1.dll' | ||
facesdk = cdll.LoadLibrary(libPath) | ||
|
||
getMachineCode = facesdk.getMachineCode | ||
getMachineCode.argtypes = [] | ||
getMachineCode.restype = c_char_p | ||
|
||
setActivation = facesdk.setActivation | ||
setActivation.argtypes = [c_char_p] | ||
setActivation.restype = c_int32 | ||
|
||
initSDK = facesdk.initSDK | ||
initSDK.argtypes = [c_char_p] | ||
initSDK.restype = c_int32 | ||
|
||
faceDetection = facesdk.faceDetection | ||
faceDetection.argtypes = [ndpointer(c_ubyte, flags='C_CONTIGUOUS'), c_int32, c_int32, POINTER(FaceBox), c_int32] | ||
faceDetection.restype = c_int32 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#pragma once | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
enum SDK_ERROR | ||
{ | ||
SDK_SUCCESS = 0, | ||
SDK_LICENSE_KEY_ERROR = -1, | ||
SDK_LICENSE_APPID_ERROR = -2, | ||
SDK_LICENSE_EXPIRED = -3, | ||
SDK_NO_ACTIVATED = -4, | ||
SDK_INIT_ERROR = -5, | ||
}; | ||
|
||
typedef struct _tagFaceBox | ||
{ | ||
int x1, y1, x2, y2; | ||
float liveness; | ||
float yaw, roll, pitch; | ||
float face_quality, face_luminance, eye_dist; | ||
float left_eye_closed, right_eye_closed, face_occlusion, mouth_opened; | ||
float landmark_68[68 * 2]; | ||
} FaceBox; | ||
|
||
/* | ||
* Get the machine code for SDK activation | ||
*/ | ||
const char* getMachineCode(); | ||
|
||
/* | ||
* Activate the SDK using the provided license | ||
*/ | ||
|
||
int setActivation(char* license); | ||
|
||
/* | ||
* Initialize the SDK with the specified model path | ||
*/ | ||
int initSDK(char* modelPath); | ||
|
||
/* | ||
* Detect faces, perform liveness detection, determine face orientation (yaw, roll, pitch), | ||
* assess face quality, detect facial occlusion, eye closure, mouth opening, and identify facial landmarks. | ||
*/ | ||
int faceDetection(unsigned char* rgbData, int width, int height, FaceBox* faceBoxes, int faceBoxCount); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<ie> | ||
<plugins> | ||
<plugin name="AUTO" location="openvino_auto_plugin.dll"> | ||
</plugin> | ||
<plugin name="BATCH" location="openvino_auto_batch_plugin.dll"> | ||
</plugin> | ||
<plugin name="CPU" location="openvino_intel_cpu_plugin.dll"> | ||
</plugin> | ||
<plugin name="GNA" location="openvino_intel_gna_plugin.dll"> | ||
</plugin> | ||
<plugin name="GPU" location="openvino_intel_gpu_plugin.dll"> | ||
</plugin> | ||
<plugin name="HETERO" location="openvino_hetero_plugin.dll"> | ||
</plugin> | ||
<plugin name="MULTI" location="openvino_auto_plugin.dll"> | ||
</plugin> | ||
<plugin name="MYRIAD" location="openvino_intel_myriad_plugin.dll"> | ||
</plugin> | ||
<plugin name="HDDL" location="openvino_intel_hddl_plugin.dll"> | ||
</plugin> | ||
<plugin name="VPUX" location="openvino_intel_vpux_plugin.dll"> | ||
</plugin> | ||
</plugins> | ||
</ie> |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
To obtain the license, please get in touch with us using the following contact information: | ||
|
||
Email: contact@kby-ai.com | ||
Telegram: @kbyai | ||
WhatsApp: +19092802609 | ||
Skype: live:.cid.66e2522354b1049b |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Pillow | ||
numpy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import sys | ||
sys.path.append('.') | ||
|
||
from PIL import Image | ||
import numpy as np | ||
|
||
from facesdk import getMachineCode | ||
from facesdk import setActivation | ||
from facesdk import faceDetection | ||
from facesdk import initSDK | ||
from facebox import FaceBox | ||
|
||
livenessThreshold = 0.7 | ||
yawThreshold = 10 | ||
pitchThreshold = 10 | ||
rollThreshold = 10 | ||
occlusionThreshold = 0.9 | ||
eyeClosureThreshold = 0.8 | ||
mouthOpeningThreshold = 0.5 | ||
borderRate = 0.05 | ||
smallFaceThreshold = 100 | ||
lowQualityThreshold = 0.3 | ||
hightQualityThreshold = 0.7 | ||
luminanceDarkThreshold = 50 | ||
luminanceLightThreshold = 200 | ||
|
||
maxFaceCount = 10 | ||
|
||
licensePath = "license.txt" | ||
license = "" | ||
|
||
machineCode = getMachineCode() | ||
print("machineCode: ", machineCode.decode('utf-8')) | ||
|
||
try: | ||
with open(licensePath, 'r') as file: | ||
license = file.read() | ||
except IOError as exc: | ||
print("failed to open license.txt: ", exc.errno) | ||
print("license: ", license) | ||
|
||
|
||
ret = setActivation(license.encode('utf-8')) | ||
print("activation: ", ret) | ||
|
||
ret = initSDK("D:/Temp/kby_face/github/FaceLivenessDetection-Windows/data".encode('utf-8')) | ||
print("init: ", ret) | ||
|
||
def process_file(filePath): | ||
image = Image.open(filePath) | ||
image_np = np.asarray(image) | ||
|
||
faceBoxes = (FaceBox * maxFaceCount)() | ||
faceCount = faceDetection(image_np, image_np.shape[1], image_np.shape[0], faceBoxes, maxFaceCount) | ||
|
||
faces = [] | ||
for i in range(faceCount): | ||
# landmark_68 = [] | ||
# for j in range(68): | ||
# landmark_68.append({"x": faceBoxes[i].landmark_68[j * 2], "y": faceBoxes[i].landmark_68[j * 2 + 1]}) | ||
faces.append({"x1": faceBoxes[i].x1, "y1": faceBoxes[i].y1, "x2": faceBoxes[i].x2, "y2": faceBoxes[i].y2, | ||
"liveness": faceBoxes[i].liveness, | ||
"yaw": faceBoxes[i].yaw, "roll": faceBoxes[i].roll, "pitch": faceBoxes[i].pitch, | ||
"face_quality": faceBoxes[i].face_quality, "face_luminance": faceBoxes[i].face_luminance, "eye_dist": faceBoxes[i].eye_dist, | ||
"left_eye_closed": faceBoxes[i].left_eye_closed, "right_eye_closed": faceBoxes[i].right_eye_closed, | ||
"face_occlusion": faceBoxes[i].face_occlusion, "mouth_opened": faceBoxes[i].mouth_opened}) | ||
# "landmark_68": landmark_68}) | ||
|
||
result = "" | ||
if faceCount == 0: | ||
result = "No face" | ||
elif faceCount > 1: | ||
result = "Multiple face" | ||
else: | ||
livenessScore = faceBoxes[0].liveness | ||
if livenessScore > livenessThreshold: | ||
result = "Real" | ||
else: | ||
result = "Spoof" | ||
|
||
isNotFront = True | ||
isOcclusion = False | ||
isEyeClosure = False | ||
isMouthOpening = False | ||
isBoundary = False | ||
isSmall = False | ||
quality = "Low" | ||
luminance = "Dark" | ||
if abs(faceBoxes[0].yaw) < yawThreshold and abs(faceBoxes[0].roll) < rollThreshold and abs(faceBoxes[0].pitch) < pitchThreshold: | ||
isNotFront = False | ||
|
||
if faceBoxes[0].face_occlusion > occlusionThreshold: | ||
isOcclusion = True | ||
|
||
if faceBoxes[0].left_eye_closed > eyeClosureThreshold or faceBoxes[0].right_eye_closed > eyeClosureThreshold: | ||
isEyeClosure = True | ||
|
||
if faceBoxes[0].mouth_opened > mouthOpeningThreshold: | ||
isMouthOpening = True | ||
|
||
if (faceBoxes[0].x1 < image_np.shape[1] * borderRate or | ||
faceBoxes[0].y1 < image_np.shape[0] * borderRate or | ||
faceBoxes[0].x1 > image_np.shape[1] - image_np.shape[1] * borderRate or | ||
faceBoxes[0].x1 > image_np.shape[0] - image_np.shape[0] * borderRate): | ||
isBoundary = True | ||
|
||
if faceBoxes[0].eye_dist < smallFaceThreshold: | ||
isSmall = True | ||
|
||
if faceBoxes[0].face_quality < lowQualityThreshold: | ||
quality = "Low" | ||
elif faceBoxes[0].face_quality < hightQualityThreshold: | ||
quality = "Medium" | ||
else: | ||
quality = "High" | ||
|
||
if faceBoxes[0].face_luminance < luminanceDarkThreshold: | ||
luminance = "Dark" | ||
elif faceBoxes[0].face_luminance < luminanceLightThreshold: | ||
luminance = "Normal" | ||
else: | ||
luminance = "Light" | ||
|
||
faceState = {"result": result, "liveness_score": livenessScore, "is_not_front": isNotFront, "is_occluded": isOcclusion, "eye_closed": isEyeClosure, | ||
"mouth_opened": isMouthOpening, "is_boundary_face": isBoundary, "is_small": isSmall, "quality": quality, "luminance": luminance} | ||
result = {"face_state": faceState, "faces": faces} | ||
|
||
return result | ||
|
||
if __name__ == "__main__": | ||
ret = process_file('D:/Temp/kby_face/github/FaceLivenessDetection-Windows/live_examples/1.jpg') | ||
print(ret) |