Skip to content

Commit 7a87e82

Browse files
authored
Merge pull request #72 from HyperInspire/dev/eye_status
Dev/eye status Former-commit-id: 610f84b
2 parents 382bee6 + a20c37d commit 7a87e82

30 files changed

+632
-101
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
99
# Current version
1010
set(INSPIRE_FACE_VERSION_MAJOR 1)
1111
set(INSPIRE_FACE_VERSION_MINOR 1)
12-
set(INSPIRE_FACE_VERSION_PATCH 2)
12+
set(INSPIRE_FACE_VERSION_PATCH 3)
1313

1414
# Converts the version number to a string
1515
string(CONCAT INSPIRE_FACE_VERSION_MAJOR_STR ${INSPIRE_FACE_VERSION_MAJOR})

cpp/inspireface/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ set(SOURCE_FILES ${SOURCE_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/middleware/model_ar
5555
link_directories(${MNN_LIBS})
5656

5757
if(ISF_BUILD_SHARED_LIBS)
58+
add_definitions("-DISF_BUILD_SHARED_LIBS")
5859
add_library(InspireFace SHARED ${SOURCE_FILES})
5960
else()
6061
add_library(InspireFace STATIC ${SOURCE_FILES})

cpp/inspireface/c_api/inspireface.cc

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,33 @@ HResult HFGetFaceBasicTokenSize(HPInt32 bufferSize) {
281281
return HSUCCEED;
282282
}
283283

284+
HResult HFGetNumOfFaceDenseLandmark(HPInt32 num) {
285+
*num = 106;
286+
return HSUCCEED;
287+
}
288+
289+
HResult HFGetFaceDenseLandmarkFromFaceToken(HFFaceBasicToken singleFace, HPoint2f* landmarks, HInt32 num) {
290+
if (num != 106) {
291+
return HERR_SESS_LANDMARK_NUM_NOT_MATCH;
292+
}
293+
inspire::FaceBasicData data;
294+
data.dataSize = singleFace.size;
295+
data.data = singleFace.data;
296+
HyperFaceData face = {0};
297+
HInt32 ret;
298+
ret = DeserializeHyperFaceData((char* )data.data, data.dataSize, face);
299+
if (ret != HSUCCEED) {
300+
return ret;
301+
}
302+
for (size_t i = 0; i < num; i++)
303+
{
304+
landmarks[i].x = face.densityLandmark[i].x;
305+
landmarks[i].y = face.densityLandmark[i].y;
306+
}
307+
308+
return HSUCCEED;
309+
}
310+
284311
HResult HFFeatureHubFaceSearchThresholdSetting(float threshold) {
285312
FEATURE_HUB->SetRecognitionThreshold(threshold);
286313
return HSUCCEED;
@@ -549,7 +576,7 @@ HResult HFMultipleFacePipelineProcessOptional(HFSession session, HFImageStream s
549576
}
550577
if (customOption & HF_ENABLE_INTERACTION) {
551578
param.enable_interaction_liveness = true;
552-
}
579+
}
553580

554581

555582
HResult ret;
@@ -633,6 +660,21 @@ HResult HFFaceQualityDetect(HFSession session, HFFaceBasicToken singleFace, HFlo
633660

634661
}
635662

663+
HResult HFGetFaceIntereactionResult(HFSession session, PHFFaceIntereactionResult result) {
664+
if (session == nullptr) {
665+
return HERR_INVALID_CONTEXT_HANDLE;
666+
}
667+
HF_FaceAlgorithmSession *ctx = (HF_FaceAlgorithmSession* ) session;
668+
if (ctx == nullptr) {
669+
return HERR_INVALID_CONTEXT_HANDLE;
670+
}
671+
result->num = ctx->impl.GetFaceInteractionLeftEyeStatusCache().size();
672+
result->leftEyeStatusConfidence = (HFloat* )ctx->impl.GetFaceInteractionLeftEyeStatusCache().data();
673+
result->rightEyeStatusConfidence = (HFloat* )ctx->impl.GetFaceInteractionRightEyeStatusCache().data();
674+
675+
return HSUCCEED;
676+
}
677+
636678
HResult HFFeatureHubGetFaceCount(HInt32* count) {
637679
*count = FEATURE_HUB->GetFaceFeatureCount();
638680
return HSUCCEED;

cpp/inspireface/c_api/inspireface.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include "herror.h"
1111

1212
#if defined(_WIN32)
13-
#ifdef HYPER_BUILD_SHARED_LIB
13+
#ifdef ISF_BUILD_SHARED_LIBS
1414
#define HYPER_CAPI_EXPORT __declspec(dllexport)
1515
#else
1616
#define HYPER_CAPI_EXPORT
@@ -298,6 +298,23 @@ HYPER_CAPI_EXPORT extern HResult HFCopyFaceBasicToken(HFFaceBasicToken token, HP
298298
*/
299299
HYPER_CAPI_EXPORT extern HResult HFGetFaceBasicTokenSize(HPInt32 bufferSize);
300300

301+
/**
302+
* @brief Retrieve the number of dense facial landmarks.
303+
* @param num Number of dense facial landmarks
304+
* @return HResult indicating the success or failure of the operation.
305+
*/
306+
HYPER_CAPI_EXPORT extern HResult HFGetNumOfFaceDenseLandmark(HPInt32 num);
307+
308+
/**
309+
* @brief When you pass in a valid facial token, you can retrieve a set of dense facial landmarks.
310+
* The memory for the dense landmarks must be allocated by you.
311+
* @param singleFace Basic token representing a single face.
312+
* @param landmarks Pre-allocated memory address of the array for 2D floating-point coordinates.
313+
* @param num Number of landmark points
314+
* @return HResult indicating the success or failure of the operation.
315+
*/
316+
HYPER_CAPI_EXPORT extern HResult HFGetFaceDenseLandmarkFromFaceToken(HFFaceBasicToken singleFace, HPoint2f* landmarks, HInt32 num);
317+
301318
/************************************************************************
302319
* Face Recognition
303320
************************************************************************/
@@ -618,6 +635,18 @@ HYPER_CAPI_EXPORT extern HResult HFGetFaceQualityConfidence(HFSession session, P
618635
*/
619636
HYPER_CAPI_EXPORT extern HResult HFFaceQualityDetect(HFSession session, HFFaceBasicToken singleFace, HFloat *confidence);
620637

638+
639+
/**
640+
* @brief Some facial states in the face interaction module.
641+
*/
642+
typedef struct HFFaceIntereactionResult {
643+
HInt32 num; ///< Number of faces detected.
644+
HPFloat leftEyeStatusConfidence; ///< Left eye state: confidence close to 1 means open, close to 0 means closed.
645+
HPFloat rightEyeStatusConfidence; ///< Right eye state: confidence close to 1 means open, close to 0 means closed.
646+
} HFFaceIntereactionResult, *PHFFaceIntereactionResult;
647+
648+
HYPER_CAPI_EXPORT extern HResult HFGetFaceIntereactionResult(HFSession session, PHFFaceIntereactionResult result);
649+
621650
/************************************************************************
622651
* System Function
623652
************************************************************************/

cpp/inspireface/c_api/intypedef.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,9 @@ typedef struct HFaceRect {
3131
HInt32 height; ///< Height of the rectangle.
3232
} HFaceRect; ///< Rectangle representing a face region.
3333

34+
typedef struct HPoint2f{
35+
HFloat x; ///< X-coordinate
36+
HFloat y; ///< Y-coordinate
37+
} HPoint2f;
3438

3539
#endif //HYPERFACEREPO_INTYPEDEF_H

cpp/inspireface/common/face_data/data_tools.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,15 @@ inline HyperFaceData INSPIRE_API FaceObjectToHyperFaceData(const FaceObject& obj
9696
data.face3DAngle.pitch = obj.high_result.pitch;
9797
data.face3DAngle.roll = obj.high_result.roll;
9898
data.face3DAngle.yaw = obj.high_result.yaw;
99+
100+
101+
const auto &lmk = obj.landmark_smooth_aux_.back();
102+
for (size_t i = 0; i < lmk.size(); i++)
103+
{
104+
data.densityLandmark[i].x = lmk[i].x;
105+
data.densityLandmark[i].y = lmk[i].y;
106+
}
107+
99108

100109
return data;
101110
}

cpp/inspireface/common/face_data/face_data_type.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,16 @@ typedef struct TransMatrix {
5757
* Struct to represent hyper face data.
5858
*/
5959
typedef struct HyperFaceData {
60-
int trackState; ///< Track state
61-
int inGroupIndex; ///< Index within a group
62-
int trackId; ///< Track ID
63-
int trackCount; ///< Track count
64-
FaceRect rect; ///< Face rectangle
65-
TransMatrix trans; ///< Transformation matrix
66-
Point2F keyPoints[5]; ///< Key points (e.g., landmarks)
67-
Face3DAngle face3DAngle; ///< 3D face angles
68-
float quality[5]; ///< Quality values for key points
60+
int trackState; ///< Track state
61+
int inGroupIndex; ///< Index within a group
62+
int trackId; ///< Track ID
63+
int trackCount; ///< Track count
64+
FaceRect rect; ///< Face rectangle
65+
TransMatrix trans; ///< Transformation matrix
66+
Point2F keyPoints[5]; ///< Key points (e.g., landmarks)
67+
Face3DAngle face3DAngle; ///< 3D face angles
68+
float quality[5]; ///< Quality values for key points
69+
Point2F densityLandmark[106]; ///< Face density landmark
6970
} HyperFaceData;
7071

7172
} // namespace inspire

cpp/inspireface/common/face_info/face_object.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,10 @@ class INSPIRE_API FaceObject {
312312
face_id_ = id;
313313
}
314314

315+
std::vector<float> left_eye_status_;
316+
317+
std::vector<float> right_eye_status_;
318+
315319
private:
316320
TRACK_STATE tracking_state_;
317321
// std::shared_ptr<FaceAction> face_action_;

cpp/inspireface/face_context.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ int32_t FaceContext::FaceDetectAndTrack(CameraStream &image) {
6262
m_yaw_results_cache_.clear();
6363
m_pitch_results_cache_.clear();
6464
m_quality_score_results_cache_.clear();
65+
m_react_left_eye_results_cache_.clear();
66+
m_react_right_eye_results_cache_.clear();
6567
if (m_face_track_ == nullptr) {
6668
return HERR_SESS_TRACKER_FAILURE;
6769
}
@@ -129,6 +131,8 @@ int32_t FaceContext::FacesProcess(CameraStream &image, const std::vector<HyperFa
129131
std::lock_guard<std::mutex> lock(m_mtx_);
130132
m_mask_results_cache_.resize(faces.size(), -1.0f);
131133
m_rgb_liveness_results_cache_.resize(faces.size(), -1.0f);
134+
m_react_left_eye_results_cache_.resize(faces.size(), -1.0f);
135+
m_react_right_eye_results_cache_.resize(faces.size(), -1.0f);
132136
for (int i = 0; i < faces.size(); ++i) {
133137
const auto &face = faces[i];
134138
// RGB Liveness Detect
@@ -161,6 +165,38 @@ int32_t FaceContext::FacesProcess(CameraStream &image, const std::vector<HyperFa
161165
return ret;
162166
}
163167
}
168+
// Face interaction
169+
if (param.enable_interaction_liveness) {
170+
auto ret = m_face_pipeline_->Process(image, face, PROCESS_INTERACTION);
171+
if (ret != HSUCCEED) {
172+
return ret;
173+
}
174+
// Get eyes status
175+
m_react_left_eye_results_cache_[i] = m_face_pipeline_->eyesStatusCache[0];
176+
m_react_right_eye_results_cache_[i] = m_face_pipeline_->eyesStatusCache[1];
177+
// Special handling: ff it is a tracking state, it needs to be filtered
178+
if (face.trackState > 0)
179+
{
180+
auto idx = face.inGroupIndex;
181+
if (idx < m_face_track_->trackingFace.size()) {
182+
auto& target = m_face_track_->trackingFace[idx];
183+
if (target.GetTrackingId() == face.trackId) {
184+
auto new_eye_left = EmaFilter(m_face_pipeline_->eyesStatusCache[0], target.left_eye_status_, 8, 0.2f);
185+
auto new_eye_right = EmaFilter(m_face_pipeline_->eyesStatusCache[1], target.right_eye_status_, 8, 0.2f);
186+
if (face.trackState > 1) {
187+
// The filtered value can be obtained only in the tracking state
188+
m_react_left_eye_results_cache_[i] = new_eye_left;
189+
m_react_right_eye_results_cache_[i] = new_eye_right;
190+
}
191+
192+
} else {
193+
INSPIRE_LOGD("Serialized objects cannot connect to trace objects in memory, and there may be some problems");
194+
}
195+
} else {
196+
INSPIRE_LOGW("The index of the trace object does not match the trace list in memory, and there may be some problems");
197+
}
198+
}
199+
}
164200

165201
}
166202

@@ -212,6 +248,13 @@ const std::vector<float>& FaceContext::GetFaceQualityScoresResultsCache() const
212248
return m_quality_score_results_cache_;
213249
}
214250

251+
const std::vector<float>& FaceContext::GetFaceInteractionLeftEyeStatusCache() const {
252+
return m_react_left_eye_results_cache_;
253+
}
254+
255+
const std::vector<float>& FaceContext::GetFaceInteractionRightEyeStatusCache() const {
256+
return m_react_right_eye_results_cache_;
257+
}
215258

216259
const Embedded& FaceContext::GetFaceFeatureCache() const {
217260
return m_face_feature_cache_;

cpp/inspireface/face_context.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,18 @@ class INSPIRE_API FaceContext {
232232
*/
233233
const std::vector<float>& GetFaceQualityScoresResultsCache() const;
234234

235+
/**
236+
* @brief Gets the cache of left eye status predict results.
237+
* @return A const reference to a vector containing eye status predict results.
238+
*/
239+
const std::vector<float>& GetFaceInteractionLeftEyeStatusCache() const;
240+
241+
/**
242+
* @brief Gets the cache of right eye status predict results.
243+
* @return A const reference to a vector containing eye status predict results.
244+
*/
245+
const std::vector<float>& GetFaceInteractionRightEyeStatusCache() const;
246+
235247
/**
236248
* @brief Gets the cache of the current face features.
237249
* @return A const reference to the Embedded object containing current face feature data.
@@ -263,6 +275,8 @@ class INSPIRE_API FaceContext {
263275
std::vector<float> m_mask_results_cache_; ///< Cache for mask detection results
264276
std::vector<float> m_rgb_liveness_results_cache_; ///< Cache for RGB liveness detection results
265277
std::vector<float> m_quality_score_results_cache_; ///< Cache for RGB face quality score results
278+
std::vector<float> m_react_left_eye_results_cache_; ///< Cache for Left eye state in face interaction
279+
std::vector<float> m_react_right_eye_results_cache_; ///< Cache for Right eye state in face interaction
266280
Embedded m_face_feature_cache_; ///< Cache for current face feature data
267281

268282
std::mutex m_mtx_; ///< Mutex for thread safety.

0 commit comments

Comments
 (0)