mirror of
https://github.com/deepinsight/insightface.git
synced 2025-12-30 08:02:27 +00:00
Merge pull request #2776 from tunmx/bugfix/det_preprocess_error
Fix the issue of rga image processing for face detection
This commit is contained in:
@@ -768,6 +768,14 @@ For different scenarios, we currently provide several Packs, each containing mul
|
|||||||
- [x] Add the RKNPU backend support for Android .
|
- [x] Add the RKNPU backend support for Android .
|
||||||
- [ ] Example app project for Android and iOS samples.
|
- [ ] Example app project for Android and iOS samples.
|
||||||
- [ ] Add the batch forward feature.
|
- [ ] Add the batch forward feature.
|
||||||
|
- [ ] Design a scheme that can be adapted to multiple CUDA devices.
|
||||||
|
|
||||||
|
- Continue to provide more support for Rockchip NPU2 devices:
|
||||||
|
- [ ] RK3576 Series
|
||||||
|
- [ ] RK3562 Series
|
||||||
|
- [ ] RV1103B/RV1106B
|
||||||
|
- [ ] RV1126B
|
||||||
|
- [ ] RK2118
|
||||||
|
|
||||||
## Acknowledgement
|
## Acknowledgement
|
||||||
|
|
||||||
|
|||||||
@@ -694,6 +694,7 @@ HResult HFExecuteFaceTrack(HFSession session, HFImageStream streamHandle, PHFMul
|
|||||||
results->rects = (HFaceRect *)ctx->impl.GetFaceRectsCache().data();
|
results->rects = (HFaceRect *)ctx->impl.GetFaceRectsCache().data();
|
||||||
results->trackIds = (HInt32 *)ctx->impl.GetTrackIDCache().data();
|
results->trackIds = (HInt32 *)ctx->impl.GetTrackIDCache().data();
|
||||||
results->detConfidence = (HFloat *)ctx->impl.GetDetConfidenceCache().data();
|
results->detConfidence = (HFloat *)ctx->impl.GetDetConfidenceCache().data();
|
||||||
|
results->trackCounts = (HInt32 *)ctx->impl.GetTrackCountCache().data();
|
||||||
results->angles.pitch = (HFloat *)ctx->impl.GetPitchResultsCache().data();
|
results->angles.pitch = (HFloat *)ctx->impl.GetPitchResultsCache().data();
|
||||||
results->angles.roll = (HFloat *)ctx->impl.GetRollResultsCache().data();
|
results->angles.roll = (HFloat *)ctx->impl.GetRollResultsCache().data();
|
||||||
results->angles.yaw = (HFloat *)ctx->impl.GetYawResultsCache().data();
|
results->angles.yaw = (HFloat *)ctx->impl.GetYawResultsCache().data();
|
||||||
|
|||||||
@@ -513,6 +513,7 @@ typedef struct HFMultipleFaceData {
|
|||||||
HInt32 detectedNum; ///< Number of faces detected.
|
HInt32 detectedNum; ///< Number of faces detected.
|
||||||
HFaceRect *rects; ///< Array of bounding rectangles for each face.
|
HFaceRect *rects; ///< Array of bounding rectangles for each face.
|
||||||
HInt32 *trackIds; ///< Array of track IDs for each face.
|
HInt32 *trackIds; ///< Array of track IDs for each face.
|
||||||
|
HInt32 *trackCounts; ///< Array of track counts for each face.
|
||||||
HFloat *detConfidence; ///< Array of detection confidence for each face.
|
HFloat *detConfidence; ///< Array of detection confidence for each face.
|
||||||
HFFaceEulerAngle angles; ///< Euler angles for each face.
|
HFFaceEulerAngle angles; ///< Euler angles for each face.
|
||||||
PHFFaceBasicToken tokens; ///< Tokens associated with each face.
|
PHFFaceBasicToken tokens; ///< Tokens associated with each face.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#ifndef INSPIRE_FACE_SERIALIZE_TOOLS_H
|
#ifndef INSPIRE_FACE_SERIALIZE_TOOLS_H
|
||||||
#define INSPIRE_FACE_SERIALIZE_TOOLS_H
|
#define INSPIRE_FACE_SERIALIZE_TOOLS_H
|
||||||
|
|
||||||
#include "face_warpper.h"
|
#include "face_wrapper.h"
|
||||||
#include "../face_info/face_object_internal.h"
|
#include "../face_info/face_object_internal.h"
|
||||||
#include "herror.h"
|
#include "herror.h"
|
||||||
#include "data_type.h"
|
#include "data_type.h"
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ int32_t FaceSession::FaceDetectAndTrack(inspirecv::FrameProcess& process) {
|
|||||||
m_face_basic_data_cache_.clear();
|
m_face_basic_data_cache_.clear();
|
||||||
m_face_rects_cache_.clear();
|
m_face_rects_cache_.clear();
|
||||||
m_track_id_cache_.clear();
|
m_track_id_cache_.clear();
|
||||||
|
m_track_count_cache_.clear();
|
||||||
m_quality_results_cache_.clear();
|
m_quality_results_cache_.clear();
|
||||||
m_roll_results_cache_.clear();
|
m_roll_results_cache_.clear();
|
||||||
m_yaw_results_cache_.clear();
|
m_yaw_results_cache_.clear();
|
||||||
@@ -86,6 +87,7 @@ int32_t FaceSession::FaceDetectAndTrack(inspirecv::FrameProcess& process) {
|
|||||||
m_det_confidence_cache_.push_back(face.GetConfidence());
|
m_det_confidence_cache_.push_back(face.GetConfidence());
|
||||||
m_detect_cache_.push_back(byteArray);
|
m_detect_cache_.push_back(byteArray);
|
||||||
m_track_id_cache_.push_back(face.GetTrackingId());
|
m_track_id_cache_.push_back(face.GetTrackingId());
|
||||||
|
m_track_count_cache_.push_back(face.GetTrackingCount());
|
||||||
m_face_rects_cache_.push_back(data.rect);
|
m_face_rects_cache_.push_back(data.rect);
|
||||||
m_quality_results_cache_.push_back(face.high_result);
|
m_quality_results_cache_.push_back(face.high_result);
|
||||||
m_roll_results_cache_.push_back(face.high_result.roll);
|
m_roll_results_cache_.push_back(face.high_result.roll);
|
||||||
@@ -273,6 +275,10 @@ const std::vector<int32_t>& FaceSession::GetTrackIDCache() const {
|
|||||||
return m_track_id_cache_;
|
return m_track_id_cache_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<int32_t>& FaceSession::GetTrackCountCache() const {
|
||||||
|
return m_track_count_cache_;
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<float>& FaceSession::GetRollResultsCache() const {
|
const std::vector<float>& FaceSession::GetRollResultsCache() const {
|
||||||
return m_roll_results_cache_;
|
return m_roll_results_cache_;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,6 +214,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
const std::vector<int32_t>& GetTrackIDCache() const;
|
const std::vector<int32_t>& GetTrackIDCache() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the cache of tracking count.
|
||||||
|
* @return std::vector<int32_t> Cache of tracking count.
|
||||||
|
*/
|
||||||
|
const std::vector<int32_t>& GetTrackCountCache() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieves the cache of roll results from face pose estimation.
|
* @brief Retrieves the cache of roll results from face pose estimation.
|
||||||
* @return std::vector<float> Cache of roll results.
|
* @return std::vector<float> Cache of roll results.
|
||||||
@@ -396,6 +402,7 @@ private:
|
|||||||
std::vector<FaceBasicData> m_face_basic_data_cache_; ///< Cache for basic face data extracted from detection
|
std::vector<FaceBasicData> m_face_basic_data_cache_; ///< Cache for basic face data extracted from detection
|
||||||
std::vector<FaceRect> m_face_rects_cache_; ///< Cache for face rectangle data from detection
|
std::vector<FaceRect> m_face_rects_cache_; ///< Cache for face rectangle data from detection
|
||||||
std::vector<int32_t> m_track_id_cache_; ///< Cache for tracking IDs of detected faces
|
std::vector<int32_t> m_track_id_cache_; ///< Cache for tracking IDs of detected faces
|
||||||
|
std::vector<int32_t> m_track_count_cache_; ///< Cache for tracking count of detected faces
|
||||||
std::vector<float> m_det_confidence_cache_; ///< Cache for face detection confidence of detected faces
|
std::vector<float> m_det_confidence_cache_; ///< Cache for face detection confidence of detected faces
|
||||||
std::vector<float> m_roll_results_cache_; ///< Cache for storing roll results from face pose estimation
|
std::vector<float> m_roll_results_cache_; ///< Cache for storing roll results from face pose estimation
|
||||||
std::vector<float> m_yaw_results_cache_; ///< Cache for storing yaw results from face pose estimation
|
std::vector<float> m_yaw_results_cache_; ///< Cache for storing yaw results from face pose estimation
|
||||||
|
|||||||
@@ -11,4 +11,4 @@
|
|||||||
#include "similarity_converter.h"
|
#include "similarity_converter.h"
|
||||||
#include "spend_timer.h"
|
#include "spend_timer.h"
|
||||||
#include "information.h"
|
#include "information.h"
|
||||||
#include "face_warpper.h"
|
#include "face_wrapper.h"
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include "data_type.h"
|
#include "data_type.h"
|
||||||
#include "frame_process.h"
|
#include "frame_process.h"
|
||||||
#include "face_warpper.h"
|
#include "face_wrapper.h"
|
||||||
|
|
||||||
namespace inspire {
|
namespace inspire {
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#include "liveness/rgb_anti_spoofing_adapt.h"
|
#include "liveness/rgb_anti_spoofing_adapt.h"
|
||||||
#include "liveness/blink_predict_adapt.h"
|
#include "liveness/blink_predict_adapt.h"
|
||||||
#include "middleware/model_archive/inspire_archive.h"
|
#include "middleware/model_archive/inspire_archive.h"
|
||||||
#include "face_warpper.h"
|
#include "face_wrapper.h"
|
||||||
#include "track_module/landmark/landmark_param.h"
|
#include "track_module/landmark/landmark_param.h"
|
||||||
#include "attribute/face_emotion_adapt.h"
|
#include "attribute/face_emotion_adapt.h"
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include "extract/extract_adapt.h"
|
#include "extract/extract_adapt.h"
|
||||||
#include "common/face_info/face_object_internal.h"
|
#include "common/face_info/face_object_internal.h"
|
||||||
#include "face_warpper.h"
|
#include "face_wrapper.h"
|
||||||
#include "middleware/model_archive/inspire_archive.h"
|
#include "middleware/model_archive/inspire_archive.h"
|
||||||
#include "frame_process.h"
|
#include "frame_process.h"
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,12 @@ FaceLocList FaceDetectAdapt::operator()(const inspirecv::Image &bgr) {
|
|||||||
inspirecv::Image pad;
|
inspirecv::Image pad;
|
||||||
|
|
||||||
uint8_t *resized_data = nullptr;
|
uint8_t *resized_data = nullptr;
|
||||||
m_processor_->ResizeAndPadding(bgr.Data(), bgr.Width(), bgr.Height(), bgr.Channels(), m_input_size_, m_input_size_, &resized_data, scale);
|
if (ori_w == m_input_size_ && ori_h == m_input_size_) {
|
||||||
|
scale = 1.0f;
|
||||||
|
resized_data = (uint8_t *)bgr.Data();
|
||||||
|
} else {
|
||||||
|
m_processor_->ResizeAndPadding(bgr.Data(), bgr.Width(), bgr.Height(), bgr.Channels(), m_input_size_, m_input_size_, &resized_data, scale);
|
||||||
|
}
|
||||||
|
|
||||||
pad = inspirecv::Image::Create(m_input_size_, m_input_size_, bgr.Channels(), resized_data, false);
|
pad = inspirecv::Image::Create(m_input_size_, m_input_size_, bgr.Channels(), resized_data, false);
|
||||||
|
|
||||||
|
|||||||
@@ -451,9 +451,9 @@ void FaceTrackModule::SetTrackPreviewSize(int preview_size) {
|
|||||||
track_preview_size_ = preview_size;
|
track_preview_size_ = preview_size;
|
||||||
if (track_preview_size_ == -1) {
|
if (track_preview_size_ == -1) {
|
||||||
track_preview_size_ = m_face_detector_->GetInputSize();
|
track_preview_size_ = m_face_detector_->GetInputSize();
|
||||||
} else if (track_preview_size_ < 192) {
|
} else if (track_preview_size_ < 160) {
|
||||||
INSPIRE_LOGW("Track preview size %d is less than the minimum input size %d", track_preview_size_, 192);
|
INSPIRE_LOGW("Track preview size %d is less than the minimum input size %d", track_preview_size_, 160);
|
||||||
track_preview_size_ = 192;
|
track_preview_size_ = 160;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ int main(int argc, char* argv[]) {
|
|||||||
/* Maximum number of faces detected */
|
/* Maximum number of faces detected */
|
||||||
maxDetectNum = 20;
|
maxDetectNum = 20;
|
||||||
/* Face detection image input level */
|
/* Face detection image input level */
|
||||||
detectPixelLevel = 160;
|
detectPixelLevel = 320;
|
||||||
/* Handle of the current face SDK algorithm context */
|
/* Handle of the current face SDK algorithm context */
|
||||||
session = NULL;
|
session = NULL;
|
||||||
ret = HFCreateInspireFaceSessionOptional(option, detMode, maxDetectNum, detectPixelLevel, -1, &session);
|
ret = HFCreateInspireFaceSessionOptional(option, detMode, maxDetectNum, detectPixelLevel, -1, &session);
|
||||||
@@ -156,6 +156,7 @@ int main(int argc, char* argv[]) {
|
|||||||
HFLogPrint(HF_LOG_INFO, "Token size: %d", multipleFaceData.tokens[index].size);
|
HFLogPrint(HF_LOG_INFO, "Token size: %d", multipleFaceData.tokens[index].size);
|
||||||
HFLogPrint(HF_LOG_INFO, "Process face index: %d", index);
|
HFLogPrint(HF_LOG_INFO, "Process face index: %d", index);
|
||||||
HFLogPrint(HF_LOG_INFO, "DetConfidence: %f", multipleFaceData.detConfidence[index]);
|
HFLogPrint(HF_LOG_INFO, "DetConfidence: %f", multipleFaceData.detConfidence[index]);
|
||||||
|
HFLogPrint(HF_LOG_INFO, "TrackCount: %d", multipleFaceData.trackCounts[index]);
|
||||||
|
|
||||||
HFImageBitmapDrawRect(drawImage, multipleFaceData.rects[index], (HColor){0, 100, 255}, 4);
|
HFImageBitmapDrawRect(drawImage, multipleFaceData.rects[index], (HColor){0, 100, 255}, 4);
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ int main(int argc, char* argv[]) {
|
|||||||
HOption option = HF_ENABLE_QUALITY | HF_ENABLE_MASK_DETECT | HF_ENABLE_LIVENESS;
|
HOption option = HF_ENABLE_QUALITY | HF_ENABLE_MASK_DETECT | HF_ENABLE_LIVENESS;
|
||||||
/* Non-video or frame sequence mode uses IMAGE-MODE, which is always face detection without
|
/* Non-video or frame sequence mode uses IMAGE-MODE, which is always face detection without
|
||||||
* tracking */
|
* tracking */
|
||||||
HFDetectMode detMode = HF_DETECT_MODE_ALWAYS_DETECT;
|
HFDetectMode detMode = HF_DETECT_MODE_LIGHT_TRACK;
|
||||||
/* Maximum number of faces detected */
|
/* Maximum number of faces detected */
|
||||||
HInt32 maxDetectNum = 20;
|
HInt32 maxDetectNum = 20;
|
||||||
/* Face detection image input level */
|
/* Face detection image input level */
|
||||||
@@ -112,10 +112,28 @@ int main(int argc, char* argv[]) {
|
|||||||
HFLogPrint(HF_LOG_INFO, "Number of Detection: %d", multipleFaceData.detectedNum);
|
HFLogPrint(HF_LOG_INFO, "Number of Detection: %d", multipleFaceData.detectedNum);
|
||||||
HFSessionPrintTrackCostSpend(session);
|
HFSessionPrintTrackCostSpend(session);
|
||||||
|
|
||||||
|
if (multipleFaceData.detectedNum > 0) {
|
||||||
|
HFLogPrint(HF_LOG_INFO, "========================================");
|
||||||
|
for (i = 0; i < multipleFaceData.detectedNum; i++) {
|
||||||
|
HFLogPrint(HF_LOG_INFO, "TrackId: %d", multipleFaceData.trackIds[i]);
|
||||||
|
HFLogPrint(HF_LOG_INFO, "TrackCount: %d", multipleFaceData.trackCounts[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HFLogPrint(HF_LOG_WARN, "The face cannot be detected, and the tracking test results may be invalid!");
|
||||||
|
}
|
||||||
|
|
||||||
ret = HFReleaseImageStream(imageHandle);
|
ret = HFReleaseImageStream(imageHandle);
|
||||||
if (ret != HSUCCEED) {
|
if (ret != HSUCCEED) {
|
||||||
HFLogPrint(HF_LOG_ERROR, "Release image stream error: %d", ret);
|
HFLogPrint(HF_LOG_ERROR, "Release image stream error: %d", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ret = HFReleaseImageBitmap(image);
|
||||||
|
if (ret != HSUCCEED) {
|
||||||
|
HFLogPrint(HF_LOG_ERROR, "Release image bitmap error: %d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* The memory must be freed at the end of the program */
|
/* The memory must be freed at the end of the program */
|
||||||
ret = HFReleaseInspireFaceSession(session);
|
ret = HFReleaseInspireFaceSession(session);
|
||||||
if (ret != HSUCCEED) {
|
if (ret != HSUCCEED) {
|
||||||
@@ -123,11 +141,5 @@ int main(int argc, char* argv[]) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = HFReleaseImageBitmap(image);
|
|
||||||
if (ret != HSUCCEED) {
|
|
||||||
HFLogPrint(HF_LOG_ERROR, "Release image bitmap error: %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<mxfile host="Electron" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.5 Chrome/126.0.6478.183 Electron/31.3.0 Safari/537.36" version="24.7.5">
|
<mxfile host="Electron" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.5 Chrome/126.0.6478.183 Electron/31.3.0 Safari/537.36" version="24.7.5">
|
||||||
<diagram name="第 1 页" id="FP0FvKHnDjYPDM2ZKx7P">
|
<diagram name="page 1" id="FP0FvKHnDjYPDM2ZKx7P">
|
||||||
<mxGraphModel dx="781" dy="688" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
<mxGraphModel dx="781" dy="688" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0" />
|
<mxCell id="0" />
|
||||||
|
|||||||
@@ -1,102 +1,102 @@
|
|||||||
# InspireFace Python API
|
# InspireFace Python API
|
||||||
|
|
||||||
InspireFace 提供了简单易用的 Python API,通过 ctypes 封装底层动态链接库实现。您可以通过 pip 安装最新发布版本,或使用项目自行编译的动态库进行配置。
|
InspireFace provides an easy-to-use Python API that wraps the underlying dynamic link library through ctypes. You can install the latest release version via pip or configure it using the project's self-compiled dynamic library.
|
||||||
|
|
||||||
## 快速安装
|
## Quick Installation
|
||||||
|
|
||||||
### 通过 pip 安装(推荐)
|
### Install via pip (Recommended)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install inspireface
|
pip install inspireface
|
||||||
```
|
```
|
||||||
|
|
||||||
### 手动安装
|
### Manual Installation
|
||||||
|
|
||||||
1. 首先安装必要的依赖:
|
1. First install the necessary dependencies:
|
||||||
```bash
|
```bash
|
||||||
pip install loguru tqdm opencv-python
|
pip install loguru tqdm opencv-python
|
||||||
```
|
```
|
||||||
|
|
||||||
2. 将编译好的动态库复制到指定目录:
|
2. Copy the compiled dynamic library to the specified directory:
|
||||||
```bash
|
```bash
|
||||||
# 将编译好的动态库复制到对应系统架构目录
|
# Copy the compiled dynamic library to the corresponding system architecture directory
|
||||||
cp YOUR_BUILD_DIR/libInspireFace.so inspireface/modules/core/SYSTEM/CORE_ARCH/
|
cp YOUR_BUILD_DIR/libInspireFace.so inspireface/modules/core/SYSTEM/CORE_ARCH/
|
||||||
```
|
```
|
||||||
|
|
||||||
3. 安装 Python 包:
|
3. Install the Python package:
|
||||||
```bash
|
```bash
|
||||||
python setup.py install
|
python setup.py install
|
||||||
```
|
```
|
||||||
|
|
||||||
## 快速开始
|
## Quick Start
|
||||||
|
|
||||||
以下是一个简单的示例,展示如何使用 InspireFace 进行人脸检测和关键点绘制:
|
Here's a simple example showing how to use InspireFace for face detection and landmark drawing:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import cv2
|
import cv2
|
||||||
import inspireface as isf
|
import inspireface as isf
|
||||||
|
|
||||||
# 创建会话,启用所需功能
|
# Create session with required features enabled
|
||||||
session = isf.InspireFaceSession(
|
session = isf.InspireFaceSession(
|
||||||
opt=isf.HF_ENABLE_NONE, # 可选功能
|
opt=isf.HF_ENABLE_NONE, # Optional features
|
||||||
detect_mode=isf.HF_DETECT_MODE_ALWAYS_DETECT # 检测模式
|
detect_mode=isf.HF_DETECT_MODE_ALWAYS_DETECT # Detection mode
|
||||||
)
|
)
|
||||||
|
|
||||||
# 设置检测置信度阈值
|
# Set detection confidence threshold
|
||||||
session.set_detection_confidence_threshold(0.5)
|
session.set_detection_confidence_threshold(0.5)
|
||||||
|
|
||||||
# 读取图像
|
# Read image
|
||||||
image = cv2.imread("path/to/your/image.jpg")
|
image = cv2.imread("path/to/your/image.jpg")
|
||||||
assert image is not None, "请检查图像路径是否正确"
|
assert image is not None, "Please check if the image path is correct"
|
||||||
|
|
||||||
# 执行人脸检测
|
# Perform face detection
|
||||||
faces = session.face_detection(image)
|
faces = session.face_detection(image)
|
||||||
print(f"检测到 {len(faces)} 个人脸")
|
print(f"Detected {len(faces)} faces")
|
||||||
|
|
||||||
# 在图像上绘制检测结果
|
# Draw detection results on image
|
||||||
draw = image.copy()
|
draw = image.copy()
|
||||||
for idx, face in enumerate(faces):
|
for idx, face in enumerate(faces):
|
||||||
# 获取人脸框位置
|
# Get face bounding box coordinates
|
||||||
x1, y1, x2, y2 = face.location
|
x1, y1, x2, y2 = face.location
|
||||||
|
|
||||||
# 计算旋转框参数
|
# Calculate rotated box parameters
|
||||||
center = ((x1 + x2) / 2, (y1 + y2) / 2)
|
center = ((x1 + x2) / 2, (y1 + y2) / 2)
|
||||||
size = (x2 - x1, y2 - y1)
|
size = (x2 - x1, y2 - y1)
|
||||||
angle = face.roll
|
angle = face.roll
|
||||||
|
|
||||||
# 绘制旋转框
|
# Draw rotated box
|
||||||
rect = ((center[0], center[1]), (size[0], size[1]), angle)
|
rect = ((center[0], center[1]), (size[0], size[1]), angle)
|
||||||
box = cv2.boxPoints(rect)
|
box = cv2.boxPoints(rect)
|
||||||
box = box.astype(int)
|
box = box.astype(int)
|
||||||
cv2.drawContours(draw, [box], 0, (100, 180, 29), 2)
|
cv2.drawContours(draw, [box], 0, (100, 180, 29), 2)
|
||||||
|
|
||||||
# 绘制关键点
|
# Draw landmarks
|
||||||
landmarks = session.get_face_dense_landmark(face)
|
landmarks = session.get_face_dense_landmark(face)
|
||||||
for x, y in landmarks.astype(int):
|
for x, y in landmarks.astype(int):
|
||||||
cv2.circle(draw, (x, y), 0, (220, 100, 0), 2)
|
cv2.circle(draw, (x, y), 0, (220, 100, 0), 2)
|
||||||
```
|
```
|
||||||
|
|
||||||
## 更多示例
|
## More Examples
|
||||||
|
|
||||||
项目提供了多个示例文件,展示了不同的功能:
|
The project provides multiple example files demonstrating different features:
|
||||||
|
|
||||||
- `sample_face_detection.py`: 基础人脸检测
|
- `sample_face_detection.py`: Basic face detection
|
||||||
- `sample_face_track_from_video.py`: 视频人脸跟踪
|
- `sample_face_track_from_video.py`: Video face tracking
|
||||||
- `sample_face_recognition.py`: 人脸识别
|
- `sample_face_recognition.py`: Face recognition
|
||||||
- `sample_face_comparison.py`: 人脸比对
|
- `sample_face_comparison.py`: Face comparison
|
||||||
- `sample_feature_hub.py`: 特征提取
|
- `sample_feature_hub.py`: Feature extraction
|
||||||
- `sample_system_resource_statistics.py`: 系统资源统计
|
- `sample_system_resource_statistics.py`: System resource statistics
|
||||||
|
|
||||||
## 运行测试
|
## Running Tests
|
||||||
|
|
||||||
项目包含单元测试,您可以通过修改 `test/test_settings.py` 中的参数来调整测试内容:
|
The project includes unit tests. You can adjust test content by modifying parameters in `test/test_settings.py`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m unittest discover -s test
|
python -m unittest discover -s test
|
||||||
```
|
```
|
||||||
|
|
||||||
## 注意事项
|
## Notes
|
||||||
|
|
||||||
1. 确保系统已安装 OpenCV 和其他必要依赖
|
1. Ensure that OpenCV and other necessary dependencies are installed on your system
|
||||||
2. 使用前请确保动态库已正确安装
|
2. Make sure the dynamic library is correctly installed before use
|
||||||
3. 建议使用 Python 3.7 或更高版本
|
3. Python 3.7 or higher is recommended
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -197,6 +197,7 @@ class FaceInformation:
|
|||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
track_id: int,
|
track_id: int,
|
||||||
|
track_count: int,
|
||||||
detection_confidence: float,
|
detection_confidence: float,
|
||||||
location: Tuple,
|
location: Tuple,
|
||||||
roll: float,
|
roll: float,
|
||||||
@@ -205,6 +206,7 @@ class FaceInformation:
|
|||||||
_token: HFFaceBasicToken,
|
_token: HFFaceBasicToken,
|
||||||
_feature: np.array = None):
|
_feature: np.array = None):
|
||||||
self.track_id = track_id
|
self.track_id = track_id
|
||||||
|
self.track_count = track_count
|
||||||
self.detection_confidence = detection_confidence
|
self.detection_confidence = detection_confidence
|
||||||
self.location = location
|
self.location = location
|
||||||
self.roll = roll
|
self.roll = roll
|
||||||
@@ -226,7 +228,7 @@ class FaceInformation:
|
|||||||
self._token.data = cast(addressof(self.buffer), c_void_p)
|
self._token.data = cast(addressof(self.buffer), c_void_p)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"FaceInformation(track_id={self.track_id}, detection_confidence={self.detection_confidence}, location={self.location}, roll={self.roll}, yaw={self.yaw}, pitch={self.pitch})"
|
return f"FaceInformation(track_id={self.track_id}, track_count={self.track_count}, detection_confidence={self.detection_confidence}, location={self.location}, roll={self.roll}, yaw={self.yaw}, pitch={self.pitch})"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -336,6 +338,7 @@ class InspireFaceSession(object):
|
|||||||
track_ids = self._get_faces_track_ids()
|
track_ids = self._get_faces_track_ids()
|
||||||
euler_angle = self._get_faces_euler_angle()
|
euler_angle = self._get_faces_euler_angle()
|
||||||
tokens = self._get_faces_tokens()
|
tokens = self._get_faces_tokens()
|
||||||
|
track_counts = self._get_faces_track_counts()
|
||||||
|
|
||||||
infos = list()
|
infos = list()
|
||||||
for idx in range(self.multiple_faces.detectedNum):
|
for idx in range(self.multiple_faces.detectedNum):
|
||||||
@@ -347,6 +350,7 @@ class InspireFaceSession(object):
|
|||||||
track_id = track_ids[idx]
|
track_id = track_ids[idx]
|
||||||
_token = tokens[idx]
|
_token = tokens[idx]
|
||||||
detection_confidence = self.multiple_faces.detConfidence[idx]
|
detection_confidence = self.multiple_faces.detConfidence[idx]
|
||||||
|
track_count = track_counts[idx]
|
||||||
|
|
||||||
info = FaceInformation(
|
info = FaceInformation(
|
||||||
location=(top_left[0], top_left[1], bottom_right[0], bottom_right[1]),
|
location=(top_left[0], top_left[1], bottom_right[0], bottom_right[1]),
|
||||||
@@ -354,6 +358,7 @@ class InspireFaceSession(object):
|
|||||||
yaw=yaw,
|
yaw=yaw,
|
||||||
pitch=pitch,
|
pitch=pitch,
|
||||||
track_id=track_id,
|
track_id=track_id,
|
||||||
|
track_count=track_count,
|
||||||
_token=_token,
|
_token=_token,
|
||||||
detection_confidence=detection_confidence,
|
detection_confidence=detection_confidence,
|
||||||
)
|
)
|
||||||
@@ -641,6 +646,12 @@ class InspireFaceSession(object):
|
|||||||
angles = [(euler_angle.roll[i], euler_angle.yaw[i], euler_angle.pitch[i]) for i in range(num_of_faces)]
|
angles = [(euler_angle.roll[i], euler_angle.yaw[i], euler_angle.pitch[i]) for i in range(num_of_faces)]
|
||||||
|
|
||||||
return angles
|
return angles
|
||||||
|
|
||||||
|
def _get_faces_track_counts(self) -> List:
|
||||||
|
num_of_faces = self.multiple_faces.detectedNum
|
||||||
|
track_counts_ptr = self.multiple_faces.trackCounts
|
||||||
|
track_counts = [track_counts_ptr[i] for i in range(num_of_faces)]
|
||||||
|
return track_counts
|
||||||
|
|
||||||
def _get_faces_tokens(self) -> List[HFFaceBasicToken]:
|
def _get_faces_tokens(self) -> List[HFFaceBasicToken]:
|
||||||
num_of_faces = self.multiple_faces.detectedNum
|
num_of_faces = self.multiple_faces.detectedNum
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ def case_face_tracker_from_video(source, show, out):
|
|||||||
cv2.circle(frame, (x, y), 0, (255-color[0], 255-color[1], 255-color[2]), 6)
|
cv2.circle(frame, (x, y), 0, (255-color[0], 255-color[1], 255-color[2]), 6)
|
||||||
|
|
||||||
# Draw track ID at the top of the bounding box
|
# Draw track ID at the top of the bounding box
|
||||||
text = f"ID: {face.track_id}"
|
text = f"ID: {face.track_id}, Count: {face.track_count}"
|
||||||
text_size, _ = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, 0.6, 2)
|
text_size, _ = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, 0.6, 2)
|
||||||
text_x = min(box[:, 0])
|
text_x = min(box[:, 0])
|
||||||
text_y = min(box[:, 1]) - 10
|
text_y = min(box[:, 1]) - 10
|
||||||
|
|||||||
Reference in New Issue
Block a user