mirror of
https://github.com/geekwenjie/SmartJavaAI.git
synced 2026-09-18 16:39:21 +00:00
【人脸识别】 新增多种人脸识别模型
【底层优化】 支持自由选择 OpenCV 或 BufferedImage 作为图像引擎 【通用图像】 全部模型启用 Image 输入,支持各类图片格式与 Image 的互转 【模型管理】 优化模型生命周期,关闭后可重新创建 【人脸识别】 支持在人脸查询结果中绘制姓名标注 【人脸检测】 新增人脸裁剪功能 【修复】 修复若干已知问题,提升系统稳定性
This commit is contained in:
@@ -4,22 +4,20 @@ import ai.djl.MalformedModelException;
|
||||
import ai.djl.engine.Engine;
|
||||
import ai.djl.inference.Predictor;
|
||||
import ai.djl.modality.cv.Image;
|
||||
import ai.djl.modality.cv.ImageFactory;
|
||||
import ai.djl.modality.cv.output.BoundingBox;
|
||||
import ai.djl.modality.cv.output.DetectedObjects;
|
||||
import ai.djl.repository.zoo.Criteria;
|
||||
import ai.djl.repository.zoo.ModelNotFoundException;
|
||||
import ai.djl.repository.zoo.ZooModel;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
import cn.smartjavaai.common.entity.R;
|
||||
import cn.smartjavaai.common.pool.PredictorFactory;
|
||||
import cn.smartjavaai.common.utils.BufferedImageUtils;
|
||||
import cn.smartjavaai.common.utils.FileUtils;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
import cn.smartjavaai.common.utils.OpenCVUtils;
|
||||
import cn.smartjavaai.objectdetection.config.DetectorModelConfig;
|
||||
import cn.smartjavaai.objectdetection.criteria.CriteriaBuilderFactory;
|
||||
import cn.smartjavaai.objectdetection.exception.DetectionException;
|
||||
import cn.smartjavaai.vision.utils.CategoryMaskFilter;
|
||||
import cn.smartjavaai.vision.utils.DetectedObjectsFilter;
|
||||
import cn.smartjavaai.vision.utils.DetectorUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -31,8 +29,6 @@ import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -86,23 +82,21 @@ public class DetectorModel implements AutoCloseable{
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
public DetectionResponse detect(String imagePath){
|
||||
if(!FileUtils.isFileExists(imagePath)){
|
||||
throw new DetectionException("图像文件不存在");
|
||||
}
|
||||
Image image = null;
|
||||
try {
|
||||
image = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
|
||||
DetectedObjects detectedObjects = detect(image);
|
||||
image = SmartImageFactory.getInstance().fromFile(Paths.get(imagePath));
|
||||
DetectedObjects detectedObjects = detectCore(image);
|
||||
return DetectorUtils.convertToDetectionResponse(detectedObjects, image);
|
||||
} catch (Exception e) {
|
||||
throw new DetectionException(e);
|
||||
} finally {
|
||||
if (image != null){
|
||||
((Mat)image.getWrappedImage()).release();
|
||||
}
|
||||
ImageUtils.releaseOpenCVMat(image);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -117,8 +111,8 @@ public class DetectorModel implements AutoCloseable{
|
||||
}
|
||||
Image img = null;
|
||||
try {
|
||||
img = ImageFactory.getInstance().fromFile(Paths.get(imagePath));
|
||||
DetectedObjects detectedObjects = detect(img);
|
||||
img = SmartImageFactory.getInstance().fromFile(Paths.get(imagePath));
|
||||
DetectedObjects detectedObjects = detectCore(img);
|
||||
if(Objects.isNull(detectedObjects) || detectedObjects.getNumberOfObjects() == 0){
|
||||
throw new DetectionException("未检测到图片中的物体");
|
||||
}
|
||||
@@ -129,9 +123,7 @@ public class DetectorModel implements AutoCloseable{
|
||||
} catch (IOException e) {
|
||||
throw new DetectionException(e);
|
||||
} finally {
|
||||
if (img != null){
|
||||
((Mat)img.getWrappedImage()).release();
|
||||
}
|
||||
ImageUtils.releaseOpenCVMat(img);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +132,7 @@ public class DetectorModel implements AutoCloseable{
|
||||
* @param imageData
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public DetectionResponse detect(byte[] imageData){
|
||||
if(Objects.isNull(imageData)){
|
||||
throw new DetectionException("图像无效");
|
||||
@@ -159,21 +152,20 @@ public class DetectorModel implements AutoCloseable{
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public DetectionResponse detect(BufferedImage image){
|
||||
if(!ImageUtils.isImageValid(image)){
|
||||
if(!BufferedImageUtils.isImageValid(image)){
|
||||
throw new DetectionException("图像无效");
|
||||
}
|
||||
Image img = null;
|
||||
try {
|
||||
img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(image));
|
||||
DetectedObjects detectedObjects = detect(img);
|
||||
img = SmartImageFactory.getInstance().fromBufferedImage(image);
|
||||
DetectedObjects detectedObjects = detectCore(img);
|
||||
return DetectorUtils.convertToDetectionResponse(detectedObjects, img);
|
||||
} catch (Exception e) {
|
||||
throw new DetectionException(e);
|
||||
} finally {
|
||||
if (img != null) {
|
||||
((Mat)img.getWrappedImage()).release();
|
||||
}
|
||||
ImageUtils.releaseOpenCVMat(img);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -183,30 +175,20 @@ public class DetectorModel implements AutoCloseable{
|
||||
* @param sourceImage
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public BufferedImage detectAndDraw(BufferedImage sourceImage){
|
||||
if(!ImageUtils.isImageValid(sourceImage)){
|
||||
if(!BufferedImageUtils.isImageValid(sourceImage)){
|
||||
throw new DetectionException("图像无效");
|
||||
}
|
||||
Image img = ImageFactory.getInstance().fromImage(OpenCVUtils.image2Mat(sourceImage));
|
||||
DetectedObjects detectedObjects = detect(img);
|
||||
Image img = SmartImageFactory.getInstance().fromBufferedImage(sourceImage);
|
||||
DetectedObjects detectedObjects = detectCore(img);
|
||||
if(Objects.isNull(detectedObjects) || detectedObjects.getNumberOfObjects() == 0){
|
||||
throw new DetectionException("未检测到图片中的物体");
|
||||
}
|
||||
img.drawBoundingBoxes(detectedObjects);
|
||||
try {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
// 调用 save 方法将 Image 写入字节流
|
||||
img.save(outputStream, "png");
|
||||
// 将字节流转换为 BufferedImage
|
||||
byte[] imageBytes = outputStream.toByteArray();
|
||||
return ImageIO.read(new ByteArrayInputStream(imageBytes));
|
||||
} catch (IOException e) {
|
||||
throw new DetectionException("导出图片失败", e);
|
||||
} finally {
|
||||
if (img != null) {
|
||||
((Mat)img.getWrappedImage()).release();
|
||||
}
|
||||
}
|
||||
BufferedImage drawnImage = ImageUtils.toBufferedImage(img);
|
||||
ImageUtils.releaseOpenCVMat(img);
|
||||
return drawnImage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,7 +196,35 @@ public class DetectorModel implements AutoCloseable{
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
public DetectedObjects detect(Image image){
|
||||
public DetectionResponse detect(Image image){
|
||||
DetectedObjects detectedObjects = detectCore(image);
|
||||
return DetectorUtils.convertToDetectionResponse(detectedObjects, image);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检测并绘制
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
public DetectionResponse detectAndDraw(Image image){
|
||||
DetectedObjects detectedObjects = detectCore(image);
|
||||
if(Objects.isNull(detectedObjects) || detectedObjects.getNumberOfObjects() == 0){
|
||||
throw new DetectionException("未检测到图片中的物体");
|
||||
}
|
||||
Image img = ImageUtils.copy(image);
|
||||
DetectionResponse detectionResponse = DetectorUtils.convertToDetectionResponse(detectedObjects, img);
|
||||
img.drawBoundingBoxes(detectedObjects);
|
||||
detectionResponse.setDrawnImage(img);
|
||||
return detectionResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 目标检测
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
public DetectedObjects detectCore(Image image){
|
||||
Predictor<Image, DetectedObjects> predictor = null;
|
||||
try {
|
||||
predictor = predictorPool.borrowObject();
|
||||
|
||||
@@ -58,5 +58,8 @@ public interface PersonDetModel extends AutoCloseable{
|
||||
throw new UnsupportedOperationException("默认不支持该功能");
|
||||
}
|
||||
|
||||
default void setFromFactory(boolean fromFactory){
|
||||
throw new UnsupportedOperationException("默认不支持该功能");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import ai.djl.modality.cv.output.Mask;
|
||||
import ai.djl.modality.cv.output.Rectangle;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.*;
|
||||
import cn.smartjavaai.common.enums.VideoSourceType;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
@@ -230,7 +231,7 @@ public class StreamDetector implements AutoCloseable{
|
||||
mat = converterToMat.convert(frame);
|
||||
if (mat == null) return;
|
||||
|
||||
Image image = ImageFactory.getInstance().fromImage(mat);
|
||||
Image image = SmartImageFactory.getInstance().fromMat(mat);
|
||||
DetectedObjects detectedObjects = predictor.predict(image);
|
||||
// log.info("内部检测结果:{}", detectedObjects.toString());
|
||||
DetectionResponse detectionResponse = DetectorUtils.convertToDetectionResponse(detectedObjects, image);
|
||||
|
||||
Reference in New Issue
Block a user