优化人脸检测速度

This commit is contained in:
dengwenjie
2025-03-08 10:47:55 +08:00
parent 4e97688315
commit 12cac51b8a
4 changed files with 59 additions and 35 deletions

View File

@@ -3,6 +3,7 @@ package smartai.examples.face;
import cn.smartjavaai.common.entity.Rectangle; import cn.smartjavaai.common.entity.Rectangle;
import cn.smartjavaai.face.*; import cn.smartjavaai.face.*;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import smartai.examples.utils.ImageUtils; import smartai.examples.utils.ImageUtils;
@@ -28,7 +29,7 @@ public class FaceDemo {
public static void main(String[] args) { public static void main(String[] args) {
try { try {
//detectFace(); //detectFace2();
verifyIDCard(); verifyIDCard();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -42,10 +43,18 @@ public class FaceDemo {
* 应用场景:如监控摄像头、智能安防系统等需要高精度检测的场合 * 应用场景:如监控摄像头、智能安防系统等需要高精度检测的场合
*/ */
public static void detectFace() throws Exception { public static void detectFace() throws Exception {
// 创建并启动计时器
StopWatch sw = StopWatch.createStarted();
//创建人脸算法 //创建人脸算法
FaceAlgorithm currentAlgorithm = FaceAlgorithmFactory.createFaceAlgorithm(); FaceAlgorithm currentAlgorithm = FaceAlgorithmFactory.createFaceAlgorithm();
sw.stop();
logger.info("创建人脸算法耗时:" + sw.getTime() + "ms");
sw.reset();
sw.start();
//使用图片路径检测 //使用图片路径检测
FaceDetectedResult result = currentAlgorithm.detect("src/main/resources/largest_selfie.jpg"); FaceDetectedResult result = currentAlgorithm.detect("src/main/resources/largest_selfie.jpg");
sw.stop();
logger.info("人脸检测耗时:" + sw.getTime() + "ms");
logger.info("人脸检测结果:{}", JSONObject.toJSONString(result)); logger.info("人脸检测结果:{}", JSONObject.toJSONString(result));
//使用图片流检测 //使用图片流检测
File input = new File("src/main/resources/largest_selfie.jpg"); File input = new File("src/main/resources/largest_selfie.jpg");
@@ -66,10 +75,18 @@ public class FaceDemo {
* 应用场景:如监控摄像头、智能安防系统等需要高精度检测的场合 * 应用场景:如监控摄像头、智能安防系统等需要高精度检测的场合
*/ */
public static void detectFace2() throws Exception { public static void detectFace2() throws Exception {
// 创建并启动计时器
StopWatch sw = StopWatch.createStarted();
//创建轻量人脸算法 //创建轻量人脸算法
FaceAlgorithm currentAlgorithm = FaceAlgorithmFactory.createLightFaceAlgorithm(); FaceAlgorithm currentAlgorithm = FaceAlgorithmFactory.createLightFaceAlgorithm();
sw.stop();
logger.info("创建人脸算法耗时:" + sw.getTime() + "ms");
sw.reset();
sw.start();
//使用图片路径检测 //使用图片路径检测
FaceDetectedResult result = currentAlgorithm.detect("src/main/resources/largest_selfie.jpg"); FaceDetectedResult result = currentAlgorithm.detect("src/main/resources/largest_selfie.jpg");
sw.stop();
logger.info("人脸检测耗时:" + sw.getTime() + "ms");
logger.info("轻量人脸检测结果:{}", JSONObject.toJSONString(result)); logger.info("轻量人脸检测结果:{}", JSONObject.toJSONString(result));
//使用图片流检测 //使用图片流检测
//File imageFile = new File("/Users/wenjie/Downloads/djl-master/examples/src/test/resources/largest_selfie.jpg"); //File imageFile = new File("/Users/wenjie/Downloads/djl-master/examples/src/test/resources/largest_selfie.jpg");
@@ -87,10 +104,18 @@ public class FaceDemo {
* @throws Exception * @throws Exception
*/ */
public static void verifyIDCard() throws Exception { public static void verifyIDCard() throws Exception {
// 创建并启动计时器
StopWatch sw = StopWatch.createStarted();
//创建脸算法 //创建脸算法
FaceAlgorithm currentAlgorithm = FaceAlgorithmFactory.createFaceFeatureAlgorithm(); FaceAlgorithm currentAlgorithm = FaceAlgorithmFactory.createFaceFeatureAlgorithm();
sw.stop();
logger.info("创建人脸算法耗时:" + sw.getTime() + "ms");
sw.reset();
sw.start();
//提取身份证人脸特征(图片仅供测试) //提取身份证人脸特征(图片仅供测试)
float[] featureIdCard = currentAlgorithm.featureExtraction("src/main/resources/kana1.jpg"); float[] featureIdCard = currentAlgorithm.featureExtraction("src/main/resources/kana1.jpg");
sw.stop();
logger.info("人脸检测耗时:" + sw.getTime() + "ms");
//提取身份证人脸特征(从图片流获取) //提取身份证人脸特征(从图片流获取)
//File input = new File("src/main/resources/kana1.jpg"); //File input = new File("src/main/resources/kana1.jpg");
//float[] featureIdCard = currentAlgorithm.featureExtraction(new FileInputStream(input)); //float[] featureIdCard = currentAlgorithm.featureExtraction(new FileInputStream(input));

View File

@@ -33,6 +33,10 @@ public class FeatureExtractionAlgo extends AbstractFaceAlgorithm {
private Criteria<Image, float[]> faceFeatureCriteria; private Criteria<Image, float[]> faceFeatureCriteria;
private Predictor<Image, float[]> predictor;
private ZooModel<Image, float[]> model;
public static final List<Float> mean = public static final List<Float> mean =
Arrays.asList( Arrays.asList(
127.5f / 255.0f, 127.5f / 255.0f,
@@ -62,6 +66,8 @@ public class FeatureExtractionAlgo extends AbstractFaceAlgorithm {
.optProgress(new ProgressBar()) .optProgress(new ProgressBar())
.optEngine("PyTorch") // Use PyTorch engine .optEngine("PyTorch") // Use PyTorch engine
.build(); .build();
model = faceFeatureCriteria.loadModel();
predictor = model.newPredictor();
} }
@@ -76,10 +82,7 @@ public class FeatureExtractionAlgo extends AbstractFaceAlgorithm {
Path imageFile = Paths.get(imagePath); Path imageFile = Paths.get(imagePath);
Image img = ImageFactory.getInstance().fromFile(imageFile); Image img = ImageFactory.getInstance().fromFile(imageFile);
img.getWrappedImage(); img.getWrappedImage();
try (ZooModel<Image, float[]> model = faceFeatureCriteria.loadModel()) { return predictor.predict(img);
Predictor<Image, float[]> predictor = model.newPredictor();
return predictor.predict(img);
}
} }
/** /**
@@ -92,10 +95,7 @@ public class FeatureExtractionAlgo extends AbstractFaceAlgorithm {
public float[] featureExtraction(InputStream inputStream) throws Exception { public float[] featureExtraction(InputStream inputStream) throws Exception {
Image img = ImageFactory.getInstance().fromInputStream(inputStream); Image img = ImageFactory.getInstance().fromInputStream(inputStream);
img.getWrappedImage(); img.getWrappedImage();
try (ZooModel<Image, float[]> model = faceFeatureCriteria.loadModel()) { return predictor.predict(img);
Predictor<Image, float[]> predictor = model.newPredictor();
return predictor.predict(img);
}
} }
/** /**

View File

@@ -38,6 +38,10 @@ public class RetinaFace extends AbstractFaceAlgorithm {
private Criteria<Image, float[]> faceFeatureCriteria; private Criteria<Image, float[]> faceFeatureCriteria;
private Predictor<Image, DetectedObjects> predictor;
private ZooModel<Image, DetectedObjects> model;
/** /**
* 特征图层的基础缩放比例 * 特征图层的基础缩放比例
*/ */
@@ -57,7 +61,7 @@ public class RetinaFace extends AbstractFaceAlgorithm {
* @param config * @param config
*/ */
@Override @Override
public void loadModel(ModelConfig config) { public void loadModel(ModelConfig config) throws ModelNotFoundException, MalformedModelException, IOException {
FaceDetectionTranslator translator = FaceDetectionTranslator translator =
new FaceDetectionTranslator(config.getConfidenceThreshold(), config.getNmsThresh(), variance, config.getMaxFaceCount(), scales, steps); new FaceDetectionTranslator(config.getConfidenceThreshold(), config.getNmsThresh(), variance, config.getMaxFaceCount(), scales, steps);
criteria = criteria =
@@ -71,6 +75,8 @@ public class RetinaFace extends AbstractFaceAlgorithm {
.optProgress(new ProgressBar()) .optProgress(new ProgressBar())
.optEngine("PyTorch") // Use PyTorch engine .optEngine("PyTorch") // Use PyTorch engine
.build(); .build();
model = criteria.loadModel();
predictor = model.newPredictor();
} }
@@ -85,11 +91,8 @@ public class RetinaFace extends AbstractFaceAlgorithm {
public FaceDetectedResult detect(String imagePath) throws Exception{ public FaceDetectedResult detect(String imagePath) throws Exception{
Path facePath = Paths.get(imagePath); Path facePath = Paths.get(imagePath);
Image img = ImageFactory.getInstance().fromFile(facePath); Image img = ImageFactory.getInstance().fromFile(facePath);
try (ZooModel<Image, DetectedObjects> model = criteria.loadModel(); DetectedObjects detection = predictor.predict(img);
Predictor<Image, DetectedObjects> predictor = model.newPredictor()) { return convertToFaceDetectedResult(detection,img);
DetectedObjects detection = predictor.predict(img);
return convertToFaceDetectedResult(detection,img);
}
} }
/** /**
@@ -101,13 +104,8 @@ public class RetinaFace extends AbstractFaceAlgorithm {
@Override @Override
public FaceDetectedResult detect(InputStream imageInputStream) throws Exception { public FaceDetectedResult detect(InputStream imageInputStream) throws Exception {
Image img = ImageFactory.getInstance().fromInputStream(imageInputStream); Image img = ImageFactory.getInstance().fromInputStream(imageInputStream);
try (ZooModel<Image, DetectedObjects> model = criteria.loadModel(); DetectedObjects detection = predictor.predict(img);
Predictor<Image, DetectedObjects> predictor = model.newPredictor()) { return convertToFaceDetectedResult(detection,img);
DetectedObjects detection = predictor.predict(img);
return convertToFaceDetectedResult(detection,img);
/*saveBoundingBoxImage(img, detection);
return detection;*/
}
} }
/** /**

View File

@@ -1,17 +1,20 @@
package cn.smartjavaai.face.algo; package cn.smartjavaai.face.algo;
import ai.djl.MalformedModelException;
import ai.djl.inference.Predictor; import ai.djl.inference.Predictor;
import ai.djl.modality.cv.Image; import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.ImageFactory; import ai.djl.modality.cv.ImageFactory;
import ai.djl.modality.cv.output.DetectedObjects; import ai.djl.modality.cv.output.DetectedObjects;
import ai.djl.modality.cv.translator.ImageFeatureExtractorFactory; import ai.djl.modality.cv.translator.ImageFeatureExtractorFactory;
import ai.djl.repository.zoo.Criteria; import ai.djl.repository.zoo.Criteria;
import ai.djl.repository.zoo.ModelNotFoundException;
import ai.djl.repository.zoo.ZooModel; import ai.djl.repository.zoo.ZooModel;
import ai.djl.training.util.ProgressBar; import ai.djl.training.util.ProgressBar;
import cn.smartjavaai.common.entity.Point; import cn.smartjavaai.common.entity.Point;
import cn.smartjavaai.common.entity.Rectangle; import cn.smartjavaai.common.entity.Rectangle;
import cn.smartjavaai.face.*; import cn.smartjavaai.face.*;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@@ -41,6 +44,10 @@ public class UltraLightFastGenericFace extends AbstractFaceAlgorithm {
*/ */
private static final double[] variance = {0.1f, 0.2f}; private static final double[] variance = {0.1f, 0.2f};
private Predictor<Image, DetectedObjects> predictor;
private ZooModel<Image, DetectedObjects> model;
@@ -49,7 +56,7 @@ public class UltraLightFastGenericFace extends AbstractFaceAlgorithm {
* @param config * @param config
*/ */
@Override @Override
public void loadModel(ModelConfig config) { public void loadModel(ModelConfig config) throws ModelNotFoundException, MalformedModelException, IOException {
FaceDetectionTranslator translator = FaceDetectionTranslator translator =
new FaceDetectionTranslator(config.getConfidenceThreshold(), config.getNmsThresh(), variance, config.getMaxFaceCount(), scales, steps); new FaceDetectionTranslator(config.getConfidenceThreshold(), config.getNmsThresh(), variance, config.getMaxFaceCount(), scales, steps);
criteria = criteria =
@@ -60,6 +67,8 @@ public class UltraLightFastGenericFace extends AbstractFaceAlgorithm {
.optProgress(new ProgressBar()) .optProgress(new ProgressBar())
.optEngine("PyTorch") // Use PyTorch engine .optEngine("PyTorch") // Use PyTorch engine
.build(); .build();
model = criteria.loadModel();
predictor = model.newPredictor();
} }
/** /**
@@ -72,11 +81,8 @@ public class UltraLightFastGenericFace extends AbstractFaceAlgorithm {
public FaceDetectedResult detect(String imagePath) throws Exception{ public FaceDetectedResult detect(String imagePath) throws Exception{
Path facePath = Paths.get(imagePath); Path facePath = Paths.get(imagePath);
Image img = ImageFactory.getInstance().fromFile(facePath); Image img = ImageFactory.getInstance().fromFile(facePath);
try (ZooModel<Image, DetectedObjects> model = criteria.loadModel(); DetectedObjects detection = predictor.predict(img);
Predictor<Image, DetectedObjects> predictor = model.newPredictor()) { return convertToFaceDetectedResult(detection,img);
DetectedObjects detection = predictor.predict(img);
return convertToFaceDetectedResult(detection,img);
}
} }
/** /**
@@ -88,13 +94,8 @@ public class UltraLightFastGenericFace extends AbstractFaceAlgorithm {
@Override @Override
public FaceDetectedResult detect(InputStream imageInputStream) throws Exception { public FaceDetectedResult detect(InputStream imageInputStream) throws Exception {
Image img = ImageFactory.getInstance().fromInputStream(imageInputStream); Image img = ImageFactory.getInstance().fromInputStream(imageInputStream);
try (ZooModel<Image, DetectedObjects> model = criteria.loadModel(); DetectedObjects detection = predictor.predict(img);
Predictor<Image, DetectedObjects> predictor = model.newPredictor()) { return convertToFaceDetectedResult(detection,img);
DetectedObjects detection = predictor.predict(img);
return convertToFaceDetectedResult(detection,img);
/*saveBoundingBoxImage(img, detection);
return detection;*/
}
} }
/** /**