mirror of
https://github.com/geekwenjie/SmartJavaAI.git
synced 2026-09-15 22:57:26 +00:00
新增目标检测功能
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
package cn.smartjavaai.common.entity;
|
||||
|
||||
/**
|
||||
* 检测结果-矩形区域
|
||||
* @author dwj
|
||||
*/
|
||||
public class DetectionRectangle {
|
||||
|
||||
public int x;
|
||||
public int y;
|
||||
public int width;
|
||||
public int height;
|
||||
public float score;
|
||||
|
||||
public String className;
|
||||
|
||||
public DetectionRectangle() {
|
||||
}
|
||||
|
||||
public DetectionRectangle(int x, int y, int width, int height, float score) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
public DetectionRectangle(int x, int y, int width, int height, float score, String className) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.score = score;
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public float getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
public void setScore(float score) {
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public void setClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.smartjavaai.common.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 检测结果
|
||||
* @author dwj
|
||||
* @date 2025/4/12
|
||||
*/
|
||||
public class DetectionResponse {
|
||||
|
||||
private List<DetectionRectangle> rectangleList;
|
||||
|
||||
public List<DetectionRectangle> getRectangleList() {
|
||||
return rectangleList;
|
||||
}
|
||||
|
||||
public void setRectangleList(List<DetectionRectangle> rectangleList) {
|
||||
this.rectangleList = rectangleList;
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package cn.smartjavaai.common.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 矩形区域
|
||||
* @author dwj
|
||||
*/
|
||||
public class Rectangle {
|
||||
|
||||
/**
|
||||
* 矩形区域点集合
|
||||
*/
|
||||
List<Point> pointList;
|
||||
|
||||
/**
|
||||
* 矩形区域宽度
|
||||
*/
|
||||
int width;
|
||||
|
||||
/**
|
||||
* 矩形区域高度
|
||||
*/
|
||||
int height;
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public List<Point> getPointList() {
|
||||
return pointList;
|
||||
}
|
||||
|
||||
public void setPointList(List<Point> pointList) {
|
||||
this.pointList = pointList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.smartjavaai.common.enums;
|
||||
|
||||
/**
|
||||
* 目标检测模型枚举
|
||||
* @author dwj
|
||||
* @date 2025/4/4
|
||||
*/
|
||||
public enum DeviceEnum {
|
||||
|
||||
// resnet50 系列
|
||||
CPU,
|
||||
GPU;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package cn.smartjavaai.common.pool;
|
||||
|
||||
import ai.djl.inference.Predictor;
|
||||
import ai.djl.repository.zoo.ZooModel;
|
||||
import org.apache.commons.pool2.PooledObject;
|
||||
import org.apache.commons.pool2.BasePooledObjectFactory;
|
||||
import org.apache.commons.pool2.impl.DefaultPooledObject;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPool;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
/**
|
||||
* 模型共享池管理器
|
||||
* @author dwj
|
||||
* @date 2025/4/8
|
||||
*/
|
||||
public class ModelPredictorPoolManager {
|
||||
|
||||
// 每个模型的唯一key -> 对应Predictor池
|
||||
private final Map<String, GenericObjectPool<? extends Predictor<?, ?>>> poolMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 注册模型池
|
||||
* @param key 模型标识符(自定义,如模型路径、模型名等)
|
||||
* @param model 模型本体
|
||||
* @param config 池配置(可选)
|
||||
*/
|
||||
public <I, O> void registerModel(String key, ZooModel<I, O> model, GenericObjectPoolConfig<Predictor<I, O>> config) {
|
||||
PredictorFactory<I, O> factory = new PredictorFactory<>(model);
|
||||
GenericObjectPool<Predictor<I, O>> pool = new GenericObjectPool<>(factory, config);
|
||||
poolMap.put(key, pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* 借出一个 Predictor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <I, O> Predictor<I, O> borrowPredictor(String key) throws Exception {
|
||||
GenericObjectPool<Predictor<I, O>> pool = (GenericObjectPool<Predictor<I, O>>) poolMap.get(key);
|
||||
if (pool == null) {
|
||||
throw new IllegalArgumentException("模型未注册: " + key);
|
||||
}
|
||||
return pool.borrowObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* 归还一个 Predictor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <I, O> void returnPredictor(String key, Predictor<I, O> predictor) {
|
||||
GenericObjectPool<Predictor<I, O>> pool = (GenericObjectPool<Predictor<I, O>>) poolMap.get(key);
|
||||
if (pool != null) {
|
||||
pool.returnObject(predictor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁全部池
|
||||
*/
|
||||
public void closeAll() {
|
||||
for (GenericObjectPool<? extends Predictor<?, ?>> pool : poolMap.values()) {
|
||||
pool.close();
|
||||
}
|
||||
poolMap.clear();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.smartjavaai.common.pool;
|
||||
|
||||
import ai.djl.inference.Predictor;
|
||||
import ai.djl.repository.zoo.ZooModel;
|
||||
import org.apache.commons.pool2.BasePooledObjectFactory;
|
||||
import org.apache.commons.pool2.PooledObject;
|
||||
import org.apache.commons.pool2.impl.DefaultPooledObject;
|
||||
|
||||
/**
|
||||
* Predictor 工厂类
|
||||
* @author dwj
|
||||
* @date 2025/4/8
|
||||
*/
|
||||
public class PredictorFactory<I, O> extends BasePooledObjectFactory<Predictor<I, O>> {
|
||||
private final ZooModel<I, O> model;
|
||||
|
||||
public PredictorFactory(ZooModel<I, O> model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predictor<I, O> create() {
|
||||
return model.newPredictor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledObject<Predictor<I, O>> wrap(Predictor<I, O> predictor) {
|
||||
return new DefaultPooledObject<>(predictor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyObject(PooledObject<Predictor<I, O>> p) {
|
||||
p.getObject().close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.smartjavaai.common.utils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 文件操作工具类
|
||||
* @author dwj
|
||||
* @date 2025/4/4
|
||||
*/
|
||||
public class FileUtils {
|
||||
|
||||
/**
|
||||
* 检查文件是否存在
|
||||
* @param filePath
|
||||
* @return
|
||||
*/
|
||||
public static boolean isFileExists(String filePath) {
|
||||
File file = new File(filePath);
|
||||
return file.exists() && !file.isDirectory(); // 确保是文件且存在
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
package cn.smartjavaai.common.utils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
//import java.awt.image.ColorConvertOp;
|
||||
import java.awt.image.ComponentSampleModel;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
@@ -74,4 +78,18 @@ public class ImageUtils {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查图像是否有效
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
public static boolean isImageValid(BufferedImage image) {
|
||||
// 检查是否为 null 或尺寸异常(如宽高为0)
|
||||
return image != null && image.getWidth() > 0 && image.getHeight() > 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user