mirror of
https://github.com/geekwenjie/SmartJavaAI.git
synced 2026-09-12 12:48:57 +00:00
临时提交
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<smartjavaai.version>1.0.23</smartjavaai.version>
|
||||
<smartjavaai.version>1.0.24</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.face.facedet.FaceDetDemo</exec.mainClass>
|
||||
|
||||
@@ -255,6 +255,14 @@
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ai.djl.pytorch</groupId>
|
||||
<artifactId>pytorch-native-cpu</artifactId>
|
||||
<classifier>linux-aarch64</classifier>
|
||||
<scope>runtime</scope>
|
||||
<version>2.5.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
|
||||
* with the License. A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0/
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file 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.
|
||||
*/
|
||||
package smartai.examples.face;
|
||||
|
||||
import ai.djl.ModelException;
|
||||
import ai.djl.inference.Predictor;
|
||||
import ai.djl.modality.Classifications;
|
||||
import ai.djl.modality.Input;
|
||||
import ai.djl.modality.Output;
|
||||
import ai.djl.modality.cv.Image;
|
||||
import ai.djl.ndarray.NDList;
|
||||
import ai.djl.repository.zoo.Criteria;
|
||||
import ai.djl.repository.zoo.ZooModel;
|
||||
import ai.djl.translate.NoBatchifyTranslator;
|
||||
import ai.djl.translate.TranslateException;
|
||||
import ai.djl.translate.TranslatorContext;
|
||||
import ai.djl.util.JsonUtils;
|
||||
import ai.djl.util.Utils;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PythonTranslator implements NoBatchifyTranslator<byte[], Classifications> {
|
||||
|
||||
private ZooModel<Input, Output> model;
|
||||
private Predictor<Input, Output> predictor;
|
||||
|
||||
@Override
|
||||
public void prepare(TranslatorContext ctx) throws ModelException, IOException {
|
||||
if (predictor == null) {
|
||||
Criteria<Input, Output> criteria =
|
||||
Criteria.builder()
|
||||
.setTypes(Input.class, Output.class)
|
||||
.optModelPath(Paths.get("src/test/python"))
|
||||
.optEngine("Python")
|
||||
.build();
|
||||
model = criteria.loadModel();
|
||||
predictor = model.newPredictor();
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public NDList processInput(TranslatorContext ctx, String url)
|
||||
// throws IOException, TranslateException {
|
||||
// Input input = new Input();
|
||||
// try (InputStream is = new URL(url).openStream()) {
|
||||
// input.add("data", Utils.toByteArray(is));
|
||||
// }
|
||||
// input.addProperty("Content-Type", "image/jpeg");
|
||||
// // calling preprocess() function in model.py
|
||||
// input.addProperty("handler", "preprocess");
|
||||
// Output output = predictor.predict(input);
|
||||
// if (output.getCode() != 200) {
|
||||
// throw new TranslateException("Python preprocess() failed: " + output.getMessage());
|
||||
// }
|
||||
//
|
||||
// return output.getDataAsNDList(ctx.getNDManager());
|
||||
// }
|
||||
|
||||
@Override
|
||||
public NDList processInput(TranslatorContext ctx, byte[] image)
|
||||
throws IOException, TranslateException {
|
||||
Input input = new Input();
|
||||
input.add("data", image);
|
||||
input.addProperty("Content-Type", "image/jpeg");
|
||||
// calling preprocess() function in model.py
|
||||
input.addProperty("handler", "preprocess");
|
||||
Output output = predictor.predict(input);
|
||||
if (output.getCode() != 200) {
|
||||
throw new TranslateException("Python preprocess() failed: " + output.getMessage());
|
||||
}
|
||||
return output.getDataAsNDList(ctx.getNDManager());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Classifications processOutput(TranslatorContext ctx, NDList list)
|
||||
throws TranslateException {
|
||||
Input input = new Input();
|
||||
input.add("data", list);
|
||||
// calling postprocess() function in processing.py
|
||||
input.addProperty("handler", "postprocess");
|
||||
Output output = predictor.predict(input);
|
||||
if (output.getCode() != 200) {
|
||||
throw new TranslateException("Python postprocess() failed: " + output.getMessage());
|
||||
}
|
||||
|
||||
String json = output.getData().getAsString();
|
||||
System.out.println("json:" + json);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (predictor != null) {
|
||||
predictor.close();
|
||||
model.close();
|
||||
predictor = null;
|
||||
model = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package smartai.examples.face;
|
||||
|
||||
import ai.djl.Application;
|
||||
import ai.djl.Device;
|
||||
import ai.djl.MalformedModelException;
|
||||
import ai.djl.inference.Predictor;
|
||||
import ai.djl.modality.Classifications;
|
||||
import ai.djl.modality.audio.Audio;
|
||||
import ai.djl.modality.audio.AudioFactory;
|
||||
import ai.djl.modality.audio.translator.SpeechRecognitionTranslatorFactory;
|
||||
import ai.djl.repository.Artifact;
|
||||
import ai.djl.repository.MRL;
|
||||
import ai.djl.repository.zoo.Criteria;
|
||||
import ai.djl.repository.zoo.ModelNotFoundException;
|
||||
import ai.djl.repository.zoo.ModelZoo;
|
||||
import ai.djl.repository.zoo.ZooModel;
|
||||
import ai.djl.translate.TranslateException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author dwj
|
||||
* @date 2025/7/29
|
||||
*/
|
||||
@Slf4j
|
||||
public class Test {
|
||||
|
||||
public static void main(String[] args) throws ModelNotFoundException, MalformedModelException, IOException, TranslateException {
|
||||
// PythonTranslator translator = new PythonTranslator();
|
||||
// Criteria<byte[], Classifications> criteria =
|
||||
// Criteria.builder()
|
||||
// .setTypes(byte[].class, Classifications.class)
|
||||
// .optModelPath(Paths.get("/Users/wenjie/Documents/develop/model/arcfaceresnet100-11-int8.onnx"))
|
||||
// .optEngine("OnnxRuntime")
|
||||
// .optTranslator(translator)
|
||||
// .build();
|
||||
// String path = "/Users/wenjie/Downloads/facetest/jsy.jpg";
|
||||
// try (ZooModel<byte[], Classifications> model = criteria.loadModel();
|
||||
// Predictor<byte[], Classifications> predictor = model.newPredictor()) {
|
||||
// byte[] data = Files.readAllBytes(Paths.get(path));
|
||||
// Classifications ret = predictor.predict(data);
|
||||
// System.out.println(ret);
|
||||
// }
|
||||
//
|
||||
// // unload python model
|
||||
// translator.close();
|
||||
|
||||
|
||||
// Load model.
|
||||
// Wav2Vec2 model is a speech model that accepts a float array corresponding to the raw
|
||||
// waveform of the speech signal.
|
||||
|
||||
// String url = "/Users/wenjie/Downloads/20210601_u2++_conformer_exp/final.pt";
|
||||
// Criteria<Audio, String> criteria =
|
||||
// Criteria.builder()
|
||||
// .setTypes(Audio.class, String.class)
|
||||
//// .optModelUrls(url)
|
||||
// .optModelPath(Paths.get(url))
|
||||
// .optDevice(Device.cpu()) // torchscript model only support CPU
|
||||
// .optTranslatorFactory(new SpeechRecognitionTranslatorFactory())
|
||||
//// .optModelName("data.pkl")
|
||||
// .optEngine("PyTorch")
|
||||
// .build();
|
||||
//
|
||||
// // Read in audio file
|
||||
// String wave = "https://resources.djl.ai/audios/speech.wav";
|
||||
// Audio audio = AudioFactory.newInstance().fromUrl(wave);
|
||||
// try (ZooModel<Audio, String> model = criteria.loadModel();
|
||||
// Predictor<Audio, String> predictor = model.newPredictor()) {
|
||||
// String result = predictor.predict(audio);
|
||||
// log.info("Result: {}", result);
|
||||
// }
|
||||
|
||||
boolean withArtifacts =
|
||||
args.length > 0 && ("--artifact".equals(args[0]) || "-a".equals(args[0]));
|
||||
if (!withArtifacts) {
|
||||
log.info("============================================================");
|
||||
log.info("user ./gradlew listModel --args='-a' to show artifact detail");
|
||||
log.info("============================================================");
|
||||
}
|
||||
Map<Application, List<Artifact>> models = ModelZoo.listModels();
|
||||
for (Map.Entry<Application, List<Artifact>> entry : models.entrySet()) {
|
||||
String appName = entry.getKey().toString();
|
||||
for (Artifact artifact : entry.getValue()) {
|
||||
if (withArtifacts) {
|
||||
log.info("{} djl://{}", appName, artifact);
|
||||
} else {
|
||||
log.info("{} {}", appName, artifact);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public class FaceDetDemo {
|
||||
//高精度模型,速度慢
|
||||
config.setModelEnum(FaceDetModelEnum.RETINA_FACE);//人脸检测模型
|
||||
//下载模型并替换本地路径,下载地址:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/xxx/Documents/develop/model/retinaface.pt");
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/face_model/retinaface.pt");
|
||||
config.setConfidenceThreshold(FaceDetectConstant.DEFAULT_CONFIDENCE_THRESHOLD);//只返回相似度大于该值的人脸
|
||||
config.setNmsThresh(FaceDetectConstant.NMS_THRESHOLD);//用于去除重复的人脸框,当两个框的重叠度超过该值时,只保留一个
|
||||
return FaceDetModelFactory.getInstance().getModel(config);
|
||||
@@ -95,12 +95,21 @@ public class FaceDetDemo {
|
||||
@Test
|
||||
public void testFaceDetect(){
|
||||
try {
|
||||
FaceDetModel faceModel = FaceDetModelFactory.getInstance().getModel();
|
||||
FaceDetModel faceModel = getFaceDetModel();
|
||||
R<DetectionResponse> detectedResult = faceModel.detect(imgPath);
|
||||
if(detectedResult.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectedResult.getData()));
|
||||
// if(detectedResult.isSuccess()){
|
||||
// log.info("人脸检测结果:{}", JSONObject.toJSONString(detectedResult.getData()));
|
||||
// }else{
|
||||
// log.info("人脸检测失败:{}", detectedResult.getMessage());
|
||||
// }
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
R<DetectionResponse> detectedResult2 = faceModel.detect("/Users/wenjie/Downloads/facetest/surprise.png");
|
||||
log.info("耗时:{}", System.currentTimeMillis() - start);
|
||||
if(detectedResult2.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectedResult2.getData()));
|
||||
}else{
|
||||
log.info("人脸检测失败:{}", detectedResult.getMessage());
|
||||
log.info("人脸检测失败:{}", detectedResult2.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -63,7 +63,7 @@ public class FaceRecDemo {
|
||||
//高精度模型,速度慢
|
||||
config.setModelEnum(FaceDetModelEnum.RETINA_FACE);//人脸检测模型
|
||||
//下载模型并替换本地路径,下载地址:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/xxx/Documents/develop/model/retinaface.pt");
|
||||
// config.setModelPath("/Users/wenjie/Documents/develop/model/retinaface.pt");
|
||||
config.setConfidenceThreshold(FaceDetectConstant.DEFAULT_CONFIDENCE_THRESHOLD);//只返回相似度大于该值的人脸
|
||||
config.setNmsThresh(FaceDetectConstant.NMS_THRESHOLD);//用于去除重复的人脸框,当两个框的重叠度超过该值时,只保留一个
|
||||
config.setDevice(device);
|
||||
@@ -170,7 +170,7 @@ public class FaceRecDemo {
|
||||
FaceRecConfig config = new FaceRecConfig();
|
||||
//高精度模型,速度慢, 追求速度请更换高速模型,具体其他模型参数可以查看文档:http://doc.smartjavaai.cn/face.html
|
||||
config.setModelEnum(FaceRecModelEnum.ELASTIC_FACE_MODEL);//人脸检测模型
|
||||
config.setModelPath("/Users/xxx/Documents/develop/model/elasticface.pt");
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/elasticface.pt");
|
||||
//裁剪人脸:如果图片已经是裁剪过的,则请将此参数设置为false
|
||||
config.setCropFace(true);
|
||||
//开启人脸对齐:适用于人脸不正的场景,开启将提升人脸特征准确度,关闭可以提升性能
|
||||
|
||||
126
examples/face-example/src/test/python/model.py
Normal file
126
examples/face-example/src/test/python/model.py
Normal file
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file
|
||||
# except in compliance with the License. A copy of the License is located at
|
||||
#
|
||||
# http://aws.amazon.com/apache2.0/
|
||||
#
|
||||
# or in the "LICENSE.txt" file accompanying this file. This file is distributed on an "AS IS"
|
||||
# BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the License for
|
||||
# the specific language governing permissions and limitations under the License.
|
||||
"""
|
||||
PyTorch resnet18 pre/post processing example.
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from typing import Optional, Any
|
||||
import sklearn
|
||||
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
from torchvision import transforms
|
||||
|
||||
from djl_python import Input
|
||||
from djl_python import Output
|
||||
|
||||
|
||||
class Processing(object):
|
||||
|
||||
def __init__(self):
|
||||
self.topK = 5
|
||||
self.image_processing = None
|
||||
self.mapping = None
|
||||
self.initialized = False
|
||||
|
||||
def initialize(self, properties: dict):
|
||||
"""
|
||||
Initialize model.
|
||||
"""
|
||||
self.image_processing = transforms.Compose([
|
||||
transforms.Resize(112),
|
||||
transforms.CenterCrop(112),
|
||||
transforms.ToTensor(),
|
||||
transforms.Normalize(mean=[0.485, 0.456, 0.406],
|
||||
std=[0.229, 0.224, 0.225])
|
||||
])
|
||||
#self.mapping = self.load_label_mapping("index_to_name.json")
|
||||
self.initialized = True
|
||||
|
||||
def preprocess(self, inputs: Input) -> Output:
|
||||
outputs = Output()
|
||||
try:
|
||||
batch = inputs.get_batches()
|
||||
images = []
|
||||
for i, item in enumerate(batch):
|
||||
image = self.image_processing(item.get_as_image())
|
||||
images.append(image)
|
||||
images = torch.stack(images)
|
||||
outputs.add_as_numpy(images.detach().numpy())
|
||||
outputs.add_property("content-type", "tensor/ndlist")
|
||||
except Exception as e:
|
||||
logging.exception("pre-process failed")
|
||||
# error handling
|
||||
outputs = Output().error(str(e))
|
||||
|
||||
return outputs
|
||||
|
||||
def postprocess(self, inputs: Input) -> Output:
|
||||
outputs = Output()
|
||||
try:
|
||||
data = inputs.get_as_numpy(0)[0]
|
||||
item = torch.from_numpy(data)
|
||||
print("data shape:", item.shape)
|
||||
embedding = sklearn.preprocessing.normalize(item).flatten()
|
||||
outputs.add(embedding)
|
||||
except Exception as e:
|
||||
logging.exception("post-process failed")
|
||||
# error handling
|
||||
outputs = Output().error(str(e))
|
||||
|
||||
return outputs
|
||||
|
||||
@staticmethod
|
||||
def load_label_mapping(mapping_file_path: Any) -> dict:
|
||||
if not os.path.isfile(mapping_file_path):
|
||||
raise Exception('mapping file not found: ' + mapping_file_path)
|
||||
|
||||
with open(mapping_file_path) as f:
|
||||
mapping = json.load(f)
|
||||
if not isinstance(mapping, dict):
|
||||
raise Exception('mapping file should be in "class":"label" format')
|
||||
|
||||
for key, value in mapping.items():
|
||||
new_value = value
|
||||
if isinstance(new_value, list):
|
||||
new_value = value[-1]
|
||||
if not isinstance(new_value, str):
|
||||
raise Exception(
|
||||
'labels in mapping must be either str or [str]')
|
||||
mapping[key] = new_value
|
||||
return mapping
|
||||
|
||||
|
||||
_service = Processing()
|
||||
|
||||
|
||||
def preprocess(inputs: Input) -> Output:
|
||||
return _service.preprocess(inputs)
|
||||
|
||||
|
||||
def postprocess(inputs: Input) -> Output:
|
||||
return _service.postprocess(inputs)
|
||||
|
||||
|
||||
def handle(inputs: Input) -> Optional[Output]:
|
||||
"""
|
||||
Default handler function
|
||||
"""
|
||||
if not _service.initialized:
|
||||
# stateful model
|
||||
_service.initialize(inputs.get_properties())
|
||||
|
||||
return None
|
||||
Reference in New Issue
Block a user