mirror of
https://github.com/geekwenjie/SmartJavaAI.git
synced 2026-09-15 22:57:26 +00:00
1、新增图片与视频活体检测
2、新增人脸属性识别(性别、年龄、口罩、姿态、眼睛状态) 3、优化检测返回与包结构 4、新增 dependencyManagement 统一依赖版本管理
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
package cn.smartjavaai.ocr.recognition;
|
||||
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
|
||||
/**
|
||||
* OCR模型
|
||||
* @author dwj
|
||||
*/
|
||||
public interface OcrRecModel {
|
||||
|
||||
/**
|
||||
* 加载模型
|
||||
* @param config
|
||||
*/
|
||||
void loadModel(OcrRecModelConfig config); // 加载模型
|
||||
|
||||
/**
|
||||
* 人脸检测
|
||||
* @param imagePath 图片路径
|
||||
* @return
|
||||
*/
|
||||
default DetectionResponse detect(String imagePath) {
|
||||
throw new UnsupportedOperationException("默认不支持该功能");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测并绘制结果
|
||||
* @param imagePath 图片输入路径(包含文件名称)
|
||||
* @param outputPath 图片输出路径(包含文件名称)
|
||||
*/
|
||||
default void detectAndDraw(String imagePath, String outputPath) {
|
||||
throw new UnsupportedOperationException("默认不支持该功能");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package cn.smartjavaai.ocr.recognition;
|
||||
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author dwj
|
||||
* @date 2025/4/22
|
||||
*/
|
||||
@Data
|
||||
public class OcrRecModelConfig {
|
||||
|
||||
/**
|
||||
* 模型名称
|
||||
*/
|
||||
private OcrRecModelEnum modelEnum;
|
||||
|
||||
/**
|
||||
* 设备类型
|
||||
*/
|
||||
private DeviceEnum device;
|
||||
|
||||
/**
|
||||
* 模型路径
|
||||
*/
|
||||
private String modelPath;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.smartjavaai.ocr.recognition;
|
||||
|
||||
/**
|
||||
* OCR识别模型枚举
|
||||
* @author dwj
|
||||
* @date 2025/4/4
|
||||
*/
|
||||
public enum OcrRecModelEnum {
|
||||
|
||||
PADDLEOCR_V4_REC_MODEL;
|
||||
|
||||
|
||||
/**
|
||||
* 根据名称获取枚举 (忽略大小写和下划线变体)
|
||||
*/
|
||||
public static OcrRecModelEnum fromName(String name) {
|
||||
String formatted = name.trim().toUpperCase().replaceAll("[-_]", "");
|
||||
for (OcrRecModelEnum model : values()) {
|
||||
if (model.name().replaceAll("_", "").equals(formatted)) {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("未知模型名称: " + name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package cn.smartjavaai.ocr.recognition;
|
||||
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.ocr.exception.OcrException;
|
||||
import cn.smartjavaai.ocr.ppv4.model.PaddleOCRV4DetModel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* OCR模型工厂
|
||||
* @author dwj
|
||||
*/
|
||||
@Slf4j
|
||||
public class OcrRecModelFactory {
|
||||
|
||||
// 使用 volatile 和双重检查锁定来确保线程安全的单例模式
|
||||
private static volatile OcrRecModelFactory instance;
|
||||
|
||||
private static final ConcurrentHashMap<String, OcrRecModel> modelMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 算法注册表
|
||||
*/
|
||||
private static final Map<String, Class<? extends OcrRecModel>> registry =
|
||||
new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
public static OcrRecModelFactory getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (OcrRecModelFactory.class) {
|
||||
if (instance == null) {
|
||||
instance = new OcrRecModelFactory();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 注册算法
|
||||
* @param name
|
||||
* @param clazz
|
||||
*/
|
||||
private static void registerModel(String name, Class<? extends OcrRecModel> clazz) {
|
||||
registry.put(name.toLowerCase(), clazz);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取模型(通过配置)
|
||||
* @param config
|
||||
* @return
|
||||
*/
|
||||
public OcrRecModel getModel(OcrRecModelConfig config) {
|
||||
if(Objects.isNull(config) || Objects.isNull(config.getModelEnum())){
|
||||
throw new OcrException("未配置OCR模型");
|
||||
}
|
||||
return modelMap.computeIfAbsent(config.getModelEnum().name(), k -> {
|
||||
return createFaceModel(config);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用ModelConfig创建算法
|
||||
* @param config
|
||||
* @return
|
||||
*/
|
||||
private OcrRecModel createFaceModel(OcrRecModelConfig config) {
|
||||
Class<?> clazz = registry.get(config.getModelEnum().name().toLowerCase());
|
||||
if(clazz == null){
|
||||
throw new OcrException("Unsupported model");
|
||||
}
|
||||
OcrRecModel algorithm = null;
|
||||
try {
|
||||
algorithm = (OcrRecModel) clazz.newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
throw new OcrException(e);
|
||||
}
|
||||
algorithm.loadModel(config);
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
|
||||
// 初始化默认算法
|
||||
static {
|
||||
//registerModel("PADDLEOCR_V4_REC_MODEL", PaddleOCRV4DetModel.class);
|
||||
log.info("缓存目录:{}", Config.getCachePath());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user