mirror of
https://github.com/geekwenjie/SmartJavaAI.git
synced 2026-10-01 17:37:01 +00:00
【人脸识别】 新增多种人脸识别模型
【底层优化】 支持自由选择 OpenCV 或 BufferedImage 作为图像引擎 【通用图像】 全部模型启用 Image 输入,支持各类图片格式与 Image 的互转 【模型管理】 优化模型生命周期,关闭后可重新创建 【人脸识别】 支持在人脸查询结果中绘制姓名标注 【人脸检测】 新增人脸裁剪功能 【修复】 修复若干已知问题,提升系统稳定性
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<smartjavaai.version>1.0.24</smartjavaai.version>
|
||||
<smartjavaai.version>1.0.25</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.face.facedet.FaceDetDemo</exec.mainClass>
|
||||
|
||||
@@ -220,35 +220,6 @@
|
||||
|
||||
|
||||
|
||||
<!-- linux aarch64 平台 (保留对应平台的配置,可以减小包大小)-->
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp</artifactId>
|
||||
<version>${javacv.version}</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>ffmpeg</artifactId>
|
||||
<version>6.1.1-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>openblas</artifactId>
|
||||
<version>0.3.26-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<version>4.9.0-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
@@ -278,7 +249,21 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
|
||||
|
||||
<repositories>
|
||||
<!-- <repository>-->
|
||||
<!-- <id>aliyunmaven</id>-->
|
||||
<!-- <name>阿里云公共仓库</name>-->
|
||||
<!-- <url>https://maven.aliyun.com/repository/public</url>-->
|
||||
<!-- <releases>-->
|
||||
<!-- <enabled>true</enabled>-->
|
||||
<!-- </releases>-->
|
||||
<!-- <snapshots>-->
|
||||
<!-- <enabled>false</enabled>-->
|
||||
<!-- </snapshots>-->
|
||||
<!-- </repository>-->
|
||||
<repository>
|
||||
<id>central</id>
|
||||
<url>https://repo1.maven.org/maven2/</url>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package smartai.examples.face.attribute;
|
||||
|
||||
import ai.djl.modality.cv.Image;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.DetectionInfo;
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
import cn.smartjavaai.common.entity.R;
|
||||
import cn.smartjavaai.common.entity.face.FaceAttribute;
|
||||
import cn.smartjavaai.common.entity.face.FaceInfo;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
import cn.smartjavaai.face.config.FaceAttributeConfig;
|
||||
import cn.smartjavaai.face.config.FaceDetConfig;
|
||||
import cn.smartjavaai.face.enums.FaceAttributeModelEnum;
|
||||
@@ -38,6 +41,8 @@ public class FaceAttributeDetDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -47,13 +52,13 @@ public class FaceAttributeDetDemo {
|
||||
FaceAttributeConfig config = new FaceAttributeConfig();
|
||||
config.setModelEnum(FaceAttributeModelEnum.SEETA_FACE6_MODEL);
|
||||
//需替换为实际模型存储路径
|
||||
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
|
||||
config.setModelPath("C:/Users/DengWenJie/Downloads/sf3.0_models/sf3.0_models");
|
||||
return FaceAttributeModelFactory.getInstance().getModel(config);
|
||||
}
|
||||
|
||||
public FaceDetModel getFaceDetModel() {
|
||||
//需替换为实际模型存储路径
|
||||
String modelPath = "C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models";
|
||||
String modelPath = "C:/Users/DengWenJie/Downloads/sf3.0_models/sf3.0_models";
|
||||
FaceDetConfig faceDetectModelConfig = new FaceDetConfig();
|
||||
faceDetectModelConfig.setModelEnum(FaceDetModelEnum.SEETA_FACE6_MODEL);
|
||||
faceDetectModelConfig.setModelPath(modelPath);
|
||||
@@ -68,10 +73,12 @@ public class FaceAttributeDetDemo {
|
||||
public void testFaceAttributeDetect(){
|
||||
try {
|
||||
FaceAttributeModel faceAttributeModel = getFaceAttributeModel();
|
||||
DetectionResponse detectionResponse = faceAttributeModel.detect("src/main/resources/iu_1.jpg");
|
||||
////创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
DetectionResponse detectionResponse = faceAttributeModel.detect(image);
|
||||
//绘制并导出人脸属性图片,小人脸仅有人脸框
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/iu_1.jpg").toAbsolutePath().toString()));
|
||||
FaceUtils.drawBoxesWithFaceAttribute(image, detectionResponse,"C:/Users/Administrator/Downloads/double_person_.png");
|
||||
BufferedImage bufferedImage = ImageUtils.toBufferedImage(image);
|
||||
FaceUtils.drawBoxesWithFaceAttribute(bufferedImage, detectionResponse,"C:/Users/Administrator/Downloads/double_person_.png");
|
||||
log.info("人脸属性检测结果:{}", JSONObject.toJSONString(detectionResponse));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -85,7 +92,9 @@ public class FaceAttributeDetDemo {
|
||||
public void testFaceAttributeDetect2(){
|
||||
try {
|
||||
FaceAttributeModel faceAttributeModel = getFaceAttributeModel();
|
||||
FaceAttribute faceAttribute = faceAttributeModel.detectTopFace("src/main/resources/iu_1.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
FaceAttribute faceAttribute = faceAttributeModel.detectTopFace(image);
|
||||
log.info("人脸属性检测结果:{}", JSONObject.toJSONString(faceAttribute));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -101,8 +110,8 @@ public class FaceAttributeDetDemo {
|
||||
try {
|
||||
FaceDetModel faceDetModel = getFaceDetModel();
|
||||
FaceAttributeModel faceAttributeModel = getFaceAttributeModel();
|
||||
//人脸检测
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/iu_1.jpg").toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
R<DetectionResponse> detectionResponse = faceDetModel.detect(image);
|
||||
if(detectionResponse.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectionResponse.getData()));
|
||||
|
||||
@@ -3,6 +3,7 @@ package smartai.examples.face.expression;
|
||||
import ai.djl.modality.cv.Image;
|
||||
import ai.djl.modality.cv.ImageFactory;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.DetectionInfo;
|
||||
import cn.smartjavaai.common.entity.DetectionRectangle;
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
@@ -11,6 +12,7 @@ import cn.smartjavaai.common.entity.face.ExpressionResult;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.enums.face.FacialExpression;
|
||||
import cn.smartjavaai.common.enums.face.LivenessStatus;
|
||||
import cn.smartjavaai.common.utils.BufferedImageUtils;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
import cn.smartjavaai.common.utils.OpenCVUtils;
|
||||
import cn.smartjavaai.face.config.FaceDetConfig;
|
||||
@@ -60,6 +62,8 @@ public class ExpressionRecDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -75,7 +79,7 @@ public class ExpressionRecDemo {
|
||||
//人脸检测模型,SmartJavaAI提供了多种模型选择(更多模型,请查看文档),切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(FaceDetModelEnum.MTCNN);
|
||||
//下载模型并替换本地路径,下载地址:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/face_model");
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/face_model/mtcnn");
|
||||
//只返回相似度大于该值的人脸,需要根据实际情况调整,分值越大越严格容易漏检,分值越小越宽松容易误识别
|
||||
config.setConfidenceThreshold(0.5f);
|
||||
//用于去除重复的人脸框,当两个框的重叠度超过该值时,只保留一个
|
||||
@@ -106,7 +110,9 @@ public class ExpressionRecDemo {
|
||||
public void testExpressionDetect() {
|
||||
try {
|
||||
ExpressionModel model = getExpressionModel();
|
||||
R<ExpressionResult> result = model.detectTopFace("src/main/resources/emotion/happy.png");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/emotion/happy.png");
|
||||
R<ExpressionResult> result = model.detectTopFace(image);
|
||||
if(result.isSuccess()){
|
||||
log.info("识别结果:{}", JSONObject.toJSONString(result.getData().getExpression().getDescription()));
|
||||
}else{
|
||||
@@ -125,7 +131,9 @@ public class ExpressionRecDemo {
|
||||
public void testExpressionDetect2() {
|
||||
try {
|
||||
ExpressionModel model = getExpressionModel();
|
||||
R<DetectionResponse> result = model.detect("src/main/resources/emotion/happy.png");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/emotion/happy.png");
|
||||
R<DetectionResponse> result = model.detect(image);
|
||||
if(result.isSuccess()){
|
||||
//log.info("识别结果:{}", JSONObject.toJSONString(result.getData()));
|
||||
for (DetectionInfo detectionInfo : result.getData().getDetectionInfoList()) {
|
||||
@@ -149,7 +157,8 @@ public class ExpressionRecDemo {
|
||||
try {
|
||||
FaceDetModel faceDetModel = getFaceDetModel();
|
||||
ExpressionModel model = getExpressionModel();
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/emotion/happy.png").toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/emotion/happy.png");
|
||||
R<DetectionResponse> detResult = faceDetModel.detect(image);
|
||||
if(detResult.isSuccess()){
|
||||
R<List<ExpressionResult>> result = model.detect(image, detResult.getData());
|
||||
@@ -178,7 +187,8 @@ public class ExpressionRecDemo {
|
||||
try {
|
||||
FaceDetModel faceDetModel = getFaceDetModel();
|
||||
ExpressionModel model = getExpressionModel();
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/emotion/happy.png").toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/emotion/happy.png");
|
||||
R<DetectionResponse> detResult = faceDetModel.detect(image);
|
||||
if(detResult.isSuccess()){
|
||||
for (DetectionInfo detectionInfo : detResult.getData().getDetectionInfoList()) {
|
||||
@@ -204,15 +214,16 @@ public class ExpressionRecDemo {
|
||||
public void testExpressionDetectAndDraw(){
|
||||
try {
|
||||
ExpressionModel model = getExpressionModel();
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/emotion/surprise.png").toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/emotion/surprise.png");
|
||||
R<DetectionResponse> result = model.detect(image);
|
||||
if(result.isSuccess()){
|
||||
//log.info("识别结果:{}", JSONObject.toJSONString(result.getData()));
|
||||
for (DetectionInfo detectionInfo : result.getData().getDetectionInfoList()) {
|
||||
log.info("识别结果:{}", JSONObject.toJSONString(detectionInfo.getFaceInfo().getExpressionResult().getExpression().getDescription()));
|
||||
ImageUtils.drawImageRectWithText(image, detectionInfo.getDetectionRectangle(), detectionInfo.getFaceInfo().getExpressionResult().getExpression().getDescription(), Color.red);
|
||||
ImageUtils.drawRectAndText(image, detectionInfo.getDetectionRectangle(), detectionInfo.getFaceInfo().getExpressionResult().getExpression().getDescription());
|
||||
}
|
||||
ImageUtils.saveImage(image, "output/detect.jpg");
|
||||
ImageUtils.save(image, "output/detect.jpg");
|
||||
}else{
|
||||
log.info("识别失败:{}", result.getMessage());
|
||||
}
|
||||
@@ -225,7 +236,7 @@ public class ExpressionRecDemo {
|
||||
* 摄像头表情识别
|
||||
* 注意事项:如果视频比较卡,可以使用轻量的人脸检测模型
|
||||
*/
|
||||
@Test
|
||||
// @Test
|
||||
public void testExpressionDetectCamera(){
|
||||
try {
|
||||
ExpressionModel expressionModel = getExpressionModel();
|
||||
@@ -264,7 +275,7 @@ public class ExpressionRecDemo {
|
||||
JOptionPane.showConfirmDialog(null, "Failed to capture image from WebCam.");
|
||||
}
|
||||
ViewerFrame frame = new ViewerFrame(width, height);
|
||||
ImageFactory factory = ImageFactory.getInstance();
|
||||
SmartImageFactory factory = SmartImageFactory.getInstance();
|
||||
Size size = new Size(width, height);
|
||||
|
||||
while (capture.isOpened()) {
|
||||
@@ -273,19 +284,18 @@ public class ExpressionRecDemo {
|
||||
}
|
||||
Mat resizeImage = new Mat();
|
||||
Imgproc.resize(image, resizeImage, size);
|
||||
Image img = factory.fromImage(resizeImage);
|
||||
BufferedImage bufferedImage = OpenCVUtils.mat2Image(resizeImage);
|
||||
R<DetectionResponse> detectedResult = expressionModel.detect(bufferedImage);
|
||||
Image img = factory.fromMat(resizeImage);
|
||||
R<DetectionResponse> detectedResult = expressionModel.detect(img);
|
||||
if(!detectedResult.isSuccess()){
|
||||
log.debug("识别失败:{}", detectedResult.getMessage());
|
||||
continue;
|
||||
}
|
||||
for(DetectionInfo detectionInfo : detectedResult.getData().getDetectionInfoList()){
|
||||
DetectionRectangle detectionRectangle = detectionInfo.getDetectionRectangle();
|
||||
String text = detectionInfo.getFaceInfo().getExpressionResult().getExpression().getDescription() + ":" + detectionInfo.getFaceInfo().getExpressionResult().getScore();
|
||||
ImageUtils.drawImageRectWithText(bufferedImage, detectionRectangle, text, Color.red);
|
||||
String text = detectionInfo.getFaceInfo().getExpressionResult().getExpression().getLabel() + ":" + detectionInfo.getFaceInfo().getExpressionResult().getScore();
|
||||
ImageUtils.drawRectAndText(img, detectionRectangle, text);
|
||||
}
|
||||
frame.showImage(bufferedImage);
|
||||
frame.showImage(ImageUtils.toBufferedImage(img));
|
||||
}
|
||||
|
||||
capture.release();
|
||||
|
||||
@@ -2,7 +2,9 @@ package smartai.examples.face.facedet;
|
||||
|
||||
import ai.djl.modality.cv.Image;
|
||||
import ai.djl.modality.cv.ImageFactory;
|
||||
import ai.djl.util.JsonUtils;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.DetectionInfo;
|
||||
import cn.smartjavaai.common.entity.DetectionRectangle;
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
@@ -17,6 +19,7 @@ import cn.smartjavaai.face.enums.FaceDetModelEnum;
|
||||
import cn.smartjavaai.face.factory.FaceDetModelFactory;
|
||||
import cn.smartjavaai.face.model.facedect.FaceDetModel;
|
||||
import cn.smartjavaai.face.model.liveness.LivenessDetModel;
|
||||
import cn.smartjavaai.face.utils.FaceUtils;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import nu.pattern.OpenCV;
|
||||
@@ -51,6 +54,8 @@ public class FaceDetDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -67,7 +72,7 @@ public class FaceDetDemo {
|
||||
//人脸检测模型,SmartJavaAI提供了多种模型选择(更多模型,请查看文档),切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(FaceDetModelEnum.MTCNN);
|
||||
//下载模型并替换本地路径,下载地址:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/face_model");
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/face_model/mtcnn");
|
||||
//只返回相似度大于该值的人脸,需要根据实际情况调整,分值越大越严格容易漏检,分值越小越宽松容易误识别
|
||||
config.setConfidenceThreshold(0.5f);
|
||||
//用于去除重复的人脸框,当两个框的重叠度超过该值时,只保留一个
|
||||
@@ -104,7 +109,7 @@ public class FaceDetDemo {
|
||||
//人脸检测模型,SmartJavaAI提供了多种模型选择(更多模型,请查看文档),切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(FaceDetModelEnum.YOLOV5_FACE_320);
|
||||
//下载模型并替换本地路径,下载地址:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/face_model/yolo-face/yolov5face-n-0.5-320x320.onnx");
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/face_model/yolo-face/yolov5face-n-0.5-320x320.onnx");
|
||||
//只返回相似度大于该值的人脸,需要根据实际情况调整,分值越大越严格容易漏检,分值越小越宽松容易误识别
|
||||
config.setConfidenceThreshold(0.5f);
|
||||
//用于去除重复的人脸框,当两个框的重叠度超过该值时,只保留一个
|
||||
@@ -137,9 +142,16 @@ public class FaceDetDemo {
|
||||
public void testFaceDetect(){
|
||||
try {
|
||||
FaceDetModel faceModel = getFaceDetModel();
|
||||
R<DetectionResponse> detectedResult = faceModel.detect(imgPath);
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile(imgPath);
|
||||
R<DetectionResponse> detectedResult = faceModel.detect(image);
|
||||
if(detectedResult.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectedResult.getData()));
|
||||
//裁剪人脸保存
|
||||
for (DetectionInfo detectionInfo : detectedResult.getData().getDetectionInfoList()) {
|
||||
Image faceImage = FaceUtils.cropFace(image, detectionInfo.getDetectionRectangle());
|
||||
ImageUtils.save(faceImage, "output/face_" + detectionInfo.getDetectionRectangle().getX() + "_" + detectionInfo.getDetectionRectangle().getY() + ".jpg");
|
||||
}
|
||||
}else{
|
||||
log.info("人脸检测失败:{}", detectedResult.getMessage());
|
||||
}
|
||||
@@ -156,7 +168,12 @@ public class FaceDetDemo {
|
||||
public void testFaceDetectAndDraw(){
|
||||
try {
|
||||
FaceDetModel faceModel = getFaceDetModel();
|
||||
faceModel.detectAndDraw("src/main/resources/largest_selfie.jpg","output/largest_selfie_detected.png");
|
||||
R<DetectionResponse> detectedResult = faceModel.detectAndDraw("src/main/resources/largest_selfie.jpg","output/largest_selfie_detected.png");
|
||||
if(detectedResult.isSuccess()){
|
||||
log.info("人脸检测成功:{}", JsonUtils.toJson(detectedResult.getData()));
|
||||
}else{
|
||||
log.info("人脸检测失败:{}", detectedResult.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -170,15 +187,14 @@ public class FaceDetDemo {
|
||||
public void testFaceDetectAndDraw2(){
|
||||
try {
|
||||
FaceDetModel faceModel = getFaceDetModel();
|
||||
BufferedImage image = null;
|
||||
String imagePath = "src/main/resources/largest_selfie.jpg";
|
||||
image = ImageIO.read(new File(Paths.get(imagePath).toAbsolutePath().toString()));
|
||||
//可以根据后续业务场景使用detectedImage
|
||||
R<BufferedImage> detectedImage = faceModel.detectAndDraw(image);
|
||||
if(detectedImage.isSuccess()){
|
||||
log.info("人脸检测成功");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile(imgPath);
|
||||
R<DetectionResponse> detectionResponseR = faceModel.detectAndDraw(image);
|
||||
if(detectionResponseR.isSuccess()){
|
||||
log.info("人脸检测成功:{}", JsonUtils.toJson(detectionResponseR.getData()));
|
||||
ImageUtils.save(detectionResponseR.getData().getDrawnImage(), "output/iu_1_detect.png");
|
||||
}else{
|
||||
log.info("人脸检测失败:{}", detectedImage.getMessage());
|
||||
log.info("人脸检测失败:{}", detectionResponseR.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -187,31 +203,6 @@ public class FaceDetDemo {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 人脸检测(GPU模式)
|
||||
*/
|
||||
@Test
|
||||
public void testDetectFaceGPU(){
|
||||
try {
|
||||
FaceDetConfig config = new FaceDetConfig();
|
||||
//人脸检测模型,SmartJavaAI提供了多种模型选择(更多模型,请查看文档),切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(FaceDetModelEnum.MTCNN);
|
||||
//下载模型并替换本地路径,下载地址:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/face_model");
|
||||
//只返回相似度大于该值的人脸,需要根据实际情况调整,分值越大越严格容易漏检,分值越小越宽松容易误识别
|
||||
config.setConfidenceThreshold(0.5f);
|
||||
config.setDevice(DeviceEnum.GPU);
|
||||
FaceDetModel faceModel = FaceDetModelFactory.getInstance().getModel(config);
|
||||
R<DetectionResponse> detectedResult = faceModel.detect(imgPath);
|
||||
if(detectedResult.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectedResult.getData()));
|
||||
}else{
|
||||
log.info("人脸检测失败:{}", detectedResult.getMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 人脸检测(Seetaface6)
|
||||
@@ -221,7 +212,9 @@ public class FaceDetDemo {
|
||||
public void testFaceDetectSeetaface6(){
|
||||
try {
|
||||
FaceDetModel faceModel = getSeetaface6DetModel();
|
||||
R<DetectionResponse> detectedResult = faceModel.detect(imgPath);
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile(imgPath);
|
||||
R<DetectionResponse> detectedResult = faceModel.detect(image);
|
||||
if(detectedResult.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectedResult.getData()));
|
||||
}else{
|
||||
@@ -276,7 +269,7 @@ public class FaceDetDemo {
|
||||
JOptionPane.showConfirmDialog(null, "Failed to capture image from WebCam.");
|
||||
}
|
||||
ViewerFrame frame = new ViewerFrame(width, height);
|
||||
ImageFactory factory = ImageFactory.getInstance();
|
||||
SmartImageFactory factory = SmartImageFactory.getInstance();
|
||||
Size size = new Size(width, height);
|
||||
|
||||
while (capture.isOpened()) {
|
||||
@@ -285,9 +278,8 @@ public class FaceDetDemo {
|
||||
}
|
||||
Mat resizeImage = new Mat();
|
||||
Imgproc.resize(image, resizeImage, size);
|
||||
Image img = factory.fromImage(resizeImage);
|
||||
BufferedImage bufferedImage = OpenCVUtils.mat2Image(resizeImage);
|
||||
R<DetectionResponse> detectedResult = faceModel.detect(bufferedImage);
|
||||
Image img = factory.fromMat(resizeImage);
|
||||
R<DetectionResponse> detectedResult = faceModel.detect(img);
|
||||
if(!detectedResult.isSuccess()){
|
||||
log.debug("识别失败:{}", detectedResult.getMessage());
|
||||
continue;
|
||||
@@ -298,11 +290,10 @@ public class FaceDetDemo {
|
||||
if(detectionInfo.getScore() > 0){
|
||||
text = detectionInfo.getScore() + "";
|
||||
}
|
||||
ImageUtils.drawImageRectWithText(bufferedImage, detectionRectangle, text, Color.red);
|
||||
ImageUtils.drawRectAndText(img, detectionRectangle, text);
|
||||
}
|
||||
frame.showImage(bufferedImage);
|
||||
frame.showImage(ImageUtils.toBufferedImage(img));
|
||||
}
|
||||
|
||||
capture.release();
|
||||
System.exit(0);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package smartai.examples.face.facerec;
|
||||
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import ai.djl.modality.cv.Image;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
import cn.smartjavaai.common.entity.R;
|
||||
import cn.smartjavaai.common.entity.face.FaceSearchResult;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.utils.BufferedImageUtils;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
import cn.smartjavaai.face.config.FaceDetConfig;
|
||||
import cn.smartjavaai.face.config.FaceRecConfig;
|
||||
import cn.smartjavaai.face.constant.FaceDetectConstant;
|
||||
@@ -18,7 +21,6 @@ import cn.smartjavaai.face.factory.FaceDetModelFactory;
|
||||
import cn.smartjavaai.face.factory.FaceRecModelFactory;
|
||||
import cn.smartjavaai.face.model.facedect.FaceDetModel;
|
||||
import cn.smartjavaai.face.model.facerec.FaceRecModel;
|
||||
import cn.smartjavaai.face.utils.SimilarityUtil;
|
||||
import cn.smartjavaai.face.vector.config.MilvusConfig;
|
||||
import cn.smartjavaai.face.vector.config.SQLiteConfig;
|
||||
import cn.smartjavaai.face.vector.entity.FaceVector;
|
||||
@@ -28,6 +30,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@@ -45,6 +48,8 @@ public class FaceRecDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -61,7 +66,7 @@ public class FaceRecDemo {
|
||||
//人脸检测模型,SmartJavaAI提供了多种模型选择(更多模型,请查看文档),切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(FaceDetModelEnum.MTCNN);
|
||||
//下载模型并替换本地路径,下载地址:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/face_model");
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/face_model/mtcnn");
|
||||
//只返回相似度大于该值的人脸,需要根据实际情况调整,分值越大越严格容易漏检,分值越小越宽松容易误识别
|
||||
config.setConfidenceThreshold(0.5f);
|
||||
//用于去除重复的人脸框,当两个框的重叠度超过该值时,只保留一个
|
||||
@@ -116,19 +121,19 @@ public class FaceRecDemo {
|
||||
* 也可以使用其他模型,具体其他模型参数可以查看文档:http://doc.smartjavaai.cn/face.html
|
||||
* @return
|
||||
*/
|
||||
public FaceRecModel getHighAccuracyFaceRecModel(){
|
||||
public FaceRecModel getFaceRecModel(){
|
||||
FaceRecConfig config = new FaceRecConfig();
|
||||
//高精度模型,速度慢
|
||||
config.setModelEnum(FaceRecModelEnum.ELASTIC_FACE_MODEL);
|
||||
config.setModelEnum(FaceRecModelEnum.INSIGHT_FACE_IRSE50_MODEL);
|
||||
//模型路径,请下载模型并替换为本地路径:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/elasticface.pt");
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/face_model/recognition/InsightFace/model_ir_se50.pt");
|
||||
//裁剪人脸:如果图片已经是裁剪过的,则请将此参数设置为false
|
||||
config.setCropFace(true);
|
||||
//开启人脸对齐:适用于人脸不正的场景,开启将提升人脸特征准确度,关闭可以提升性能
|
||||
config.setAlign(true);
|
||||
config.setDevice(device);
|
||||
//指定人脸检测模型
|
||||
config.setDetectModel(getProFaceDetModel());
|
||||
config.setDetectModel(getFaceDetModel());
|
||||
return FaceRecModelFactory.getInstance().getModel(config);
|
||||
}
|
||||
|
||||
@@ -141,9 +146,9 @@ public class FaceRecDemo {
|
||||
public FaceRecModel getHighSpeedFaceRecModel(){
|
||||
FaceRecConfig config = new FaceRecConfig();
|
||||
//模型枚举
|
||||
config.setModelEnum(FaceRecModelEnum.SEETA_FACE6_LIGHT_MODEL);
|
||||
config.setModelEnum(FaceRecModelEnum.INSIGHT_FACE_MOBILE_FACENET_MODEL);
|
||||
//模型路径,请下载模型并替换为本地路径:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/xxx/Documents/develop/model/sf3.0_models");
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/face_model/recognition/InsightFace/model_mobilefacenet.pt");
|
||||
//裁剪人脸:如果图片已经是裁剪过的,则请将此参数设置为false
|
||||
config.setCropFace(true);
|
||||
//开启人脸对齐:适用于人脸不正的场景,开启将提升人脸特征准确度,关闭可以提升性能
|
||||
@@ -161,8 +166,9 @@ public class FaceRecDemo {
|
||||
public FaceRecModel getFaceRecModelWithDbConfig(){
|
||||
FaceRecConfig config = new FaceRecConfig();
|
||||
//高精度模型,速度慢,追求速度请更换高速模型,具体其他模型参数可以查看文档:http://doc.smartjavaai.cn/face.html
|
||||
config.setModelEnum(FaceRecModelEnum.ELASTIC_FACE_MODEL);//人脸识别模型
|
||||
config.setModelPath("/Users/xxx/Documents/develop/model/elasticface.pt");
|
||||
config.setModelEnum(FaceRecModelEnum.INSIGHT_FACE_IRSE50_MODEL);
|
||||
//模型路径,请下载模型并替换为本地路径:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/face_model/recognition/InsightFace/model_ir_se50.pt");
|
||||
//裁剪人脸:如果图片已经是裁剪过的,则请将此参数设置为false
|
||||
config.setCropFace(true);
|
||||
//开启人脸对齐:适用于人脸不正的场景,开启将提升人脸特征准确度,关闭可以提升性能
|
||||
@@ -175,9 +181,9 @@ public class FaceRecDemo {
|
||||
MilvusConfig vectorDBConfig = new MilvusConfig();
|
||||
vectorDBConfig.setHost("127.0.0.1");
|
||||
vectorDBConfig.setPort(19530);
|
||||
//vectorDBConfig.setUsername("root");
|
||||
//vectorDBConfig.setPassword("Milvus");
|
||||
//vectorDBConfig.setCollectionName("face5");
|
||||
// vectorDBConfig.setUsername("root");
|
||||
// vectorDBConfig.setPassword("Milvus");
|
||||
// vectorDBConfig.setCollectionName("face6");
|
||||
//ID策略:自动生成
|
||||
vectorDBConfig.setIdStrategy(IdStrategy.AUTO);
|
||||
//索引类型:内积 (Inner Product) 不建议修改
|
||||
@@ -193,8 +199,9 @@ public class FaceRecDemo {
|
||||
public FaceRecModel getFaceRecModelWithSQLiteConfig(){
|
||||
FaceRecConfig config = new FaceRecConfig();
|
||||
//高精度模型,速度慢, 追求速度请更换高速模型,具体其他模型参数可以查看文档:http://doc.smartjavaai.cn/face.html
|
||||
config.setModelEnum(FaceRecModelEnum.ELASTIC_FACE_MODEL);//人脸检测模型
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/elasticface.pt");
|
||||
config.setModelEnum(FaceRecModelEnum.INSIGHT_FACE_IRSE50_MODEL);
|
||||
//模型路径,请下载模型并替换为本地路径:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/face_model/recognition/InsightFace/model_ir_se50.pt");
|
||||
//裁剪人脸:如果图片已经是裁剪过的,则请将此参数设置为false
|
||||
config.setCropFace(true);
|
||||
//开启人脸对齐:适用于人脸不正的场景,开启将提升人脸特征准确度,关闭可以提升性能
|
||||
@@ -221,9 +228,11 @@ public class FaceRecDemo {
|
||||
public void testExtractFeatures(){
|
||||
try {
|
||||
//高精度模型,速度慢, 追求速度请更换高速模型: getHighSpeedFaceRecModel
|
||||
FaceRecModel faceRecModel = getHighAccuracyFaceRecModel();
|
||||
FaceRecModel faceRecModel = getFaceRecModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
//提取图片中所有人脸特征
|
||||
R<DetectionResponse> faceResult = faceRecModel.extractFeatures("src/main/resources/iu_1.jpg");
|
||||
R<DetectionResponse> faceResult = faceRecModel.extractFeatures(image);
|
||||
if(faceResult.isSuccess()){
|
||||
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(faceResult.getData()));
|
||||
}else{
|
||||
@@ -246,15 +255,59 @@ public class FaceRecDemo {
|
||||
public void featureComparison(){
|
||||
try {
|
||||
//高精度模型,速度慢, 追求速度请更换高速模型: getHighSpeedFaceRecModel
|
||||
FaceRecModel faceRecModel = getHighAccuracyFaceRecModel();
|
||||
FaceRecModel faceRecModel = getFaceRecModel();
|
||||
//基于图像直接比对人脸特征
|
||||
R<Float> similarResult = faceRecModel.featureComparison("src/main/resources/iu_1.jpg","src/main/resources/iu_2.jpg");
|
||||
if(similarResult.isSuccess()){
|
||||
//相似度阈值不同模型不同,具体参看文档
|
||||
log.info("人脸比对相似度:{}", JSONObject.toJSONString(similarResult.getData()));
|
||||
//不同模型的相似度标准不同。当前阈值仅适用于 insight_face 模型,切换模型时请相应调整阈值,详情请参考文档。
|
||||
if(similarResult.getData() >= 0.62f){
|
||||
log.info("识别为同一人");
|
||||
}else{
|
||||
log.info("识别为不同人");
|
||||
}
|
||||
}else{
|
||||
log.info("人脸比对失败:{}", similarResult.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 人脸比对1:1(基于图像直接比对)
|
||||
* 流程:从输入图像中裁剪分数最高的人脸 → 提取其人脸特征 → 比对两张图片中提取的人脸特征。(接口内自动完成)
|
||||
* 注意事项:
|
||||
* 1、首次调用接口,可能会较慢。只要不关闭程序,后续调用会明显加快。若每次重启程序,则每次首次调用都将重新加载,仍会较慢。
|
||||
* 2、若人脸朝向不正,可开启人脸对齐以提升特征提取准确度。(方法参考自定义配置人脸特征提取)
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void featureComparison3(){
|
||||
try {
|
||||
//高精度模型,速度慢, 追求速度请更换高速模型: getHighSpeedFaceRecModel
|
||||
FaceRecModel faceRecModel = getFaceRecModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image1 = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
Image image2 = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_2.jpg");
|
||||
//基于图像直接比对人脸特征
|
||||
R<Float> similarResult = faceRecModel.featureComparison(image1, image2);
|
||||
if(similarResult.isSuccess()){
|
||||
//相似度阈值不同模型不同,具体参看文档
|
||||
log.info("人脸比对相似度:{}", JSONObject.toJSONString(similarResult.getData()));
|
||||
//不同模型的相似度标准不同。当前阈值仅适用于 insight_face 模型,切换模型时请相应调整阈值,详情请参考文档。
|
||||
if(similarResult.getData() >= 0.62f){
|
||||
log.info("识别为同一人");
|
||||
}else{
|
||||
log.info("识别为不同人");
|
||||
}
|
||||
}else{
|
||||
log.info("人脸比对失败:{}", similarResult.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
@@ -273,9 +326,11 @@ public class FaceRecDemo {
|
||||
public void featureComparison2(){
|
||||
try {
|
||||
//高精度模型,速度慢, 追求速度请更换高速模型: getHighSpeedFaceRecModel
|
||||
FaceRecModel faceRecModel = getHighAccuracyFaceRecModel();
|
||||
FaceRecModel faceRecModel = getFaceRecModel();
|
||||
//特征提取(提取分数最高人脸特征),适用于单人脸场景
|
||||
R<float[]> featureResult1 = faceRecModel.extractTopFaceFeature("src/main/resources/iu_1.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image1 = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
R<float[]> featureResult1 = faceRecModel.extractTopFaceFeature(image1);
|
||||
if(featureResult1.isSuccess()){
|
||||
log.info("图片1人脸特征提取成功:{}", JSONObject.toJSONString(featureResult1.getData()));
|
||||
}else{
|
||||
@@ -283,7 +338,8 @@ public class FaceRecDemo {
|
||||
return;
|
||||
}
|
||||
//特征提取(提取分数最高人脸特征),适用于单人脸场景
|
||||
R<float[]> featureResult2 = faceRecModel.extractTopFaceFeature("src/main/resources/iu_2.jpg");
|
||||
Image image2 = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_2.jpg");
|
||||
R<float[]> featureResult2 = faceRecModel.extractTopFaceFeature(image2);
|
||||
if(featureResult2.isSuccess()){
|
||||
log.info("图片2人脸特征提取成功:{}", JSONObject.toJSONString(featureResult2.getData()));
|
||||
}else{
|
||||
@@ -293,6 +349,12 @@ public class FaceRecDemo {
|
||||
//计算相似度
|
||||
float similar = faceRecModel.calculSimilar(featureResult1.getData(), featureResult2.getData());
|
||||
log.info("相似度:{}", similar);
|
||||
//不同模型的相似度标准不同。当前阈值仅适用于 insight_face 模型,切换模型时请相应调整阈值,详情请参考文档。
|
||||
if(similar >= 0.62f){
|
||||
log.info("识别为同一人");
|
||||
}else{
|
||||
log.info("识别为不同人");
|
||||
}
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
@@ -318,8 +380,10 @@ public class FaceRecDemo {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
log.info("====================人脸注册==========================");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
//特征提取(提取分数最高人脸特征),适用于单人脸场景
|
||||
R<float[]> featureResult = faceRecModel.extractTopFaceFeature("src/main/resources/iu_1.jpg");
|
||||
R<float[]> featureResult = faceRecModel.extractTopFaceFeature(image);
|
||||
if(featureResult.isSuccess()){
|
||||
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult.getData()));
|
||||
}else{
|
||||
@@ -341,21 +405,23 @@ public class FaceRecDemo {
|
||||
}else{
|
||||
log.info("注册失败:{}", registerResult.getMessage());
|
||||
}
|
||||
/*log.info("====================人脸更新==========================");
|
||||
log.info("====================人脸更新==========================");
|
||||
//更新人脸 只支持自定义ID:vectorDBConfig.setIdStrategy(IdStrategy.CUSTOM);
|
||||
FaceRegisterInfo updateInfo = new FaceRegisterInfo();
|
||||
//设置人脸注册的自定义元数据,本例中使用 JSON 格式存储用户信息
|
||||
JSONObject metadataJsonUpdate = new JSONObject();
|
||||
metadataJsonUpdate.put("name", "iu_update");
|
||||
metadataJsonUpdate.put("age", "25");
|
||||
updateInfo.setMetadata(metadataJsonUpdate.toJSONString());
|
||||
//更新必须设置ID,只有
|
||||
updateInfo.setId(registerResult.getData());
|
||||
faceRecModel.upsertFace(updateInfo, "src/main/resources/iu_2.jpg");
|
||||
log.info("更新人脸成功");*/
|
||||
// FaceRegisterInfo updateInfo = new FaceRegisterInfo();
|
||||
// //设置人脸注册的自定义元数据,本例中使用 JSON 格式存储用户信息
|
||||
// JSONObject metadataJsonUpdate = new JSONObject();
|
||||
// metadataJsonUpdate.put("name", "iu_update");
|
||||
// metadataJsonUpdate.put("age", "25");
|
||||
// updateInfo.setMetadata(metadataJsonUpdate.toJSONString());
|
||||
// //更新必须设置ID,只有
|
||||
// updateInfo.setId(registerResult.getData());
|
||||
// Image image2 = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_2.jpg");
|
||||
// faceRecModel.upsertFace(updateInfo, image2);
|
||||
// log.info("更新人脸成功");
|
||||
log.info("====================人脸查询==========================");
|
||||
//特征提取(提取分数最高人脸特征),适用于单人脸场景
|
||||
R<float[]> featureResult2 = faceRecModel.extractTopFaceFeature("src/main/resources/iu_3.jpg");
|
||||
Image image3 = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_3.jpg");
|
||||
R<float[]> featureResult2 = faceRecModel.extractTopFaceFeature(image3);
|
||||
if(featureResult2.isSuccess()){
|
||||
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult2.getData()));
|
||||
}else{
|
||||
@@ -364,8 +430,7 @@ public class FaceRecDemo {
|
||||
}
|
||||
FaceSearchParams faceSearchParams = new FaceSearchParams();
|
||||
faceSearchParams.setTopK(1);
|
||||
faceSearchParams.setThreshold(0.8f);
|
||||
|
||||
// faceSearchParams.setThreshold(0.62f);
|
||||
List<FaceSearchResult> faceSearchResults = faceRecModel.search(featureResult2.getData(), faceSearchParams);
|
||||
// R<DetectionResponse> faceSearchResults = faceModel.search("src/main/resources/face/iu_3.jpg", faceSearchParams);
|
||||
log.info("人脸查询结果:{}", JSONArray.toJSONString(faceSearchResults));
|
||||
@@ -397,7 +462,9 @@ public class FaceRecDemo {
|
||||
}
|
||||
log.info("====================人脸注册==========================");
|
||||
//特征提取(提取分数最高人脸特征),适用于单人脸场景
|
||||
R<float[]> featureResult = faceRecModel.extractTopFaceFeature("src/main/resources/iu_1.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
R<float[]> featureResult = faceRecModel.extractTopFaceFeature(image);
|
||||
if(featureResult.isSuccess()){
|
||||
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult.getData()));
|
||||
}else{
|
||||
@@ -429,11 +496,13 @@ public class FaceRecDemo {
|
||||
updateInfo.setMetadata(metadataJsonUpdate.toJSONString());
|
||||
//更新必须设置ID,只有
|
||||
updateInfo.setId(registerResult.getData());
|
||||
faceRecModel.upsertFace(updateInfo, "src/main/resources/iu_2.jpg");
|
||||
Image image2 = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_2.jpg");
|
||||
faceRecModel.upsertFace(updateInfo, image2);
|
||||
log.info("更新人脸成功");
|
||||
log.info("====================人脸查询==========================");
|
||||
//特征提取(提取分数最高人脸特征),适用于单人脸场景
|
||||
R<float[]> featureResult2 = faceRecModel.extractTopFaceFeature("src/main/resources/iu_3.jpg");
|
||||
Image image3 = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_3.jpg");
|
||||
R<float[]> featureResult2 = faceRecModel.extractTopFaceFeature(image3);
|
||||
if(featureResult2.isSuccess()){
|
||||
log.info("人脸特征提取成功:{}", JSONObject.toJSONString(featureResult2.getData()));
|
||||
}else{
|
||||
@@ -442,7 +511,7 @@ public class FaceRecDemo {
|
||||
}
|
||||
FaceSearchParams faceSearchParams = new FaceSearchParams();
|
||||
faceSearchParams.setTopK(1);
|
||||
faceSearchParams.setThreshold(0.8f);
|
||||
//faceSearchParams.setThreshold(0.62f);
|
||||
List<FaceSearchResult> faceSearchResults = faceRecModel.search(featureResult2.getData(), faceSearchParams);
|
||||
log.info("人脸查询结果:{}", JSONArray.toJSONString(faceSearchResults));
|
||||
log.info("====================人脸删除==========================");
|
||||
@@ -454,6 +523,57 @@ public class FaceRecDemo {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 人脸查询及绘制
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void searchFace3(){
|
||||
try {
|
||||
//高精度模型,速度慢, 追求速度请更换高速模型
|
||||
FaceRecModel faceRecModel = getFaceRecModelWithSQLiteConfig();
|
||||
//等待加载人脸库结束
|
||||
while (!faceRecModel.isLoadFaceCompleted()){
|
||||
Thread.sleep(100);
|
||||
}
|
||||
log.info("====================人脸注册==========================");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
//人脸注册信息
|
||||
FaceRegisterInfo faceRegisterInfo = new FaceRegisterInfo();
|
||||
//设置人脸注册的自定义元数据,本例中使用 JSON 格式存储用户信息
|
||||
JSONObject metadataJson = new JSONObject();
|
||||
metadataJson.put("name", "iu");
|
||||
metadataJson.put("age", "25");
|
||||
faceRegisterInfo.setMetadata(metadataJson.toJSONString());
|
||||
//可自定义 ID,若未设置则自动生成。
|
||||
//faceRegisterInfo.setId("00001");
|
||||
//人脸注册,返回人脸库ID
|
||||
R<String> registerResult = faceRecModel.register(faceRegisterInfo, image);
|
||||
if(registerResult.isSuccess()){
|
||||
log.info("注册成功:ID-{}", registerResult.getData());
|
||||
}else{
|
||||
log.info("注册失败:{}", registerResult.getMessage());
|
||||
}
|
||||
log.info("====================人脸查询==========================");
|
||||
//特征提取(提取分数最高人脸特征),适用于单人脸场景
|
||||
Image image3 = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_3.jpg");
|
||||
FaceSearchParams faceSearchParams = new FaceSearchParams();
|
||||
faceSearchParams.setTopK(1);
|
||||
//faceSearchParams.setThreshold(0.62f);
|
||||
//图片中只会显示Metadata信息中name的字段
|
||||
Image drawSearchResult = faceRecModel.drawSearchResult(image3, faceSearchParams, "name");
|
||||
ImageUtils.save(drawSearchResult, "output/search_result.jpg");
|
||||
log.info("====================人脸删除==========================");
|
||||
faceRecModel.removeRegister(registerResult.getData());
|
||||
log.info("人脸删除成功");
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取人脸信息
|
||||
@@ -486,7 +606,7 @@ public class FaceRecDemo {
|
||||
public void listFaces(){
|
||||
//使用ID获取人脸信息
|
||||
try {
|
||||
FaceRecModel faceRecModel = getFaceRecModelWithDbConfig();
|
||||
FaceRecModel faceRecModel = getFaceRecModelWithSQLiteConfig();
|
||||
//等待加载人脸库结束
|
||||
while (!faceRecModel.isLoadFaceCompleted()){
|
||||
Thread.sleep(100);
|
||||
|
||||
@@ -4,6 +4,7 @@ import ai.djl.modality.cv.Image;
|
||||
import ai.djl.modality.cv.ImageFactory;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.DetectionInfo;
|
||||
import cn.smartjavaai.common.entity.DetectionRectangle;
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
@@ -65,6 +66,8 @@ public class LivenessDetDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -104,9 +107,9 @@ public class LivenessDetDemo {
|
||||
config.setModelEnum(LivenessModelEnum.MINI_VISION_MODEL);
|
||||
config.setDevice(device);
|
||||
//模型1路径:需替换为实际模型存储路径
|
||||
config.setModelPath("/Users/xxx/Documents/develop/model/live/2.7_80x80_MiniFASNetV2.onnx");
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/live/2.7_80x80_MiniFASNetV2.onnx");
|
||||
//SE模型路径:需替换为实际模型存储路径
|
||||
config.putCustomParam("seModelPath", "/Users/xxx/Documents/develop/model/live/4_0_0_80x80_MiniFASNetV1SE.onnx");
|
||||
config.putCustomParam("seModelPath", "/Users/wenjie/Documents/develop/model/live/4_0_0_80x80_MiniFASNetV1SE.onnx");
|
||||
//人脸活体阈值,可选,超过阈值则认为是真人,低于阈值是非活体
|
||||
config.setRealityThreshold(0.5f);
|
||||
/*视频检测帧数,可选,默认10,输出帧数超过这个number之后,就可以输出识别结果。
|
||||
@@ -132,7 +135,7 @@ public class LivenessDetDemo {
|
||||
//人脸检测模型,SmartJavaAI提供了多种模型选择(更多模型,请查看文档),切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(FaceDetModelEnum.MTCNN);
|
||||
//下载模型并替换本地路径,下载地址:https://pan.baidu.com/s/10l22x5fRz_gwLr8EAHa1Jg?pwd=1234 提取码: 1234
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/face_model");
|
||||
config.setModelPath("/Users/wenjie/Documents/develop/model/face_model/mtcnn");
|
||||
//只返回相似度大于该值的人脸,需要根据实际情况调整,分值越大越严格容易漏检,分值越小越宽松容易误识别
|
||||
config.setConfidenceThreshold(0.5f);
|
||||
//用于去除重复的人脸框,当两个框的重叠度超过该值时,只保留一个
|
||||
@@ -149,10 +152,12 @@ public class LivenessDetDemo {
|
||||
public void testLivenessDetect(){
|
||||
try {
|
||||
LivenessDetModel livenessDetModel = getLivenessDetModel();
|
||||
R<DetectionResponse> response = livenessDetModel.detect("src/main/resources/liveness/1.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/liveness/1.jpg");
|
||||
R<DetectionResponse> response = livenessDetModel.detect(image);
|
||||
if(response.isSuccess()){
|
||||
for (DetectionInfo detectionInfo : response.getData().getDetectionInfoList()){
|
||||
log.info("活体检测结果:{}", JSONObject.toJSONString(detectionInfo.getFaceInfo().getLivenessStatus().getStatus().getDescription()));
|
||||
log.info("活体检测结果:{}", JSONObject.toJSONString(detectionInfo));
|
||||
}
|
||||
}else{
|
||||
log.info("活体检测失败:{}", response.getMessage());
|
||||
@@ -169,18 +174,18 @@ public class LivenessDetDemo {
|
||||
public void testLivenessDetectAndDraw(){
|
||||
try {
|
||||
LivenessDetModel livenessDetModel = getLivenessDetModel();
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/liveness/1.jpg").toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/liveness/1.jpg");
|
||||
R<DetectionResponse> response = livenessDetModel.detect(image);
|
||||
if(response.isSuccess()){
|
||||
for (DetectionInfo detectionInfo : response.getData().getDetectionInfoList()){
|
||||
log.info("活体检测结果:{}", JSONObject.toJSONString(detectionInfo.getFaceInfo().getLivenessStatus().getStatus().getDescription()));
|
||||
Color color = detectionInfo.getFaceInfo().getLivenessStatus().getStatus() == LivenessStatus.LIVE ? Color.GREEN : Color.RED;
|
||||
ImageUtils.drawImageRectWithText(image, detectionInfo.getDetectionRectangle(), detectionInfo.getFaceInfo().getLivenessStatus().getStatus().getDescription(), color);
|
||||
ImageUtils.drawRectAndText(image, detectionInfo.getDetectionRectangle(), detectionInfo.getFaceInfo().getLivenessStatus().getStatus().toString());
|
||||
ImageUtils.save(image, "output/detect.jpg");
|
||||
}
|
||||
}else{
|
||||
log.info("活体检测失败:{}", response.getMessage());
|
||||
}
|
||||
ImageUtils.saveImage(image, "output/detect.jpg");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -194,10 +199,12 @@ public class LivenessDetDemo {
|
||||
try {
|
||||
LivenessDetModel livenessDetModel = getLivenessDetModel();
|
||||
//指定文件夹路径
|
||||
File dir = new File("face-example/src/main/resources/liveness");
|
||||
File dir = new File("src/main/resources/liveness");
|
||||
File[] files = dir.listFiles();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
SmartImageFactory imageFactory = SmartImageFactory.getInstance();
|
||||
for (File file : files) {
|
||||
R<LivenessResult> response = livenessDetModel.detectTopFace(ImageIO.read(file));
|
||||
R<LivenessResult> response = livenessDetModel.detectTopFace(imageFactory.fromFile(file));
|
||||
if(response.isSuccess()){
|
||||
log.info("{}活体检测结果:{},分数:{}", file.getName(), response.getData().getStatus().getDescription(), response.getData().getScore());
|
||||
}else{
|
||||
@@ -218,8 +225,8 @@ public class LivenessDetDemo {
|
||||
try {
|
||||
FaceDetModel faceDetectModel = getFaceDetModel();
|
||||
LivenessDetModel livenessDetModel = getLivenessDetModel();
|
||||
// 将图片路径转换为 BufferedImage
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/liveness/1.jpg").toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/liveness/1.jpg");
|
||||
//人脸检测
|
||||
R<DetectionResponse> detectionResponse = faceDetectModel.detect(image);
|
||||
if(detectionResponse.isSuccess()){
|
||||
@@ -251,8 +258,8 @@ public class LivenessDetDemo {
|
||||
try {
|
||||
FaceDetModel faceDetModel = getFaceDetModel();
|
||||
LivenessDetModel livenessDetModel = getMiniVisionLivenessDetModel();
|
||||
// 将图片路径转换为 BufferedImage
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/liveness/1.jpg").toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/liveness/1.jpg");
|
||||
R<DetectionResponse> detResult = faceDetModel.detect(image);
|
||||
if(detResult.isSuccess()){
|
||||
for (DetectionInfo detectionInfo : detResult.getData().getDetectionInfoList()) {
|
||||
@@ -281,7 +288,7 @@ public class LivenessDetDemo {
|
||||
try {
|
||||
LivenessDetModel livenessDetModel = getLivenessDetModel();
|
||||
//视频路径
|
||||
R<LivenessResult> livenessStatus = livenessDetModel.detectVideo("video.mp4");
|
||||
R<LivenessResult> livenessStatus = livenessDetModel.detectVideo("/Users/wenjie/Documents/idea_workplace/SmartJavaAI-Demo/src/main/resources/girl.mp4");
|
||||
if (livenessStatus.isSuccess()){
|
||||
log.info("识别结果:{}", JSONObject.toJSONString(livenessStatus.getData()));
|
||||
}else{
|
||||
@@ -296,7 +303,7 @@ public class LivenessDetDemo {
|
||||
* 摄像头活体检测
|
||||
* 注意事项:如果视频比较卡,可以使用轻量的人脸检测模型
|
||||
*/
|
||||
@Test
|
||||
// @Test
|
||||
public void testLivenessDetectCamera(){
|
||||
try {
|
||||
LivenessDetModel livenessDetModel = getLivenessDetModel();
|
||||
@@ -335,7 +342,7 @@ public class LivenessDetDemo {
|
||||
JOptionPane.showConfirmDialog(null, "Failed to capture image from WebCam.");
|
||||
}
|
||||
ViewerFrame frame = new ViewerFrame(width, height);
|
||||
ImageFactory factory = ImageFactory.getInstance();
|
||||
SmartImageFactory factory = SmartImageFactory.getInstance();
|
||||
Size size = new Size(width, height);
|
||||
|
||||
while (capture.isOpened()) {
|
||||
@@ -344,9 +351,8 @@ public class LivenessDetDemo {
|
||||
}
|
||||
Mat resizeImage = new Mat();
|
||||
Imgproc.resize(image, resizeImage, size);
|
||||
Image img = factory.fromImage(resizeImage);
|
||||
BufferedImage bufferedImage = OpenCVUtils.mat2Image(resizeImage);
|
||||
R<DetectionResponse> detectedResult = livenessDetModel.detect(bufferedImage);
|
||||
Image img = factory.fromMat(resizeImage);
|
||||
R<DetectionResponse> detectedResult = livenessDetModel.detect(img);
|
||||
if(!detectedResult.isSuccess()){
|
||||
log.debug("识别失败:{}", detectedResult.getMessage());
|
||||
continue;
|
||||
@@ -355,11 +361,10 @@ public class LivenessDetDemo {
|
||||
DetectionRectangle detectionRectangle = detectionInfo.getDetectionRectangle();
|
||||
Color color = detectionInfo.getFaceInfo().getLivenessStatus().getStatus() == LivenessStatus.LIVE ? Color.GREEN : Color.RED;
|
||||
String text = detectionInfo.getFaceInfo().getLivenessStatus().getStatus().getDescription() + ":" + detectionInfo.getFaceInfo().getLivenessStatus().getScore();
|
||||
ImageUtils.drawImageRectWithText(bufferedImage, detectionRectangle, text, color);
|
||||
ImageUtils.drawRectAndText(img, detectionRectangle, text);
|
||||
}
|
||||
frame.showImage(bufferedImage);
|
||||
frame.showImage(ImageUtils.toBufferedImage(img));
|
||||
}
|
||||
|
||||
capture.release();
|
||||
System.exit(0);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package smartai.examples.face.quality;
|
||||
|
||||
import ai.djl.modality.cv.Image;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.DetectionInfo;
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
import cn.smartjavaai.common.entity.R;
|
||||
@@ -47,6 +49,8 @@ public class FaceQualityDetDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -62,7 +66,7 @@ public class FaceQualityDetDemo {
|
||||
QualityConfig config = new QualityConfig();
|
||||
config.setModelEnum(QualityModelEnum.SEETA_FACE6_MODEL);
|
||||
//需替换为实际模型存储路径
|
||||
config.setModelPath("C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models");
|
||||
config.setModelPath("C:/Users/DengWenJie/Downloads/sf3.0_models/sf3.0_models");
|
||||
config.setDevice(device);
|
||||
return FaceQualityModelFactory.getInstance().getModel(config);
|
||||
}
|
||||
@@ -74,7 +78,7 @@ public class FaceQualityDetDemo {
|
||||
*/
|
||||
public FaceDetModel getFaceDetModel() {
|
||||
//需替换为实际模型存储路径
|
||||
String modelPath = "C:/Users/Administrator/Downloads/sf3.0_models/sf3.0_models";
|
||||
String modelPath = "C:/Users/DengWenJie/Downloads/sf3.0_models/sf3.0_models";
|
||||
FaceDetConfig faceDetectModelConfig = new FaceDetConfig();
|
||||
faceDetectModelConfig.setModelEnum(FaceDetModelEnum.SEETA_FACE6_MODEL);
|
||||
faceDetectModelConfig.setModelPath(modelPath);
|
||||
@@ -91,8 +95,9 @@ public class FaceQualityDetDemo {
|
||||
try {
|
||||
FaceQualityModel faceQualityModel = getFaceQualityModel();
|
||||
FaceDetModel faceDetModel = getFaceDetModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
//人脸检测
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/iu_1.jpg").toAbsolutePath().toString()));
|
||||
R<DetectionResponse> detectionResponse = faceDetModel.detect(image);
|
||||
if(detectionResponse.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectionResponse.getData()));
|
||||
@@ -124,8 +129,9 @@ public class FaceQualityDetDemo {
|
||||
try {
|
||||
FaceQualityModel faceQualityModel = getFaceQualityModel();
|
||||
FaceDetModel faceDetModel = getFaceDetModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
//人脸检测
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/iu_1.jpg").toAbsolutePath().toString()));
|
||||
R<DetectionResponse> detectionResponse = faceDetModel.detect(image);
|
||||
if(detectionResponse.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectionResponse.getData()));
|
||||
@@ -157,8 +163,8 @@ public class FaceQualityDetDemo {
|
||||
try {
|
||||
FaceQualityModel faceQualityModel = getFaceQualityModel();
|
||||
FaceDetModel faceDetModel = getFaceDetModel();
|
||||
//人脸检测
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/iu_1.jpg").toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
R<DetectionResponse> detectionResponse = faceDetModel.detect(image);
|
||||
if(detectionResponse.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectionResponse.getData()));
|
||||
@@ -190,8 +196,9 @@ public class FaceQualityDetDemo {
|
||||
try {
|
||||
FaceQualityModel faceQualityModel = getFaceQualityModel();
|
||||
FaceDetModel faceDetModel = getFaceDetModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
//人脸检测
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/iu_1.jpg").toAbsolutePath().toString()));
|
||||
R<DetectionResponse> detectionResponse = faceDetModel.detect(image);
|
||||
if(detectionResponse.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectionResponse.getData()));
|
||||
@@ -224,8 +231,9 @@ public class FaceQualityDetDemo {
|
||||
try {
|
||||
FaceQualityModel faceQualityModel = getFaceQualityModel();
|
||||
FaceDetModel faceDetModel = getFaceDetModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
//人脸检测
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/iu_1.jpg").toAbsolutePath().toString()));
|
||||
R<DetectionResponse> detectionResponse = faceDetModel.detect(image);
|
||||
if(detectionResponse.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectionResponse.getData()));
|
||||
@@ -258,8 +266,9 @@ public class FaceQualityDetDemo {
|
||||
try {
|
||||
FaceQualityModel faceQualityModel = getFaceQualityModel();
|
||||
FaceDetModel faceDetModel = getFaceDetModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/iu_1.jpg");
|
||||
//人脸检测
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get("src/main/resources/iu_1.jpg").toAbsolutePath().toString()));
|
||||
R<DetectionResponse> detectionResponse = faceDetModel.detect(image);
|
||||
if(detectionResponse.isSuccess()){
|
||||
log.info("人脸检测结果:{}", JSONObject.toJSONString(detectionResponse.getData()));
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 682 KiB After Width: | Height: | Size: 674 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 276 KiB After Width: | Height: | Size: 273 KiB |
@@ -12,7 +12,7 @@
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<smartjavaai.version>1.0.24</smartjavaai.version>
|
||||
<smartjavaai.version>1.0.25</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.ocr.common.OcrRecognizeDemo</exec.mainClass>
|
||||
|
||||
@@ -219,39 +219,6 @@
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- linux aarch64 平台 (保留对应平台的配置,可以减小包大小)-->
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp</artifactId>
|
||||
<version>${javacv.version}</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>ffmpeg</artifactId>
|
||||
<version>6.1.1-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>openblas</artifactId>
|
||||
<version>0.3.26-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<version>4.9.0-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -2,6 +2,7 @@ package smartai.examples.ocr.common;
|
||||
|
||||
import ai.djl.modality.cv.Image;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
@@ -43,6 +44,7 @@ public class OcrDetectionDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -56,7 +58,7 @@ public class OcrDetectionDemo {
|
||||
//指定检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL);
|
||||
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
config.setDetModelPath("/Users/xxx/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
config.setDetModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
config.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDetModel(config);
|
||||
}
|
||||
@@ -73,7 +75,9 @@ public class OcrDetectionDemo {
|
||||
public void detect(){
|
||||
try {
|
||||
OcrCommonDetModel model = getDetectionModel();
|
||||
List<OcrBox> boxes = model.detect("src/main/resources/ocr_1.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_1.jpg");
|
||||
List<OcrBox> boxes = model.detect(image);
|
||||
log.info("OCR检测结果:{}", JSONObject.toJSONString(boxes));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -97,6 +101,26 @@ public class OcrDetectionDemo {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本检测并绘制结果
|
||||
* 检测图像中的文本区域,仅检测文本框位置,不识别文字内容
|
||||
* 注意事项:
|
||||
* 1、批量检测时,模型应统一放在外层 try 中使用,避免重复加载,自动释放资源更安全。
|
||||
* 2、模型文件需要放在单独文件夹
|
||||
*/
|
||||
@Test
|
||||
public void detectAndDraw2(){
|
||||
try {
|
||||
OcrCommonDetModel model = getDetectionModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_1.jpg");
|
||||
Image resultImage = model.detectAndDraw(image);
|
||||
ImageUtils.save(resultImage, "output/ocr_1_detected2.jpg");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量文本检测:批量检测要求图片宽高一致
|
||||
@@ -110,7 +134,7 @@ public class OcrDetectionDemo {
|
||||
try {
|
||||
OcrCommonDetModel model = getDetectionModel();
|
||||
//批量检测要求图片宽高一致
|
||||
String folderPath = "/Users/xxx/Downloads/testing33";
|
||||
String folderPath = "/Users/wenjie/Downloads/testing33";
|
||||
//读取文件夹中所有图片
|
||||
List<Image> images = ImageUtils.readImagesFromFolder(folderPath);
|
||||
List<List<OcrBox>> ocrResult = model.batchDetectDJLImage(images);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package smartai.examples.ocr.common;
|
||||
|
||||
import ai.djl.modality.cv.Image;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
import cn.smartjavaai.ocr.config.DirectionModelConfig;
|
||||
import cn.smartjavaai.ocr.config.OcrDetModelConfig;
|
||||
import cn.smartjavaai.ocr.entity.OcrBox;
|
||||
@@ -46,7 +49,7 @@ public class OcrDirectionDetDemo {
|
||||
//指定行文本方向检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
directionModelConfig.setModelEnum(DirectionModelEnum.PP_LCNET_X0_25);
|
||||
//指定行文本方向检测模型路径,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
directionModelConfig.setModelPath("/Users/xxx/Documents/develop/model/ocr/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx");
|
||||
directionModelConfig.setModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx");
|
||||
directionModelConfig.setDevice(device);
|
||||
directionModelConfig.setTextDetModel(getDetectionModel());
|
||||
return OcrModelFactory.getInstance().getDirectionModel(directionModelConfig);
|
||||
@@ -61,7 +64,7 @@ public class OcrDirectionDetDemo {
|
||||
//指定检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL);
|
||||
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
config.setDetModelPath("/Users/xxx/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
config.setDetModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
config.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDetModel(config);
|
||||
}
|
||||
@@ -78,7 +81,9 @@ public class OcrDirectionDetDemo {
|
||||
public void detect(){
|
||||
try {
|
||||
OcrDirectionModel directionModel = getDirectionModel();
|
||||
List<OcrItem> itemList = directionModel.detect("src/main/resources/ocr_1.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_1.jpg");
|
||||
List<OcrItem> itemList = directionModel.detect(image);
|
||||
log.info("OCR方向检测结果1:{}", JSONObject.toJSONString(itemList));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -102,6 +107,25 @@ public class OcrDirectionDetDemo {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本检测并绘制结果
|
||||
* 流程:文本检测 -> 方向分类
|
||||
* 检测图像中的文本区域,仅检测文本框位置,不识别文字内容
|
||||
* 模型需要放在单独文件夹
|
||||
*/
|
||||
@Test
|
||||
public void detectAndDraw2(){
|
||||
try {
|
||||
OcrDirectionModel directionModel = getDirectionModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_1.jpg");
|
||||
Image resultImage = directionModel.detectAndDraw(image);
|
||||
ImageUtils.save(resultImage, "output/ocr_1_detected4.jpg");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import ai.djl.util.JsonUtils;
|
||||
import cn.hutool.core.img.ImgUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.utils.BufferedImageUtils;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
import cn.smartjavaai.ocr.config.DirectionModelConfig;
|
||||
import cn.smartjavaai.ocr.config.OcrDetModelConfig;
|
||||
@@ -48,34 +50,70 @@ public class OcrRecognizeDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
//Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通用识别模型(不带方向矫正)
|
||||
* 获取通用识别模型(高精确度模型)
|
||||
* 注意事项:高精度模型,识别准确度高,速度慢
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonRecModel getRecModel(){
|
||||
public OcrCommonRecModel getProRecModel(){
|
||||
OcrRecModelConfig recModelConfig = new OcrRecModelConfig();
|
||||
//指定文本识别模型,切换模型需要同时修改modelEnum及modelPath
|
||||
recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL);
|
||||
recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_SERVER_REC_MODEL);
|
||||
//指定识别模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
recModelConfig.setRecModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_server_rec_infer/PP-OCRv5_server_rec.onnx");
|
||||
recModelConfig.setDevice(device);
|
||||
recModelConfig.setTextDetModel(getDetectionModel());
|
||||
recModelConfig.setTextDetModel(getProDetectionModel());
|
||||
recModelConfig.setDirectionModel(getDirectionModel());
|
||||
return OcrModelFactory.getInstance().getRecModel(recModelConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文本检测模型
|
||||
* 获取通用识别模型(极速模型)
|
||||
* 注意事项:极速模型,识别准确度低,速度快
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonDetModel getDetectionModel() {
|
||||
public OcrCommonRecModel getFastRecModel(){
|
||||
OcrRecModelConfig recModelConfig = new OcrRecModelConfig();
|
||||
//指定文本识别模型,切换模型需要同时修改modelEnum及modelPath
|
||||
recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL);
|
||||
//指定识别模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
recModelConfig.setRecModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_mobile_rec_infer/PP-OCRv5_mobile_rec_infer.onnx");
|
||||
recModelConfig.setDevice(device);
|
||||
recModelConfig.setTextDetModel(getFastDetectionModel());
|
||||
return OcrModelFactory.getInstance().getRecModel(recModelConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取文本检测模型(极速模型)
|
||||
* 注意事项:极速模型,识别准确度低,速度快
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonDetModel getFastDetectionModel() {
|
||||
OcrDetModelConfig config = new OcrDetModelConfig();
|
||||
//指定检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL);
|
||||
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
config.setDetModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
config.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDetModel(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文本检测模型(高精确度模型)
|
||||
* 注意事项:高精度模型,识别准确度高,速度慢
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonDetModel getProDetectionModel() {
|
||||
OcrDetModelConfig config = new OcrDetModelConfig();
|
||||
//指定检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_SERVER_DET_MODEL);
|
||||
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
config.setDetModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
|
||||
config.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDetModel(config);
|
||||
@@ -90,28 +128,12 @@ public class OcrRecognizeDemo {
|
||||
//指定行文本方向检测模型,切换模型需要同时修改modelEnum及modelPath
|
||||
directionModelConfig.setModelEnum(DirectionModelEnum.PP_LCNET_X0_25);
|
||||
//指定行文本方向检测模型路径,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
directionModelConfig.setModelPath("/Users/xxx/Documents/develop/model/ocr/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx");
|
||||
directionModelConfig.setModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-LCNet_x0_25_textline_ori_infer/PP-LCNet_x0_25_textline_ori_infer.onnx");
|
||||
directionModelConfig.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDirectionModel(directionModelConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取通用识别模型(带方向矫正)
|
||||
* @return
|
||||
*/
|
||||
public OcrCommonRecModel getRecModelWithDirection() {
|
||||
OcrRecModelConfig recModelConfig = new OcrRecModelConfig();
|
||||
//指定文本识别模型,切换模型需要同时修改modelEnum及modelPath
|
||||
recModelConfig.setRecModelEnum(CommonRecModelEnum.PP_OCR_V5_MOBILE_REC_MODEL);
|
||||
//指定识别模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
recModelConfig.setRecModelPath("/Users/xxx/Documents/develop/model/ocr/PP-OCRv5_mobile_rec_infer/PP-OCRv5_mobile_rec_infer.onnx");
|
||||
recModelConfig.setDevice(device);
|
||||
recModelConfig.setTextDetModel(getDetectionModel());
|
||||
recModelConfig.setDirectionModel(getDirectionModel());
|
||||
return OcrModelFactory.getInstance().getRecModel(recModelConfig);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 文本识别
|
||||
@@ -124,10 +146,12 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void recognize(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
//不带方向矫正,分行返回文本
|
||||
OcrRecOptions options = new OcrRecOptions(false, true);
|
||||
OcrInfo ocrInfo = recModel.recognize("/Users/wenjie/Downloads/49421755855753_.pic_hd.jpg",options);
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_1.jpg");
|
||||
OcrInfo ocrInfo = recModel.recognize(image, options);
|
||||
log.info("OCR识别结果:{}", JSONObject.toJSONString(ocrInfo));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -146,8 +170,10 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void recognizeHandWriting(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
OcrInfo ocrInfo = recModel.recognize("src/main/resources/handwriting_1.jpg",new OcrRecOptions());
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/handwriting_1.jpg");
|
||||
OcrInfo ocrInfo = recModel.recognize(image, new OcrRecOptions());
|
||||
log.info("OCR识别结果:{}", JSONObject.toJSONString(ocrInfo));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -166,10 +192,12 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void recognize2(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModelWithDirection();
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
//带方向矫正,分行返回文本
|
||||
OcrRecOptions options = new OcrRecOptions(true, true);
|
||||
OcrInfo ocrInfo = recModel.recognize("src/main/resources/ocr_3.jpg",options);
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/ocr_3.jpg");
|
||||
OcrInfo ocrInfo = recModel.recognize(image, options);
|
||||
log.info("OCR识别结果:{}", JSONObject.toJSONString(ocrInfo));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -189,7 +217,7 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void recognizeAndDraw(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModelWithDirection();
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
int fontSize = 18;
|
||||
recModel.recognizeAndDraw("src/main/resources/general_ocr_002.png", "output/ocr_4_recognized.jpg", fontSize, new OcrRecOptions());
|
||||
} catch (Exception e) {
|
||||
@@ -200,55 +228,24 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void recognizeAndDraw2(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
int fontSize = 18;
|
||||
//创建保存路径
|
||||
Path inputImagePath = Paths.get("src/main/resources/general_ocr_002.png");
|
||||
Path imageOutputPath = Paths.get("output/ocr_4_recognized.jpg");
|
||||
BufferedImage image = null;
|
||||
image = ImageIO.read(new File(inputImagePath.toAbsolutePath().toString()));
|
||||
BufferedImage resultImage = recModel.recognizeAndDraw(image, fontSize, new OcrRecOptions());
|
||||
ImageUtils.saveImage(resultImage, imageOutputPath.toAbsolutePath().toString());
|
||||
Path imageOutputPath = Paths.get("output/ocr_5_recognized.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile(inputImagePath);
|
||||
OcrInfo ocrInfo = recModel.recognizeAndDraw(image, fontSize, new OcrRecOptions());
|
||||
log.info("OCR识别结果:{}", JSONObject.toJSONString(ocrInfo));
|
||||
//保存绘制结果
|
||||
if(ocrInfo != null && ocrInfo.getDrawnImage() != null){
|
||||
ImageUtils.save(ocrInfo.getDrawnImage(), imageOutputPath.toAbsolutePath().toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本识别并绘制结果(返回base64)
|
||||
*/
|
||||
@Test
|
||||
public void recognizeAndDrawToBase64(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
int fontSize = 18;
|
||||
//创建保存路径
|
||||
Path inputImagePath = Paths.get("src/main/resources/general_ocr_002.png");
|
||||
byte[] imageBytes = FileUtil.readBytes(inputImagePath);
|
||||
String base64 = recModel.recognizeAndDrawToBase64(imageBytes, fontSize, new OcrRecOptions());
|
||||
log.info("base64:{}", base64);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文本识别并绘制结果(返回OcrInfo,OcrInfo中包含base64)
|
||||
*/
|
||||
@Test
|
||||
public void recognizeAndDraw3(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
int fontSize = 18;
|
||||
//创建保存路径
|
||||
Path inputImagePath = Paths.get("src/main/resources/general_ocr_002.png");
|
||||
byte[] imageBytes = FileUtil.readBytes(inputImagePath);
|
||||
OcrInfo ocrInfo = recModel.recognizeAndDraw(imageBytes, fontSize, new OcrRecOptions());
|
||||
log.info("ocrInfo:{}", JsonUtils.toJson(ocrInfo));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量识别
|
||||
@@ -259,7 +256,7 @@ public class OcrRecognizeDemo {
|
||||
@Test
|
||||
public void batchRecognize(){
|
||||
try {
|
||||
OcrCommonRecModel recModel = getRecModelWithDirection();
|
||||
OcrCommonRecModel recModel = getFastRecModel();
|
||||
//批量检测要求图片宽高一致
|
||||
String folderPath = "/Users/xxx/Downloads/testing33";
|
||||
//读取文件夹中所有图片
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package smartai.examples.ocr.plate;
|
||||
|
||||
import ai.djl.modality.cv.Image;
|
||||
import ai.djl.util.JsonUtils;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.R;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
@@ -38,6 +40,7 @@ public class PlateRecDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -68,6 +71,7 @@ public class PlateRecDemo {
|
||||
recModelConfig.setModelPath("/Users/wenjie/Documents/develop/model/plate/plate_rec_color.onnx");
|
||||
//指定车牌检测模型
|
||||
recModelConfig.setPlateDetModel(getPlateDetModel());
|
||||
recModelConfig.setDevice(device);
|
||||
return PlateModelFactory.getInstance().getRecModel(recModelConfig);
|
||||
}
|
||||
|
||||
@@ -75,10 +79,12 @@ public class PlateRecDemo {
|
||||
* 车牌识别
|
||||
*/
|
||||
@Test
|
||||
public void testDetect() {
|
||||
public void testDetect() throws IOException {
|
||||
PlateRecModel plateRecModel = getPlateRecModel();
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/plate/Quicker_20220930_180856.png");
|
||||
//识别车号
|
||||
R<List<PlateInfo>> result = plateRecModel.recognize("src/main/resources/plate/Quicker_20220930_180856.png");
|
||||
R<List<PlateInfo>> result = plateRecModel.recognize(image);
|
||||
if(result.isSuccess()){
|
||||
log.info("车牌识别结果:{}", JsonUtils.toJson(result.getData()));
|
||||
}else{
|
||||
@@ -109,14 +115,14 @@ public class PlateRecDemo {
|
||||
public void recognizeAndDraw2() {
|
||||
try {
|
||||
PlateRecModel plateRecModel = getPlateRecModel();
|
||||
BufferedImage image = null;
|
||||
String imagePath = "src/main/resources/plate/Quicker_20220930_180856.png";
|
||||
image = ImageIO.read(new File(Paths.get(imagePath).toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile(imagePath);
|
||||
//可以根据后续业务场景使用detectedImage
|
||||
R<BufferedImage> detectedImage = plateRecModel.recognizeAndDraw(image);
|
||||
R<Image> detectedImage = plateRecModel.recognizeAndDraw(image);
|
||||
if(detectedImage.isSuccess()){
|
||||
log.info("车牌识别成功");
|
||||
ImageUtils.saveImage(detectedImage.getData(), "output/plate_recognized2.jpg");
|
||||
ImageUtils.save(detectedImage.getData(), "output/plate_recognized3.jpg");
|
||||
}else{
|
||||
log.error("车牌识别失败:{}", detectedImage.getMessage());
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package smartai.examples.ocr.table;
|
||||
import ai.djl.modality.cv.Image;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.smartjavaai.common.config.Config;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.R;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
@@ -47,6 +48,7 @@ public class TableRecDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -79,7 +81,6 @@ public class TableRecDemo {
|
||||
config.setModelEnum(CommonDetModelEnum.PP_OCR_V5_MOBILE_DET_MODEL);
|
||||
//指定模型位置,需要更改为自己的模型路径(下载地址请查看文档)
|
||||
config.setDetModelPath("/Users/wenjie/Documents/develop/model/ocr/PP-OCRv5_mobile_det_infer/PP-OCRv5_mobile_det_infer.onnx");
|
||||
// config.setDetModelPath("/Users/xxx/Documents/develop/model/ocr/PP-OCRv5_server_det_infer/PP-OCRv5_server_det.onnx");
|
||||
config.setDevice(device);
|
||||
return OcrModelFactory.getInstance().getDetModel(config);
|
||||
}
|
||||
@@ -115,45 +116,6 @@ public class TableRecDemo {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 表格识别
|
||||
* 仅支持简单表格
|
||||
* 流程:表格结构识别 -> 文本检测 -> 文本识别 -> 合成html table
|
||||
* 注意事项:
|
||||
* 1、批量检测时,模型应统一放在外层 try 中使用,避免重复加载,自动释放资源更安全。
|
||||
* 2、模型文件需要放在单独文件夹
|
||||
*/
|
||||
@Test
|
||||
public void recognize(){
|
||||
try {
|
||||
TableStructureModel tableStructureModel = getTableStructureModel();
|
||||
OcrCommonDetModel detModel = getDetectionModel();
|
||||
OcrCommonRecModel recModel = getRecModel();
|
||||
OcrDirectionModel directionModel = getDirectionModel();
|
||||
//创建表格识别器
|
||||
TableRecognizer tableRecognizer = TableRecognizer.builder()
|
||||
.withStructureModel(tableStructureModel)
|
||||
.withTextDetModel(detModel)
|
||||
// .withDirectionModel(getDirectionModel()) //如果表格中存在旋转的文字,可以使用方向分类模型
|
||||
.withTextRecModel(recModel).build();
|
||||
String imagePath = "src/main/resources/table/table_ch1.png";
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get(imagePath).toAbsolutePath().toString()));
|
||||
R<TableStructureResult> result = tableRecognizer.recognize(image);
|
||||
if(result.isSuccess()){
|
||||
log.info("result: {}", result.getData().getHtml());
|
||||
//导出html内容到文件
|
||||
Path outputPath = Paths.get("output/table_ch2_result.html");
|
||||
FileUtil.writeUtf8String(result.getData().getHtml(), outputPath.toAbsolutePath().toString());
|
||||
//绘制表格结构
|
||||
tableRecognizer.drawTable(result.getData(), image, "output/table_ch2_result.jpg");
|
||||
//导出excel,如果导出失败,可能是因为表格结果识别的结果是错乱的
|
||||
tableRecognizer.exportExcel(result.getData().getHtml(), "output/table_ch2_result.xls");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 表格识别
|
||||
@@ -177,7 +139,8 @@ public class TableRecDemo {
|
||||
// .withDirectionModel(getDirectionModel()) //如果表格中存在旋转的文字,可以使用方向分类模型
|
||||
.withTextRecModel(recModel).build();
|
||||
String imagePath = "src/main/resources/table/table_ch1.png";
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get(imagePath).toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile(imagePath);
|
||||
R<TableStructureResult> result = tableRecognizer.recognize(image);
|
||||
if(result.isSuccess()){
|
||||
log.info("result: {}", result.getData().getHtml());
|
||||
@@ -185,8 +148,8 @@ public class TableRecDemo {
|
||||
Path outputPath = Paths.get("output/table_ch2_result.html");
|
||||
FileUtil.writeUtf8String(result.getData().getHtml(), outputPath.toAbsolutePath().toString());
|
||||
//绘制表格结构
|
||||
BufferedImage resultImage = tableRecognizer.drawTable(result.getData(), image);
|
||||
ImageUtils.saveImage(resultImage, "output/table_ch2_result.jpg");
|
||||
Image resultImage = tableRecognizer.drawTable(result.getData(), image);
|
||||
ImageUtils.save(resultImage, "output/table_ch2_result.jpg");
|
||||
//导出excel,如果导出失败,可能是因为表格结果识别的结果是错乱的
|
||||
try (OutputStream out = Files.newOutputStream(Paths.get("output/table_ch2_result2.xls"))) {
|
||||
tableRecognizer.exportExcel(result.getData().getHtml(), out);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<smartjavaai.version>1.0.24</smartjavaai.version>
|
||||
<smartjavaai.version>1.0.25</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.speech.asr.common.OcrRecognizeDemo</exec.mainClass>
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<smartjavaai.version>1.0.24</smartjavaai.version>
|
||||
<smartjavaai.version>1.0.25</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.nlp.translation.TranslationDemo</exec.mainClass>
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<smartjavaai.version>1.0.24</smartjavaai.version>
|
||||
<smartjavaai.version>1.0.25</smartjavaai.version>
|
||||
<!--如果打包运行,需要替换成你的main-->
|
||||
<exec.mainClass>smartai.examples.vision.ObjectDetectionDemo</exec.mainClass>
|
||||
|
||||
@@ -272,36 +272,6 @@
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- linux aarch64 平台 (保留对应平台的配置,可以减小包大小)-->
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp</artifactId>
|
||||
<version>${javacv.version}</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>ffmpeg</artifactId>
|
||||
<version>6.1.1-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>openblas</artifactId>
|
||||
<version>0.3.26-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<version>4.9.0-1.5.10</version>
|
||||
<classifier>${javacv.platform.linux-arm64}</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ public class ActionRecognizeDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ public class InstanceSegDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -119,7 +121,7 @@ public class InstanceSegDemo {
|
||||
if(result.isSuccess()){
|
||||
log.info("实例分割结果:{}", JSONObject.toJSONString(result.getData()));
|
||||
//保存图片
|
||||
ImageUtils.saveImage(result.getData().getDrawnImage(), "dog_bike_car_detected.png", "output");
|
||||
ImageUtils.save(result.getData().getDrawnImage(), "dog_bike_car_detected2.png", "output");
|
||||
}else{
|
||||
log.info("实例分割失败:{}", result.getMessage());
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ public class ObbDetDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -115,7 +117,7 @@ public class ObbDetDemo {
|
||||
if(result.isSuccess()){
|
||||
log.info("旋转框检测结果:{}", JSONObject.toJSONString(result.getData()));
|
||||
//保存图片
|
||||
ImageUtils.saveImage(result.getData().getDrawnImage(), "boats_obb_detected.png", "output");
|
||||
ImageUtils.save(result.getData().getDrawnImage(), "output/boats_obb_detected2.png");
|
||||
}else{
|
||||
log.info("旋转框检测失败:{}", result.getMessage());
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import ai.djl.modality.cv.ImageFactory;
|
||||
import ai.djl.util.JsonUtils;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.smartjavaai.common.cv.SmartImageFactory;
|
||||
import cn.smartjavaai.common.entity.DetectionInfo;
|
||||
import cn.smartjavaai.common.entity.DetectionRectangle;
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
@@ -56,6 +57,8 @@ public class ObjectDetectionDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -90,7 +93,9 @@ public class ObjectDetectionDemo {
|
||||
public void objectDetection(){
|
||||
try {
|
||||
DetectorModel detectorModel = getModel();
|
||||
DetectionResponse detectionResponse = detectorModel.detect("src/main/resources/object_detection.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/object_detection.jpg");
|
||||
DetectionResponse detectionResponse = detectorModel.detect(image);
|
||||
log.info("目标检测结果:{}", JSONObject.toJSONString(detectionResponse));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -118,10 +123,14 @@ public class ObjectDetectionDemo {
|
||||
try {
|
||||
DetectorModel detectorModel = getModel();
|
||||
String imagePath = "src/main/resources/object_detection.jpg";
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get(imagePath).toAbsolutePath().toString()));
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile(imagePath);
|
||||
//可以根据后续业务场景使用detectedImage
|
||||
BufferedImage detectedImage = detectorModel.detectAndDraw(image);
|
||||
Assert.assertNotNull("detectedImage null", detectedImage);
|
||||
DetectionResponse detectionResponse = detectorModel.detectAndDraw(image);
|
||||
log.info("目标检测结果:{}", JSONObject.toJSONString(detectionResponse));
|
||||
if(detectionResponse != null && detectionResponse.getDrawnImage() != null){
|
||||
ImageUtils.save(detectionResponse.getDrawnImage(), "output/object_detection_detected2.png");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -181,9 +190,9 @@ public class ObjectDetectionDemo {
|
||||
config.setTopK(100);
|
||||
config.setDevice(device);
|
||||
DetectorModel detectorModel = ObjectDetectionModelFactory.getInstance().getModel(config);
|
||||
DetectionResponse detectionResponse = detectorModel.detect("src/main/resources/dog_bike_car.jpg");
|
||||
//检测并保存绘制结果
|
||||
detectorModel.detectAndDraw("src/main/resources/dog_bike_car.jpg", "output/dog_bike_car_detect.jpg");
|
||||
//创建Image对象,可以从文件、url、InputStream创建、BufferedImage、Base64创建,具体使用方法可以查看文档
|
||||
Image image = SmartImageFactory.getInstance().fromFile("src/main/resources/dog_bike_car.jpg");
|
||||
DetectionResponse detectionResponse = detectorModel.detect(image);
|
||||
log.info("目标检测结果:{}", JSONObject.toJSONString(detectionResponse));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -218,11 +227,11 @@ public class ObjectDetectionDemo {
|
||||
log.info("时间:" + LocalDateTimeUtil.now().toString());
|
||||
log.info("检测结果:{}", JsonUtils.toJson(detectionInfoList));
|
||||
//绘制检测结果
|
||||
OpenCVUtils.drawRectAndText(image, detectionInfoList);
|
||||
ImageUtils.drawRectAndText(image, detectionInfoList);
|
||||
//保存图片
|
||||
ImageUtils.saveImage(image, "test"+ UUID.fastUUID().toString() +".png","/Users/wenjie/Downloads");
|
||||
ImageUtils.save(image, "test"+ UUID.fastUUID().toString() +".png","/Users/wenjie/Downloads");
|
||||
if (image != null){
|
||||
((Mat)image.getWrappedImage()).release();
|
||||
ImageUtils.releaseOpenCVMat(image);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +277,12 @@ public class ObjectDetectionDemo {
|
||||
log.info("时间:" + LocalDateTimeUtil.now().toString());
|
||||
log.info("检测结果:{}", JsonUtils.toJson(detectionInfoList));
|
||||
//绘制检测结果
|
||||
OpenCVUtils.drawRectAndText(image, detectionInfoList);
|
||||
ImageUtils.drawRectAndText(image, detectionInfoList);
|
||||
//保存图片
|
||||
ImageUtils.saveImage(image, "test"+ UUID.fastUUID().toString() +".png","/Users/wenjie/Downloads");
|
||||
ImageUtils.save(image, "test"+ UUID.fastUUID().toString() +".png","/Users/wenjie/Downloads");
|
||||
if (image != null){
|
||||
ImageUtils.releaseOpenCVMat(image);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -316,9 +328,12 @@ public class ObjectDetectionDemo {
|
||||
log.info("时间:" + LocalDateTimeUtil.now().toString());
|
||||
log.info("检测结果:{}", JsonUtils.toJson(detectionInfoList));
|
||||
//绘制检测结果
|
||||
OpenCVUtils.drawRectAndText(image, detectionInfoList);
|
||||
ImageUtils.drawRectAndText(image, detectionInfoList);
|
||||
//保存图片
|
||||
ImageUtils.saveImage(image, "test"+ UUID.fastUUID().toString() +".png","/Users/wenjie/Downloads");
|
||||
ImageUtils.save(image, "test"+ UUID.fastUUID().toString() +".png","/Users/wenjie/Downloads");
|
||||
if (image != null){
|
||||
ImageUtils.releaseOpenCVMat(image);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -385,7 +400,7 @@ public class ObjectDetectionDemo {
|
||||
JOptionPane.showConfirmDialog(null, "Failed to capture image from WebCam.");
|
||||
}
|
||||
ViewerFrame frame = new ViewerFrame(width, height);
|
||||
ImageFactory factory = ImageFactory.getInstance();
|
||||
SmartImageFactory factory = SmartImageFactory.getInstance();
|
||||
Size size = new Size(width, height);
|
||||
|
||||
while (capture.isOpened()) {
|
||||
@@ -394,9 +409,8 @@ public class ObjectDetectionDemo {
|
||||
}
|
||||
Mat resizeImage = new Mat();
|
||||
Imgproc.resize(image, resizeImage, size);
|
||||
Image img = factory.fromImage(resizeImage);
|
||||
BufferedImage bufferedImage = OpenCVUtils.mat2Image(resizeImage);
|
||||
DetectionResponse detectedResult = detectorModel.detect(bufferedImage);
|
||||
Image img = factory.fromMat(resizeImage);
|
||||
DetectionResponse detectedResult = detectorModel.detect(img);
|
||||
if (Objects.isNull(detectedResult) || Objects.isNull(detectedResult.getDetectionInfoList()) || detectedResult.getDetectionInfoList().size() == 0){
|
||||
log.debug("未检测到物体");
|
||||
continue;
|
||||
@@ -404,11 +418,10 @@ public class ObjectDetectionDemo {
|
||||
for(DetectionInfo detectionInfo : detectedResult.getDetectionInfoList()){
|
||||
DetectionRectangle detectionRectangle = detectionInfo.getDetectionRectangle();
|
||||
String text = detectionInfo.getObjectDetInfo().getClassName();
|
||||
ImageUtils.drawImageRectWithText(bufferedImage, detectionRectangle, text, Color.RED);
|
||||
ImageUtils.drawRectAndText(img, detectionRectangle, text);
|
||||
}
|
||||
frame.showImage(bufferedImage);
|
||||
frame.showImage(ImageUtils.toBufferedImage(img));
|
||||
}
|
||||
|
||||
capture.release();
|
||||
System.exit(0);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -32,6 +32,8 @@ public class PersonDetectDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -108,7 +110,7 @@ public class PersonDetectDemo {
|
||||
if(result.isSuccess()){
|
||||
log.info("行人检测结果:{}", JSONObject.toJSONString(result.getData()));
|
||||
//保存图片
|
||||
ImageUtils.saveImage(result.getData().getDrawnImage(), "person_result.png", "output");
|
||||
ImageUtils.save(result.getData().getDrawnImage(), "person_result.png", "output");
|
||||
}else{
|
||||
log.info("行人检测失败:{}", result.getMessage());
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ public class PoseDetDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -105,7 +107,7 @@ public class PoseDetDemo {
|
||||
//可以根据后续业务场景使用detectedImage
|
||||
Image drawImage = detectorModel.detectAndDraw(image);
|
||||
//保存图片
|
||||
ImageUtils.saveImage(drawImage, "pose_detected.png", "output");
|
||||
ImageUtils.save(drawImage, "pose_detected2.png", "output");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ public class SemSegDemo {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() throws IOException {
|
||||
//将图片处理的底层引擎切换为 OpenCV
|
||||
SmartImageFactory.setEngine(SmartImageFactory.Engine.OPENCV);
|
||||
//修改缓存路径
|
||||
// Config.setCachePath("/Users/xxx/smartjavaai_cache");
|
||||
}
|
||||
@@ -109,7 +111,7 @@ public class SemSegDemo {
|
||||
//可以根据后续业务场景使用detectedImage
|
||||
Image dretectedImage = detectorModel.detectAndDraw(image);
|
||||
//保存
|
||||
ImageUtils.saveImage(dretectedImage, "dog_bike_car_detected.png", "output");
|
||||
ImageUtils.save(dretectedImage, "dog_bike_car_detected2.png", "output");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user