mirror of
https://github.com/geekwenjie/SmartJavaAI.git
synced 2026-09-18 16:39:21 +00:00
1、人脸模块:新增小视科技(MiniVision)活体检测模型
2、人脸模块:新增阿里通义工作室活体检测模型 3、人脸模块:新增2个表情识别模型 4、人脸模块:新增InsightFace、ElasticFace人脸识别模型 5、人脸模块:新增Seetaface6质量评估模型 6、目标检测模块:开放更多自定义模型参数 7、人脸模块:支持base64图片 8、实现接口 AutoCloseable,支持资源的自动释放 9、OCR模块:解决加方向矫正后无法连续识别bug 10、人脸模块:解决人脸更新后缓存问题 11、优化部分功能
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
package smartai.examples.objectdetection;
|
||||
|
||||
import ai.djl.Application;
|
||||
import ai.djl.MalformedModelException;
|
||||
import ai.djl.modality.cv.Image;
|
||||
import ai.djl.modality.cv.ImageFactory;
|
||||
import ai.djl.modality.cv.output.*;
|
||||
import ai.djl.modality.cv.output.Rectangle;
|
||||
import ai.djl.repository.zoo.Criteria;
|
||||
import ai.djl.repository.zoo.ModelNotFoundException;
|
||||
import ai.djl.repository.zoo.ModelZoo;
|
||||
import ai.djl.repository.zoo.ZooModel;
|
||||
import ai.djl.training.util.ProgressBar;
|
||||
import cn.smartjavaai.common.entity.DetectionInfo;
|
||||
import cn.smartjavaai.common.entity.DetectionRectangle;
|
||||
import cn.smartjavaai.common.entity.DetectionResponse;
|
||||
import cn.smartjavaai.common.entity.R;
|
||||
import cn.smartjavaai.common.enums.DeviceEnum;
|
||||
import cn.smartjavaai.common.enums.face.LivenessStatus;
|
||||
import cn.smartjavaai.common.utils.ImageUtils;
|
||||
import cn.smartjavaai.common.utils.OpenCVUtils;
|
||||
import cn.smartjavaai.face.model.liveness.LivenessDetModel;
|
||||
import cn.smartjavaai.objectdetection.config.DetectorModelConfig;
|
||||
import cn.smartjavaai.objectdetection.enums.DetectorModelEnum;
|
||||
import cn.smartjavaai.objectdetection.exception.DetectionException;
|
||||
import cn.smartjavaai.objectdetection.model.DetectorModel;
|
||||
import cn.smartjavaai.objectdetection.model.ObjectDetectionModelFactory;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import nu.pattern.OpenCV;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
import org.opencv.videoio.VideoCapture;
|
||||
import org.opencv.videoio.Videoio;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* 目标检测模型demo
|
||||
* 支持功能:目标检测
|
||||
* 模型下载地址:https://pan.baidu.com/s/10aTOLBlR6EG-sq6g0OkAWg?pwd=1234 提取码: 1234
|
||||
* @author dwj
|
||||
*/
|
||||
@Slf4j
|
||||
public class ObjectDetection {
|
||||
|
||||
|
||||
//设备类型
|
||||
public static DeviceEnum device = DeviceEnum.CPU;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 使用默认模型检测:YOLO11N
|
||||
*/
|
||||
@Test
|
||||
public void objectDetection(){
|
||||
//默认cpu
|
||||
try (DetectorModel detectorModel = ObjectDetectionModelFactory.getInstance().getModel()){
|
||||
DetectionResponse detectionResponse = detectorModel.detect("src/main/resources/object_detection.jpg");
|
||||
log.info("目标检测结果:{}", JSONObject.toJSONString(detectionResponse));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定模型检测(19种模型可选)
|
||||
*/
|
||||
@Test
|
||||
public void objectDetection2(){
|
||||
DetectorModelConfig config = new DetectorModelConfig();
|
||||
config.setModelEnum(DetectorModelEnum.SSD_300_RESNET50);//检测模型,目前支持19种预置模型
|
||||
config.setDevice(device);
|
||||
try (DetectorModel detectorModel = ObjectDetectionModelFactory.getInstance().getModel(config)){
|
||||
DetectionResponse detectionResponse = detectorModel.detect("src/main/resources/dog_bike_car.jpg");
|
||||
log.info("目标检测结果:{}", JSONObject.toJSONString(detectionResponse));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 人脸检测并绘制检测结果
|
||||
*/
|
||||
@Test
|
||||
public void objectDetectionAndDraw(){
|
||||
try (DetectorModel detectorModel = ObjectDetectionModelFactory.getInstance().getModel()){
|
||||
detectorModel.detectAndDraw("src/main/resources/object_detection.jpg","output/object_detection_detected.png");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 人脸检测并绘制检测结果,返回BufferedImage
|
||||
*/
|
||||
@Test
|
||||
public void objectDetectionAndDraw2(){
|
||||
try (DetectorModel detectorModel = ObjectDetectionModelFactory.getInstance().getModel()){
|
||||
String imagePath = "src/main/resources/object_detection.jpg";
|
||||
BufferedImage image = ImageIO.read(new File(Paths.get(imagePath).toAbsolutePath().toString()));
|
||||
//可以根据后续业务场景使用detectedImage
|
||||
BufferedImage detectedImage = detectorModel.detectAndDraw(image);
|
||||
Assert.assertNotNull("detectedImage null", detectedImage);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 使用yolo官方模型检测物品识别
|
||||
*/
|
||||
@Test
|
||||
public void objectDetectionWithOfficialModel(){
|
||||
DetectorModelConfig config = new DetectorModelConfig();
|
||||
config.setThreshold(0.3f);
|
||||
//也支持YoloV8:YOLOV8_OFFICIAL 模型可以从文档中提供的地址下载
|
||||
config.setModelEnum(DetectorModelEnum.YOLOV12_OFFICIAL);//检测模型,目前支持19种模型
|
||||
// 指定模型路径,需要更改为自己的模型路径
|
||||
config.setModelPath("/Users/xxx/Documents/yolov12n.onnx");
|
||||
config.setDevice(device);
|
||||
//一定要将yolo官方的类别文件:synset.txt(文档中下载)放在模型同目录下,否则报错
|
||||
try (DetectorModel detectorModel = ObjectDetectionModelFactory.getInstance().getModel(config)){
|
||||
DetectionResponse detect = detectorModel.detect("src/main/resources/dog_bike_car.jpg");
|
||||
log.info("目标检测结果:{}", JSONObject.toJSONString(detect));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用自己训练的模型检测
|
||||
*/
|
||||
@Test
|
||||
public void objectDetectionWithCustomModel(){
|
||||
DetectorModelConfig config = new DetectorModelConfig();
|
||||
//也支持YoloV8:YOLOV8_CUSTOM 模型需要自己训练,训练教程可以查看文档
|
||||
config.setModelEnum(DetectorModelEnum.YOLOV12_CUSTOM);//自定义YOLOV12模型
|
||||
// 指定模型路径,需要更改为自己的模型路径
|
||||
config.setModelPath("/Users/xxx/Documents/develop/fire_model/best.onnx");
|
||||
config.putCustomParam("width", 640);//resize 宽
|
||||
config.putCustomParam("height", 640);// resize 高
|
||||
config.putCustomParam("nmsThreshold", 0.5f);
|
||||
config.setDevice(device);
|
||||
try (DetectorModel detectorModel = ObjectDetectionModelFactory.getInstance().getModel(config)){
|
||||
DetectionResponse detect = detectorModel.detect("src/main/resources/dog_bike_car.jpg");
|
||||
log.info("目标检测结果:{}", JSONObject.toJSONString(detect));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 摄像头目标检测
|
||||
* 注意事项:如果视频比较卡,可以使用轻量的检测模型
|
||||
*/
|
||||
@Test
|
||||
public void testDetectCamera(){
|
||||
try (DetectorModel detectorModel = ObjectDetectionModelFactory.getInstance().getModel()){
|
||||
OpenCV.loadShared();
|
||||
VideoCapture capture = new VideoCapture(0);
|
||||
if (!capture.isOpened()) {
|
||||
System.out.println("No camera detected");
|
||||
return;
|
||||
}
|
||||
|
||||
double ratio =
|
||||
capture.get(Videoio.CAP_PROP_FRAME_WIDTH)
|
||||
/ capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int height = (int) (screenSize.height * 0.65f);
|
||||
int width = (int) (height * ratio);
|
||||
if (width > screenSize.width) {
|
||||
width = screenSize.width;
|
||||
}
|
||||
|
||||
Mat image = new Mat();
|
||||
boolean captured = false;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
captured = capture.read(image);
|
||||
if (captured) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException ignore) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (!captured) {
|
||||
JOptionPane.showConfirmDialog(null, "Failed to capture image from WebCam.");
|
||||
}
|
||||
ViewerFrame frame = new ViewerFrame(width, height);
|
||||
ImageFactory factory = ImageFactory.getInstance();
|
||||
Size size = new Size(width, height);
|
||||
|
||||
while (capture.isOpened()) {
|
||||
if (!capture.read(image)) {
|
||||
break;
|
||||
}
|
||||
Mat resizeImage = new Mat();
|
||||
Imgproc.resize(image, resizeImage, size);
|
||||
Image img = factory.fromImage(resizeImage);
|
||||
BufferedImage bufferedImage = OpenCVUtils.mat2Image(resizeImage);
|
||||
DetectionResponse detectedResult = detectorModel.detect(bufferedImage);
|
||||
if (Objects.isNull(detectedResult) || Objects.isNull(detectedResult.getDetectionInfoList()) || detectedResult.getDetectionInfoList().size() == 0){
|
||||
log.debug("未检测到物体");
|
||||
continue;
|
||||
}
|
||||
for(DetectionInfo detectionInfo : detectedResult.getDetectionInfoList()){
|
||||
DetectionRectangle detectionRectangle = detectionInfo.getDetectionRectangle();
|
||||
String text = detectionInfo.getObjectDetInfo().getClassName();
|
||||
ImageUtils.drawImageRectWithText(bufferedImage, detectionRectangle, text, Color.RED);
|
||||
}
|
||||
frame.showImage(bufferedImage);
|
||||
}
|
||||
|
||||
capture.release();
|
||||
System.exit(0);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
|
||||
* with the License. A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0/
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
|
||||
* OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*/
|
||||
package smartai.examples.objectdetection;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class ViewerFrame {
|
||||
|
||||
private JFrame frame;
|
||||
private ImagePanel imagePanel;
|
||||
|
||||
public ViewerFrame(int width, int height) {
|
||||
frame = new JFrame("Demo");
|
||||
imagePanel = new ImagePanel();
|
||||
frame.setLayout(new BorderLayout());
|
||||
frame.add(BorderLayout.CENTER, imagePanel);
|
||||
|
||||
JOptionPane.setRootFrame(frame);
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
if (width > screenSize.width) {
|
||||
width = screenSize.width;
|
||||
}
|
||||
Dimension frameSize = new Dimension(width, height);
|
||||
frame.setSize(frameSize);
|
||||
frame.setLocation((screenSize.width - width) / 2, (screenSize.height - height) / 2);
|
||||
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
public void showImage(BufferedImage image) {
|
||||
imagePanel.setImage(image);
|
||||
SwingUtilities.invokeLater(
|
||||
() -> {
|
||||
frame.repaint();
|
||||
frame.pack();
|
||||
});
|
||||
}
|
||||
|
||||
private static final class ImagePanel extends JPanel {
|
||||
|
||||
private BufferedImage image;
|
||||
|
||||
void setImage(BufferedImage image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
if (image == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
g.drawImage(image, 0, 0, null);
|
||||
setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Main-Class: smartai.examples.face.SeetaFace6LinuxDemo
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 160 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 463 KiB |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 步骤2: 配置文件 (src/main/resources/logback.xml) -->
|
||||
<configuration scan="true" scanPeriod="30 seconds">
|
||||
<!-- 控制台日志输出 -->
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
</configuration>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
Reference in New Issue
Block a user