【人脸识别】 新增多种人脸识别模型

【底层优化】 支持自由选择 OpenCV 或 BufferedImage 作为图像引擎

【通用图像】 全部模型启用 Image 输入,支持各类图片格式与 Image 的互转

【模型管理】 优化模型生命周期,关闭后可重新创建

【人脸识别】 支持在人脸查询结果中绘制姓名标注

【人脸检测】 新增人脸裁剪功能

【修复】 修复若干已知问题,提升系统稳定性
This commit is contained in:
dengwenjie
2025-10-02 16:26:42 +08:00
parent 1b50e2b943
commit dfa8cf9bb4
133 changed files with 6635 additions and 3532 deletions

View File

@@ -6,11 +6,11 @@
<parent>
<groupId>cn.smartjavaai</groupId>
<artifactId>smartjavaai-parent</artifactId>
<version>1.0.24</version>
<version>1.0.25</version>
</parent>
<artifactId>vision</artifactId>
<version>1.0.24</version>
<version>1.0.25</version>
<name>vision</name>
<description>SmartJavaAI</description>
<url>https://github.com/geekwenjie/SmartJavaAI</url>

View File

@@ -34,4 +34,8 @@ public interface ActionRecModel extends AutoCloseable{
}
default void setFromFactory(boolean fromFactory){
throw new UnsupportedOperationException("默认不支持该功能");
}
}

View File

@@ -76,6 +76,7 @@ public class ActionRecModelFactory {
throw new DetectionException(e);
}
model.loadModel(config);
model.setFromFactory(true);
return model;
}
@@ -90,14 +91,6 @@ public class ActionRecModelFactory {
}
/**
* 移除缓存的模型
* @param modelEnum
*/
public static void removeFromCache(ActionRecModelEnum modelEnum) {
modelMap.remove(modelEnum);
}
// 初始化默认算法
static {
@@ -107,5 +100,27 @@ public class ActionRecModelFactory {
registerAlgorithm(ActionRecModelEnum.VIT_BASE_PATCH16_224_DJL, CommonActionRecModel.class);
log.debug("缓存目录:{}", Config.getCachePath());
}
/**
* 关闭所有已加载的模型
*/
public void closeAll() {
modelMap.values().forEach(model -> {
try {
model.close();
} catch (Exception e) {
e.printStackTrace();
}
});
modelMap.clear();
}
/**
* 移除缓存的模型
* @param modelEnum
*/
public static void removeFromCache(ActionRecModelEnum modelEnum) {
modelMap.remove(modelEnum);
}
}

View File

@@ -110,6 +110,9 @@ public class CommonActionRecModel implements ActionRecModel{
@Override
public void close() throws Exception {
if (fromFactory) {
ActionRecModelFactory.removeFromCache(config.getModelEnum());
}
try {
if (predictorPool != null) {
predictorPool.close();
@@ -125,4 +128,14 @@ public class CommonActionRecModel implements ActionRecModel{
log.warn("关闭 model 失败", e);
}
}
private boolean fromFactory = false;
@Override
public void setFromFactory(boolean fromFactory) {
this.fromFactory = fromFactory;
}
public boolean isFromFactory() {
return fromFactory;
}
}

View File

@@ -8,10 +8,12 @@ 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.action.model.ActionRecModelFactory;
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.ImageUtils;
import cn.smartjavaai.instanceseg.config.InstanceSegModelConfig;
import cn.smartjavaai.instanceseg.criteria.InstanceSegCriteriaFactory;
import cn.smartjavaai.instanceseg.exception.InstanceSegException;
@@ -124,8 +126,9 @@ public class CommonInstanceSegModel implements InstanceSegModel {
@Override
public R<DetectionResponse> detectAndDraw(String imagePath, String outputPath) {
Image img = null;
try {
Image img = SmartImageFactory.getInstance().fromFile(Paths.get(imagePath));
img = SmartImageFactory.getInstance().fromFile(Paths.get(imagePath));
DetectedObjects detectedObjects = detectCore(img);
if(Objects.isNull(detectedObjects) || detectedObjects.getNumberOfObjects() == 0){
return R.fail(R.Status.NO_OBJECT_DETECTED);
@@ -136,11 +139,16 @@ public class CommonInstanceSegModel implements InstanceSegModel {
return R.ok(detectionResponse);
} catch (IOException e) {
throw new InstanceSegException(e);
} finally {
ImageUtils.releaseOpenCVMat(img);
}
}
@Override
public void close() throws Exception {
if (fromFactory) {
InstanceSegModelFactory.removeFromCache(config.getModelEnum());
}
try {
if (predictorPool != null) {
predictorPool.close();
@@ -156,4 +164,14 @@ public class CommonInstanceSegModel implements InstanceSegModel {
log.warn("关闭 model 失败", e);
}
}
private boolean fromFactory = false;
@Override
public void setFromFactory(boolean fromFactory) {
this.fromFactory = fromFactory;
}
public boolean isFromFactory() {
return fromFactory;
}
}

View File

@@ -43,5 +43,8 @@ public interface InstanceSegModel extends AutoCloseable{
throw new UnsupportedOperationException("默认不支持该功能");
}
default void setFromFactory(boolean fromFactory){
throw new UnsupportedOperationException("默认不支持该功能");
}
}

View File

@@ -75,6 +75,7 @@ public class InstanceSegModelFactory {
throw new DetectionException(e);
}
model.loadModel(config);
model.setFromFactory(true);
return model;
}
@@ -97,6 +98,19 @@ public class InstanceSegModelFactory {
modelMap.remove(modelEnum);
}
/**
* 关闭所有已加载的模型
*/
public void closeAll() {
modelMap.values().forEach(model -> {
try {
model.close();
} catch (Exception e) {
e.printStackTrace();
}
});
modelMap.clear();
}
// 初始化默认算法
static {

View File

@@ -12,6 +12,8 @@ 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.ImageUtils;
import cn.smartjavaai.instanceseg.model.InstanceSegModelFactory;
import cn.smartjavaai.obb.config.ObbDetModelConfig;
import cn.smartjavaai.obb.criteria.ObbDetCriteriaFactory;
import cn.smartjavaai.obb.entity.ObbResult;
@@ -125,8 +127,9 @@ public class CommonObbDetModel implements ObbDetModel {
@Override
public R<DetectionResponse> detectAndDraw(String imagePath, String outputPath) {
Image img = null;
try {
Image img = SmartImageFactory.getInstance().fromFile(Paths.get(imagePath));
img = SmartImageFactory.getInstance().fromFile(Paths.get(imagePath));
ObbResult obbResult = detectCore(img);
if(Objects.isNull(obbResult) || CollectionUtils.isEmpty(obbResult.getRotatedBoxeList())){
return R.fail(R.Status.NO_OBJECT_DETECTED);
@@ -137,11 +140,16 @@ public class CommonObbDetModel implements ObbDetModel {
return R.ok(detectionResponse);
} catch (IOException e) {
throw new ObbDetException(e);
} finally {
ImageUtils.releaseOpenCVMat(img);
}
}
@Override
public void close() throws Exception {
if (fromFactory) {
ObbDetModelFactory.removeFromCache(config.getModelEnum());
}
try {
if (predictorPool != null) {
predictorPool.close();
@@ -157,4 +165,14 @@ public class CommonObbDetModel implements ObbDetModel {
log.warn("关闭 model 失败", e);
}
}
private boolean fromFactory = false;
@Override
public void setFromFactory(boolean fromFactory) {
this.fromFactory = fromFactory;
}
public boolean isFromFactory() {
return fromFactory;
}
}

View File

@@ -57,4 +57,7 @@ public interface ObbDetModel extends AutoCloseable{
}
default void setFromFactory(boolean fromFactory){
throw new UnsupportedOperationException("默认不支持该功能");
}
}

View File

@@ -75,6 +75,7 @@ public class ObbDetModelFactory {
throw new DetectionException(e);
}
model.loadModel(config);
model.setFromFactory(true);
return model;
}
@@ -97,6 +98,19 @@ public class ObbDetModelFactory {
modelMap.remove(modelEnum);
}
/**
* 关闭所有已加载的模型
*/
public void closeAll() {
modelMap.values().forEach(model -> {
try {
model.close();
} catch (Exception e) {
e.printStackTrace();
}
});
modelMap.clear();
}
// 初始化默认算法
static {

View File

@@ -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();

View File

@@ -58,5 +58,8 @@ public interface PersonDetModel extends AutoCloseable{
throw new UnsupportedOperationException("默认不支持该功能");
}
default void setFromFactory(boolean fromFactory){
throw new UnsupportedOperationException("默认不支持该功能");
}
}

View File

@@ -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);

View File

@@ -4,6 +4,7 @@ import ai.djl.Device;
import ai.djl.modality.Classifications;
import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.output.Joints;
import ai.djl.modality.cv.translator.YoloPoseTranslatorFactory;
import ai.djl.repository.zoo.Criteria;
import ai.djl.training.util.ProgressBar;
import ai.djl.translate.Translator;
@@ -20,6 +21,7 @@ import cn.smartjavaai.obb.exception.ObbDetException;
import cn.smartjavaai.obb.translator.YoloV11OddTranslator;
import cn.smartjavaai.objectdetection.constant.DetectorConstant;
import cn.smartjavaai.pose.config.PoseModelConfig;
import cn.smartjavaai.pose.enums.PoseModelEnum;
import cn.smartjavaai.pose.exception.PoseException;
import org.apache.commons.lang3.StringUtils;
@@ -58,19 +60,26 @@ public class PoseCriteriaFactory {
* @return
*/
public static Criteria<Image, Joints[]> createDJLCriteria(PoseModelConfig config, Device device) {
if(StringUtils.isNotBlank(config.getModelPath())
&& DJLCommonUtils.isServingPropertiesExists(Paths.get(config.getModelPath()))){
throw new PoseException("模型所在目录未找到 serving.properties 文件");
// if(StringUtils.isNotBlank(config.getModelPath())
// && !DJLCommonUtils.isServingPropertiesExists(Paths.get(config.getModelPath()))){
// throw new PoseException("模型所在目录未找到 serving.properties 文件");
// }
Criteria<Image, Joints[]> criteria = null;
if(config.getModelEnum() == PoseModelEnum.YOLO11N_POSE_PT || config.getModelEnum() == PoseModelEnum.YOLO11N_POSE_ONNX
|| config.getModelEnum() == PoseModelEnum.YOLOV8N_POSE_PT || config.getModelEnum() == PoseModelEnum.YOLOV8N_POSE_ONNX){
criteria =
Criteria.builder()
.setTypes(Image.class, Joints[].class)
.optModelUrls(StringUtils.isNotBlank(config.getModelPath()) ? null : config.getModelEnum().getModelUri())
.optModelPath(StringUtils.isNotBlank(config.getModelPath()) ? Paths.get(config.getModelPath()) : null)
.optDevice(device)
.optTranslatorFactory(new YoloPoseTranslatorFactory())
.optArgument("threshold", config.getThreshold() > 0 ? config.getThreshold() : null)
.optProgress(new ProgressBar())
.build();
}
Criteria<Image, Joints[]> criteria =
Criteria.builder()
.setTypes(Image.class, Joints[].class)
.optModelUrls(StringUtils.isNotBlank(config.getModelPath()) ? null : config.getModelEnum().getModelUri())
.optModelPath(StringUtils.isNotBlank(config.getModelPath()) ? Paths.get(config.getModelPath()) : null)
.optDevice(device)
.optArgument("threshold", config.getThreshold() > 0 ? config.getThreshold() : null)
.optProgress(new ProgressBar())
.build();
return criteria;
}

View File

@@ -14,6 +14,7 @@ import cn.smartjavaai.common.entity.R;
import cn.smartjavaai.common.pool.PredictorFactory;
import cn.smartjavaai.common.utils.ImageUtils;
import cn.smartjavaai.obb.exception.ObbDetException;
import cn.smartjavaai.obb.model.ObbDetModelFactory;
import cn.smartjavaai.objectdetection.config.PersonDetModelConfig;
import cn.smartjavaai.objectdetection.criteria.PersonDetCriteriaFactory;
import cn.smartjavaai.objectdetection.exception.DetectionException;
@@ -121,6 +122,7 @@ public class CommonPoseModel implements PoseModel {
}
// 调用 save 方法将 Image 写入字节流
img.save(Files.newOutputStream(Paths.get(outputPath)), "png");
ImageUtils.releaseOpenCVMat(img);
return allJoints;
} catch (IOException e) {
throw new ObbDetException(e);
@@ -129,6 +131,9 @@ public class CommonPoseModel implements PoseModel {
@Override
public void close() throws Exception {
if (fromFactory) {
PoseDetModelFactory.removeFromCache(config.getModelEnum());
}
try {
if (predictorPool != null) {
predictorPool.close();
@@ -144,4 +149,14 @@ public class CommonPoseModel implements PoseModel {
log.warn("关闭 model 失败", e);
}
}
private boolean fromFactory = false;
@Override
public void setFromFactory(boolean fromFactory) {
this.fromFactory = fromFactory;
}
public boolean isFromFactory() {
return fromFactory;
}
}

View File

@@ -76,6 +76,7 @@ public class PoseDetModelFactory {
throw new DetectionException(e);
}
model.loadModel(config);
model.setFromFactory(true);
return model;
}
@@ -99,6 +100,20 @@ public class PoseDetModelFactory {
}
/**
* 关闭所有已加载的模型
*/
public void closeAll() {
modelMap.values().forEach(model -> {
try {
model.close();
} catch (Exception e) {
e.printStackTrace();
}
});
modelMap.clear();
}
// 初始化默认算法
static {
registerAlgorithm(PoseModelEnum.YOLOV8N_POSE_ONNX, CommonPoseModel.class);

View File

@@ -49,5 +49,8 @@ public interface PoseModel extends AutoCloseable{
throw new UnsupportedOperationException("默认不支持该功能");
}
default void setFromFactory(boolean fromFactory){
throw new UnsupportedOperationException("默认不支持该功能");
}
}

View File

@@ -18,6 +18,7 @@ import cn.smartjavaai.common.utils.Base64ImageUtils;
import cn.smartjavaai.common.utils.ImageUtils;
import cn.smartjavaai.instanceseg.exception.InstanceSegException;
import cn.smartjavaai.objectdetection.exception.DetectionException;
import cn.smartjavaai.pose.model.PoseDetModelFactory;
import cn.smartjavaai.semseg.config.SemSegModelConfig;
import cn.smartjavaai.semseg.criteria.SemSegCriteriaFactory;
import cn.smartjavaai.vision.utils.CategoryMaskFilter;
@@ -122,6 +123,7 @@ public class CommonSemSegModel implements SemSegModel {
}
ImageUtils.drawMask(categoryMask, img, 180, 0);
img.save(Files.newOutputStream(Paths.get(outputPath)), "png");
ImageUtils.releaseOpenCVMat(img);
return R.ok(categoryMask);
} catch (IOException e) {
throw new InstanceSegException(e);
@@ -141,6 +143,9 @@ public class CommonSemSegModel implements SemSegModel {
@Override
public void close() throws Exception {
if (fromFactory) {
SemSegModelFactory.removeFromCache(config.getModelEnum());
}
try {
if (predictorPool != null) {
predictorPool.close();
@@ -156,4 +161,14 @@ public class CommonSemSegModel implements SemSegModel {
log.warn("关闭 model 失败", e);
}
}
private boolean fromFactory = false;
@Override
public void setFromFactory(boolean fromFactory) {
this.fromFactory = fromFactory;
}
public boolean isFromFactory() {
return fromFactory;
}
}

View File

@@ -38,5 +38,8 @@ public interface SemSegModel extends AutoCloseable{
}
default void setFromFactory(boolean fromFactory){
throw new UnsupportedOperationException("默认不支持该功能");
}
}

View File

@@ -75,6 +75,7 @@ public class SemSegModelFactory {
throw new DetectionException(e);
}
model.loadModel(config);
model.setFromFactory(true);
return model;
}
@@ -97,6 +98,19 @@ public class SemSegModelFactory {
modelMap.remove(modelEnum);
}
/**
* 关闭所有已加载的模型
*/
public void closeAll() {
modelMap.values().forEach(model -> {
try {
model.close();
} catch (Exception e) {
e.printStackTrace();
}
});
modelMap.clear();
}
// 初始化默认算法
static {

View File

@@ -60,13 +60,13 @@ public class DetectorUtils {
DetectionRectangle rectangle = new DetectionRectangle(x, y, width, height);
DetectionInfo detectionInfo = new DetectionInfo(rectangle, detection.getProbabilities().get(index).floatValue());
//目标检测
if(box instanceof Rectangle){
ObjectDetInfo objectDetInfo = new ObjectDetInfo(className);
detectionInfo.setObjectDetInfo(objectDetInfo);
}else if(box instanceof Mask){
if(box instanceof Mask){
Mask mask = (Mask)box;
InstanceSegInfo instanceSegInfo = new InstanceSegInfo(className, mask.getProbDist());
detectionInfo.setInstanceSegInfo(instanceSegInfo);
}else if(box instanceof Rectangle){
ObjectDetInfo objectDetInfo = new ObjectDetInfo(className);
detectionInfo.setObjectDetInfo(objectDetInfo);
}
detectionInfoList.add(detectionInfo);
index++;
@@ -106,9 +106,9 @@ public class DetectorUtils {
Imgproc.line(srcMat, points.get(0).toCvPoint(), points.get(1).toCvPoint(), new Scalar(0, 255, 0), 1);
Imgproc.line(srcMat, points.get(1).toCvPoint(), points.get(2).toCvPoint(), new Scalar(0, 255, 0),1);
Imgproc.line(srcMat, points.get(2).toCvPoint(), points.get(3).toCvPoint(), new Scalar(0, 255, 0),1);
Imgproc.line(srcMat, points.get(3).toCvPoint(), points.get(1).toCvPoint(), new Scalar(0, 255, 0), 1);
Imgproc.line(srcMat, points.get(3).toCvPoint(), points.get(0).toCvPoint(), new Scalar(0, 255, 0), 1);
// 中文乱码
Imgproc.putText(srcMat, box.className, points.get(0).toCvPoint(), Imgproc.FONT_HERSHEY_SCRIPT_SIMPLEX, 1.0, new Scalar(0, 255, 0), 1);
Imgproc.putText(srcMat, box.className, points.get(0).toCvPoint(), Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(0, 255, 0), 1);
}
}