no message
@ -1,50 +0,0 @@
|
||||
|
||||
### Download the model and put it in the /models directory
|
||||
- Link: https://github.com/mymagicpower/AIAS/releases/download/apps/MobileFace.zip
|
||||
|
||||
### Face feature extraction and comparison SDK
|
||||
This example provides a reference implementation for face feature extraction and comparison.
|
||||
For a complete example, please refer to 8_suite_hub/face_search (PyTorch algorithm implementation,
|
||||
please refer to the existing implementation and convert it to Paddle algorithm as needed).
|
||||
The complete pipeline for face recognition: face detection (including facial landmarks) --> face alignment -->
|
||||
face feature extraction --> face comparison
|
||||
|
||||
#### Face feature extraction: (omitting previous steps: face detection (including facial landmarks) --> face alignment)
|
||||
Model inference example: FeatureExtractionExample
|
||||
|
||||
#### Face feature comparison:
|
||||
Face comparison example: FeatureComparisonExample
|
||||
|
||||
|
||||
#### Run the Face Feature Extraction Example - FeatureExtractionExample
|
||||
After successful execution, the command line should display the following information:
|
||||
```text
|
||||
[INFO ] - Face feature: [-0.04026184, -0.019486362, -0.09802659, 0.01700999, 0.037829027, ...]
|
||||
```
|
||||
|
||||
#### Run the Face Feature Comparison Example - FeatureComparisonExample
|
||||
`src/test/resources/kana1.jpg`
|
||||
![kana1](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/face_sdk/images/kana1.jpg)
|
||||
`src/test/resources/kana2.jpg`
|
||||
![kana2](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/face_sdk/images/kana2.jpg)
|
||||
|
||||
After successful execution, the command line should display the following information:
|
||||
The comparison is based on the calculation of Euclidean distance.
|
||||
|
||||
```text
|
||||
[INFO ] - face1 feature: [-0.040261842, -0.019486364, ..., 0.031147916, -0.032064643]
|
||||
[INFO ] - face2 feature: [-0.049654193, -0.04029847, ..., 0.04562381, -0.044428844]
|
||||
[INFO ] - 相似度: 0.9022608
|
||||
```
|
||||
|
||||
### Open source algorithms
|
||||
#### 1. Open source algorithms used by the SDK
|
||||
- [insightface](https://github.com/deepinsight/insightface)
|
||||
|
||||
#### Pre-trained models used by the project:
|
||||
- [model_zoo](https://github.com/deepinsight/insightface/tree/master/model_zoo)
|
||||
- [iresnet50](https://paddle-model-ecology.bj.bcebos.com/model/insight-face/arcface_iresnet50_v1.0_infer.tar)
|
||||
|
||||
|
||||
#### 2. How to export the model?
|
||||
- [how_to_export_paddle_model](https://github.com/deepinsight/insightface/blob/master/recognition/arcface_paddle/tools/export.py)
|
@ -1,95 +0,0 @@
|
||||
### 官网:
|
||||
[官网链接](http://www.aias.top/)
|
||||
|
||||
### 下载模型,放置于models目录
|
||||
- 链接: https://pan.baidu.com/s/14My5-kkvjEChI9Ssvnwaiw?pwd=85av
|
||||
|
||||
### 人脸特征提取与比对SDK
|
||||
|
||||
#### 人脸识别
|
||||
广义的人脸识别实际包括构建人脸识别系统的一系列相关技术,包括人脸图像采集、人脸定位、人脸识别预处理、身份确认以及身份查找等;
|
||||
而狭义的人脸识别特指通过人脸进行身份确认或者身份查找的技术或系统。
|
||||
人脸识别是一项热门的计算机技术研究领域,它属于生物特征识别技术,是对生物体(一般特指人)本身的生物特征来区分生物体个体。
|
||||
生物特征识别技术所研究的生物特征包括脸、指纹、手掌纹、虹膜、视网膜、声音(语音)、体形、个人习惯(例如敲击键盘的力度和频率、签字)等,
|
||||
相应的识别技术就有人脸识别、指纹识别、掌纹识别、虹膜识别、视网膜识别、语音识别(用语音识别可以进行身份识别,也可以进行语音内容的识别,
|
||||
只有前者属于生物特征识别技术)、体形识别、键盘敲击识别、签字识别等。
|
||||
|
||||
#### 行业现状
|
||||
人脸识别技术目前已经广泛应用于包括人脸门禁系统、刷脸支付等各行各业。随着人脸识别技术的提升,应用越来越广泛。目前中国的人脸识
|
||||
别技术已经在世界水平上处于领先地位,在安防行业,国内主流安防厂家也都推出了各自的人脸识别产品和解决方案,泛安防行业是人脸识别技术主要应用领域。
|
||||
|
||||
#### 技术发展趋势
|
||||
目前人脸识别技术广泛采用的是基于神经网络的深度学习模型。利用深度学习提取出的人脸特征,相比于传统技术,能够提取更多的特征,
|
||||
更能表达人脸之间的相关性,能够显著提高算法的精度。近些年大数据技术以及算力都得到了大幅提升,而深度学习非常依赖于大数据与算力,
|
||||
这也是为什么这项技术在近几年取得突破的原因。更多更丰富的数据加入到训练模型中,意味着算法模型更加通用,更贴近现实世界。另一方面,算力的提升,
|
||||
使得模型可以有更深的层级结构,同时深度学习的理论模型本身也在不断的完善中,模型本身的优化将会极大地提高人脸识别的技术水平。
|
||||
|
||||
#### 人脸识别关键技术
|
||||
人脸识别涉及的关键技术包含:人脸检测,人脸关键点,人脸特征提取,人脸比对,人脸对齐。
|
||||
![face_sdk](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/face_sdk/images/face_sdk.png)
|
||||
|
||||
本文的例子给出了人脸特征提取,人脸比对的参考实现。
|
||||
完整的例子请参考 8_suite_hub/face_search(pytorch算法实现,根据需要自行参考已有实现,转换为paddle算法)。
|
||||
人脸识别完整的pipeline:人脸检测(含人脸关键点) --> 人脸对齐 --> 人脸特征提取 --> 人脸比对
|
||||
|
||||
####人脸特征提取:(省略了前序步骤: 人脸检测(含人脸关键点) --> 人脸对齐)
|
||||
模型推理例子: FeatureExtractionExample
|
||||
|
||||
####人脸特征比对:
|
||||
人脸比对例子: FeatureComparisonExample
|
||||
|
||||
|
||||
#### 运行人脸特征提取的例子 - FeatureExtractionExample
|
||||
运行成功后,命令行应该看到下面的信息:
|
||||
```text
|
||||
[INFO ] - Face feature: [-0.04026184, -0.019486362, -0.09802659, 0.01700999, 0.037829027, ...]
|
||||
```
|
||||
|
||||
#### 运行人脸特征比对的例子 - FeatureComparisonExample
|
||||
`src/test/resources/kana1.jpg`
|
||||
![kana1](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/face_sdk/images/kana1.jpg)
|
||||
`src/test/resources/kana2.jpg`
|
||||
![kana2](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/face_sdk/images/kana2.jpg)
|
||||
|
||||
运行成功后,命令行应该看到下面的信息:
|
||||
比对使用的是欧式距离的计算方式。
|
||||
|
||||
```text
|
||||
[INFO ] - face1 feature: [-0.040261842, -0.019486364, ..., 0.031147916, -0.032064643]
|
||||
[INFO ] - face2 feature: [-0.049654193, -0.04029847, ..., 0.04562381, -0.044428844]
|
||||
[INFO ] - 相似度: 0.9022608
|
||||
```
|
||||
|
||||
### 开源算法
|
||||
#### 1. sdk使用的开源算法
|
||||
- [insightface](https://github.com/deepinsight/insightface)
|
||||
|
||||
#### 项目使用的预训练模型:
|
||||
- [model_zoo](https://github.com/deepinsight/insightface/tree/master/model_zoo)
|
||||
- [iresnet50](https://paddle-model-ecology.bj.bcebos.com/model/insight-face/arcface_iresnet50_v1.0_infer.tar)
|
||||
|
||||
|
||||
#### 2. 模型如何导出 ?
|
||||
- [how_to_export_paddle_model](https://github.com/deepinsight/insightface/blob/master/recognition/arcface_paddle/tools/export.py)
|
||||
|
||||
|
||||
### 其它帮助信息
|
||||
http://aias.top/guides.html
|
||||
|
||||
|
||||
### Git地址:
|
||||
[Github链接](https://github.com/mymagicpower/AIAS)
|
||||
[Gitee链接](https://gitee.com/mymagicpower/AIAS)
|
||||
|
||||
|
||||
|
||||
#### 帮助文档:
|
||||
- http://aias.top/guides.html
|
||||
- 1.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- 4.Windows环境常见问题:
|
||||
- http://aias.top/AIAS/guides/windows.html
|
@ -1,44 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="CheckStyle-IDEA-Module">
|
||||
<option name="configuration">
|
||||
<map />
|
||||
</option>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="aais-face-feature-lib-0.1.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-cli:commons-cli:1.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.17.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.logging.log4j:log4j-core:2.17.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: ai.djl:api:0.17.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.java.dev.jna:jna:5.10.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.21" level="project" />
|
||||
<orderEntry type="library" name="Maven: ai.djl:basicdataset:0.17.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.9.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: ai.djl:model-zoo:0.17.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: ai.djl.pytorch:pytorch-engine:0.17.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: ai.djl.pytorch:pytorch-model-zoo:0.17.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: ai.djl.paddlepaddle:paddlepaddle-model-zoo:0.17.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: ai.djl.paddlepaddle:paddlepaddle-engine:0.17.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.testng:testng:6.8.1" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.10" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.beanshell:bsh:2.0b4" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: com.beust:jcommander:1.27" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.yaml:snakeyaml:1.6" level="project" />
|
||||
</component>
|
||||
</module>
|
@ -1,60 +0,0 @@
|
||||
|
||||
#### Common Model Loading Methods
|
||||
|
||||
|
||||
1. How to load a model online via URL?
|
||||
```text
|
||||
# Use optModelUrls to load a model via URL
|
||||
|
||||
Criteria<Image, DetectedObjects> criteria =
|
||||
Criteria.builder()
|
||||
.optEngine("PaddlePaddle")
|
||||
.setTypes(Image.class, DetectedObjects.class)
|
||||
.optModelUrls("https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr_models/ch_ppocr_mobile_v2.0_det_infer.zip")
|
||||
.optTranslator(new PpWordDetectionTranslator(new ConcurrentHashMap<String, String>()))
|
||||
.optProgress(new ProgressBar())
|
||||
.build();
|
||||
```
|
||||
|
||||
2. How to load a model locally?
|
||||
```text
|
||||
# Use optModelPath to load a model from a zipped file
|
||||
Path modelPath = Paths.get("src/test/resources/ch_ppocr_mobile_v2.0_det_infer.zip");
|
||||
Criteria<Image, DetectedObjects> criteria =
|
||||
Criteria.builder()
|
||||
.optEngine("PaddlePaddle")
|
||||
.setTypes(Image.class, DetectedObjects.class)
|
||||
.optModelPath(modelPath)
|
||||
.optTranslator(new PpWordDetectionTranslator(new ConcurrentHashMap<String, String>()))
|
||||
.optProgress(new ProgressBar())
|
||||
.build();
|
||||
|
||||
# Use optModelPath to load a model from a local directory
|
||||
Path modelPath = Paths.get("src/test/resources/ch_ppocr_mobile_v2.0_det_infer/");
|
||||
Criteria<Image, DetectedObjects> criteria =
|
||||
Criteria.builder()
|
||||
.optEngine("PaddlePaddle")
|
||||
.setTypes(Image.class, DetectedObjects.class)
|
||||
.optModelPath(modelPath)
|
||||
.optTranslator(new PpWordDetectionTranslator(new ConcurrentHashMap<String, String>()))
|
||||
.optProgress(new ProgressBar())
|
||||
.build();
|
||||
```
|
||||
|
||||
3. How to load a model packed into a JAR file?
|
||||
```text
|
||||
# Use optModelUrls to load a model
|
||||
# Assuming the model is located in the JAR file at:
|
||||
# BOOT-INF/classes/ch_ppocr_mobile_v2.0_det_infer.zip
|
||||
|
||||
Criteria<Image, DetectedObjects> criteria =
|
||||
Criteria.builder()
|
||||
.optEngine("PaddlePaddle")
|
||||
.setTypes(Image.class, DetectedObjects.class)
|
||||
.optModelUrls("jar:///ch_ppocr_mobile_v2.0_det_infer.zip")
|
||||
.optTranslator(new PpWordDetectionTranslator(new ConcurrentHashMap<String, String>()))
|
||||
.optProgress(new ProgressBar())
|
||||
.build();
|
||||
```
|
||||
|
||||
|
@ -1,112 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one
|
||||
~ or more contributor license agreements. See the NOTICE file
|
||||
~ distributed with this work for additional information
|
||||
~ regarding copyright ownership. The ASF licenses this file
|
||||
~ to you under the Apache License, Version 2.0 (the
|
||||
~ "License"); you may not use this file except in compliance
|
||||
~ with the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing,
|
||||
~ software distributed under the License is distributed on an
|
||||
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
~ KIND, either express or implied. See the License for the
|
||||
~ specific language governing permissions and limitations
|
||||
~ under the License.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>aias</groupId>
|
||||
<artifactId>face-feature-sdk</artifactId>
|
||||
<version>0.17.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<djl.version>0.17.0</djl.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
<version>3.8.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>2.17.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
</dependency>
|
||||
<!-- 服务器端推理引擎 -->
|
||||
<dependency>
|
||||
<groupId>ai.djl</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>${djl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ai.djl</groupId>
|
||||
<artifactId>basicdataset</artifactId>
|
||||
<version>${djl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ai.djl</groupId>
|
||||
<artifactId>model-zoo</artifactId>
|
||||
<version>${djl.version}</version>
|
||||
</dependency>
|
||||
<!-- Pytorch -->
|
||||
<dependency>
|
||||
<groupId>ai.djl.pytorch</groupId>
|
||||
<artifactId>pytorch-engine</artifactId>
|
||||
<version>${djl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ai.djl.pytorch</groupId>
|
||||
<artifactId>pytorch-model-zoo</artifactId>
|
||||
<version>${djl.version}</version>
|
||||
</dependency>
|
||||
<!-- PaddlePaddle -->
|
||||
<dependency>
|
||||
<groupId>ai.djl.paddlepaddle</groupId>
|
||||
<artifactId>paddlepaddle-model-zoo</artifactId>
|
||||
<version>${djl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ai.djl.paddlepaddle</groupId>
|
||||
<artifactId>paddlepaddle-engine</artifactId>
|
||||
<version>${djl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>6.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -1,59 +0,0 @@
|
||||
package me.aias;
|
||||
|
||||
import ai.djl.ModelException;
|
||||
import ai.djl.inference.Predictor;
|
||||
import ai.djl.modality.cv.Image;
|
||||
import ai.djl.modality.cv.ImageFactory;
|
||||
import ai.djl.repository.zoo.ModelZoo;
|
||||
import ai.djl.repository.zoo.ZooModel;
|
||||
import ai.djl.translate.TranslateException;
|
||||
import me.aias.util.FaceFeature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 人脸比对 - 1:1.
|
||||
* Face feature comparison - 1:1.
|
||||
*
|
||||
* @author Calvin
|
||||
* @email 179209347@qq.com
|
||||
* @website www.aias.top
|
||||
*/
|
||||
public final class FeatureComparisonExample {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FeatureComparisonExample.class);
|
||||
|
||||
private FeatureComparisonExample() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException, ModelException, TranslateException {
|
||||
|
||||
Path imageFile1 = Paths.get("src/test/resources/kana1.png");
|
||||
Image img1 = ImageFactory.getInstance().fromFile(imageFile1);
|
||||
Path imageFile2 = Paths.get("src/test/resources/kana2.png");
|
||||
Image img2 = ImageFactory.getInstance().fromFile(imageFile2);
|
||||
Path imageFile3 = Paths.get("src/test/resources/beauty1.png");
|
||||
Image img3 = ImageFactory.getInstance().fromFile(imageFile3);
|
||||
|
||||
FaceFeature faceFeature = new FaceFeature();
|
||||
try (ZooModel<Image, float[]> model = ModelZoo.loadModel(faceFeature.criteria());
|
||||
Predictor<Image, float[]> predictor = model.newPredictor()) {
|
||||
|
||||
float[] feature1 = predictor.predict(img1);
|
||||
logger.info("face1 feature: " + Arrays.toString(feature1));
|
||||
float[] feature2 = predictor.predict(img2);
|
||||
logger.info("face2 feature: " + Arrays.toString(feature2));
|
||||
float[] feature3 = predictor.predict(img3);
|
||||
logger.info("face3 feature: " + Arrays.toString(feature3));
|
||||
|
||||
logger.info("kana1 - kana2 Similarity: "+ Float.toString(faceFeature.calculSimilar(feature1, feature2)));
|
||||
logger.info("kana1 - beauty1 Similarity: "+ Float.toString(faceFeature.calculSimilar(feature1, feature3)));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package me.aias;
|
||||
|
||||
import ai.djl.ModelException;
|
||||
import ai.djl.inference.Predictor;
|
||||
import ai.djl.modality.cv.Image;
|
||||
import ai.djl.modality.cv.ImageFactory;
|
||||
import ai.djl.repository.zoo.ModelZoo;
|
||||
import ai.djl.repository.zoo.ZooModel;
|
||||
import ai.djl.translate.TranslateException;
|
||||
import me.aias.util.FaceFeature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 人脸特征提取
|
||||
* Face feature extraction
|
||||
*
|
||||
* @author Calvin
|
||||
* @email 179209347@qq.com
|
||||
* @website www.aias.top
|
||||
*/
|
||||
public final class FeatureExtractionExample {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FeatureExtractionExample.class);
|
||||
|
||||
private FeatureExtractionExample() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException, ModelException, TranslateException {
|
||||
Path imageFile = Paths.get("src/test/resources/kana1.png");
|
||||
Image img = ImageFactory.getInstance().fromFile(imageFile);
|
||||
|
||||
FaceFeature faceFeature = new FaceFeature();
|
||||
try (ZooModel<Image, float[]> model = ModelZoo.loadModel(faceFeature.criteria());
|
||||
Predictor<Image, float[]> predictor = model.newPredictor()) {
|
||||
float[] feature = predictor.predict(img);
|
||||
if (feature != null) {
|
||||
logger.info("Face feature: " + Arrays.toString(feature));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package me.aias.util;
|
||||
|
||||
import ai.djl.modality.cv.Image;
|
||||
import ai.djl.repository.zoo.Criteria;
|
||||
import ai.djl.training.util.ProgressBar;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
/**
|
||||
*
|
||||
* @author Calvin
|
||||
*
|
||||
* @email 179209347@qq.com
|
||||
**/
|
||||
public final class FaceFeature {
|
||||
|
||||
public FaceFeature() {
|
||||
}
|
||||
|
||||
public Criteria<Image, float[]> criteria() {
|
||||
Criteria<Image, float[]> criteria =
|
||||
Criteria.builder()
|
||||
.optEngine("PaddlePaddle")
|
||||
.setTypes(Image.class, float[].class)
|
||||
.optModelPath(Paths.get("models/MobileFace.zip"))
|
||||
.optModelName("inference")
|
||||
.optTranslator(new FaceFeatureTranslator())
|
||||
.optProgress(new ProgressBar())
|
||||
.build();
|
||||
|
||||
return criteria;
|
||||
}
|
||||
|
||||
public float calculSimilar(float[] feature1, float[] feature2) {
|
||||
float ret = 0.0f;
|
||||
float mod1 = 0.0f;
|
||||
float mod2 = 0.0f;
|
||||
int length = feature1.length;
|
||||
for (int i = 0; i < length; ++i) {
|
||||
ret += feature1[i] * feature2[i];
|
||||
mod1 += feature1[i] * feature1[i];
|
||||
mod2 += feature2[i] * feature2[i];
|
||||
}
|
||||
return (float) ((ret / Math.sqrt(mod1) / Math.sqrt(mod2)));
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
package me.aias.util;
|
||||
|
||||
import ai.djl.modality.cv.Image;
|
||||
import ai.djl.modality.cv.transform.Normalize;
|
||||
import ai.djl.modality.cv.transform.ToTensor;
|
||||
import ai.djl.modality.cv.util.NDImageUtils;
|
||||
import ai.djl.ndarray.NDArray;
|
||||
import ai.djl.ndarray.NDList;
|
||||
import ai.djl.ndarray.types.DataType;
|
||||
import ai.djl.ndarray.types.Shape;
|
||||
import ai.djl.translate.Batchifier;
|
||||
import ai.djl.translate.Pipeline;
|
||||
import ai.djl.translate.Translator;
|
||||
import ai.djl.translate.TranslatorContext;
|
||||
/**
|
||||
*
|
||||
* @author Calvin
|
||||
*
|
||||
* @email 179209347@qq.com
|
||||
**/
|
||||
public final class FaceFeatureTranslator implements Translator<Image, float[]> {
|
||||
|
||||
public FaceFeatureTranslator() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public NDList processInput(TranslatorContext ctx, Image input) {
|
||||
NDArray array = input.toNDArray(ctx.getNDManager(), Image.Flag.COLOR);
|
||||
|
||||
// float percent = 128f / Math.min(input.getWidth(), input.getHeight());
|
||||
// int resizedWidth = Math.round(input.getWidth() * percent);
|
||||
// int resizedHeight = Math.round(input.getHeight() * percent);
|
||||
// img = img.resize((resizedWidth, resizedHeight), Image.LANCZOS)
|
||||
|
||||
// array = NDImageUtils.resize(array,resizedWidth,resizedHeight);
|
||||
// array = NDImageUtils.centerCrop(array,112,112);
|
||||
array = NDImageUtils.resize(array, 112, 112);
|
||||
|
||||
// The network by default takes float32
|
||||
if (!array.getDataType().equals(DataType.FLOAT32)) {
|
||||
array = array.toType(DataType.FLOAT32, false);
|
||||
}
|
||||
|
||||
array = array.transpose(2, 0, 1).div(255f); // HWC -> CHW RGB
|
||||
|
||||
NDArray mean =
|
||||
ctx.getNDManager().create(new float[]{0.5f, 0.5f, 0.5f}, new Shape(3, 1, 1));
|
||||
NDArray std =
|
||||
ctx.getNDManager().create(new float[]{0.5f, 0.5f, 0.5f}, new Shape(3, 1, 1));
|
||||
|
||||
array = array.sub(mean);
|
||||
array = array.div(std);
|
||||
|
||||
// array = array.expandDims(0);
|
||||
|
||||
return new NDList(array);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] processOutput(TranslatorContext ctx, NDList list) {
|
||||
NDList result = new NDList();
|
||||
long numOutputs = list.singletonOrThrow().getShape().get(0);
|
||||
for (int i = 0; i < numOutputs; i++) {
|
||||
result.add(list.singletonOrThrow().get(i));
|
||||
}
|
||||
float[][] embeddings = result.stream().map(NDArray::toFloatArray).toArray(float[][]::new);
|
||||
float[] feature = new float[embeddings.length];
|
||||
for (int i = 0; i < embeddings.length; i++) {
|
||||
feature[i] = embeddings[i][0];
|
||||
}
|
||||
return feature;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Batchifier getBatchifier() {
|
||||
return Batchifier.STACK;
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="INFO">
|
||||
<Appenders>
|
||||
<Console name="console" target="SYSTEM_OUT">
|
||||
<PatternLayout
|
||||
pattern="[%-5level] - %msg%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="info" additivity="false">
|
||||
<AppenderRef ref="console"/>
|
||||
</Root>
|
||||
<Logger name="me.calvin" level="${sys:me.calvin.logging.level:-info}" additivity="false">
|
||||
<AppenderRef ref="console"/>
|
||||
</Logger>
|
||||
</Loggers>
|
||||
</Configuration>
|
Before Width: | Height: | Size: 246 KiB |
Before Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 222 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 395 KiB |
Before Width: | Height: | Size: 463 KiB |