mirror of
https://github.com/geekwenjie/SmartJavaAI.git
synced 2026-09-10 03:28:49 +00:00
人脸识别demo
This commit is contained in:
BIN
examples/output/retinaface_detected.jpg
Normal file
BIN
examples/output/retinaface_detected.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 357 KiB |
114
examples/src/main/java/smartai/examples/face/FaceDemo.java
Normal file
114
examples/src/main/java/smartai/examples/face/FaceDemo.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package smartai.examples.face;
|
||||
|
||||
import cn.smartjavaai.common.entity.Rectangle;
|
||||
import cn.smartjavaai.face.FaceAlgorithm;
|
||||
import cn.smartjavaai.face.FaceAlgorithmFactory;
|
||||
import cn.smartjavaai.face.FaceDetectedResult;
|
||||
import cn.smartjavaai.face.ModelConfig;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import smartai.examples.utils.ImageUtils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* @author dwj
|
||||
*/
|
||||
public class FaceDemo {
|
||||
|
||||
// 创建 Logger 实例
|
||||
private static final Logger logger = LoggerFactory.getLogger(FaceDemo.class);
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
//detectFace();
|
||||
//verifyIDCard();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 人脸检测(服务端模型)
|
||||
* 人脸模型:retinaface
|
||||
* 特点:识别精度高,高速
|
||||
* 应用场景:如监控摄像头、智能安防系统等需要高精度检测的场合
|
||||
*/
|
||||
public static void detectFace() throws Exception {
|
||||
//创建人脸算法
|
||||
FaceAlgorithm currentAlgorithm = FaceAlgorithmFactory.createFaceAlgorithm();
|
||||
//使用图片路径检测
|
||||
FaceDetectedResult result = currentAlgorithm.detect("src/main/resources/largest_selfie.jpg");
|
||||
logger.info("人脸检测结果:{}", JSONObject.toJSONString(result));
|
||||
//使用图片流检测
|
||||
//File imageFile = new File("/Users/wenjie/Downloads/djl-master/examples/src/test/resources/largest_selfie.jpg");
|
||||
//FaceDetectedResult result = currentAlgorithm.detect(new FileInputStream(imageFile));
|
||||
File input = new File("src/main/resources/largest_selfie.jpg");
|
||||
BufferedImage image = ImageIO.read(input);
|
||||
//创建保存路径
|
||||
Path imagePath = Paths.get("output").resolve("retinaface_detected.jpg");
|
||||
//绘制人脸框
|
||||
ImageUtils.drawBoundingBoxes(image, result, imagePath.toAbsolutePath().toString());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 人脸检测(轻量模型)
|
||||
* 人脸模型:Ultra-Light-Fast-Generic-Face-Detector-1MB
|
||||
* 特点:高速,准确率略低
|
||||
* 应用场景:如监控摄像头、智能安防系统等需要高精度检测的场合
|
||||
*/
|
||||
public static void detectFace2() throws Exception {
|
||||
//创建轻量人脸算法
|
||||
FaceAlgorithm currentAlgorithm = FaceAlgorithmFactory.createLightFaceAlgorithm();
|
||||
//使用图片路径检测
|
||||
FaceDetectedResult result = currentAlgorithm.detect("src/main/resources/largest_selfie.jpg");
|
||||
logger.info("轻量人脸检测结果:{}", JSONObject.toJSONString(result));
|
||||
//使用图片流检测
|
||||
//File imageFile = new File("/Users/wenjie/Downloads/djl-master/examples/src/test/resources/largest_selfie.jpg");
|
||||
//FaceDetectedResult result = currentAlgorithm.detect(new FileInputStream(imageFile));
|
||||
File input = new File("src/main/resources/largest_selfie.jpg");
|
||||
BufferedImage image = ImageIO.read(input);
|
||||
//创建保存路径
|
||||
Path imagePath = Paths.get("output").resolve("retinaface_detected.jpg");
|
||||
//绘制人脸框
|
||||
ImageUtils.drawBoundingBoxes(image, result, imagePath.toAbsolutePath().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 人证核验
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void verifyIDCard() throws Exception {
|
||||
//创建脸算法
|
||||
FaceAlgorithm currentAlgorithm = FaceAlgorithmFactory.createFaceAlgorithm();
|
||||
//提取身份证人脸特征(图片仅供测试)
|
||||
float[] featureIdCard = currentAlgorithm.featureExtraction("src/main/resources/kana1.jpg");
|
||||
//提取身份证人脸特征(从图片流获取)
|
||||
//File imageFile = new File("/Users/wenjie/Downloads/djl-master/examples/src/test/resources/largest_selfie.jpg");
|
||||
//float[] featureIdCard = currentAlgorithm.featureExtraction(new FileInputStream(imageFile));
|
||||
logger.info("身份证人脸特征:{}", JSONObject.toJSONString(featureIdCard));
|
||||
//提取实时人脸特征(图片仅供测试)
|
||||
float[] realTimeFeature = currentAlgorithm.featureExtraction("src/main/resources/kana2.jpg");
|
||||
logger.info("实时人脸特征:{}", JSONObject.toJSONString(realTimeFeature));
|
||||
if(realTimeFeature != null){
|
||||
if(currentAlgorithm.calculSimilar(featureIdCard, realTimeFeature) > 0.8){
|
||||
logger.info("人脸核验通过");
|
||||
}else{
|
||||
logger.info("人脸核验不通过");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package smartai.examples.utils;
|
||||
|
||||
import cn.smartjavaai.face.FaceDetectedResult;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* @author dwj
|
||||
*/
|
||||
public class ImageUtils {
|
||||
|
||||
/**
|
||||
* 绘制人脸框
|
||||
* @param sourceImage
|
||||
* @param faceDetectedResult
|
||||
* @param savePath
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void drawBoundingBoxes(BufferedImage sourceImage, FaceDetectedResult faceDetectedResult,String savePath) throws IOException {
|
||||
Graphics2D graphics = sourceImage.createGraphics();
|
||||
graphics.setColor(Color.RED);// 边框颜色
|
||||
graphics.setStroke(new BasicStroke(2)); // 线宽2像素
|
||||
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON); // 抗锯齿
|
||||
int stroke = 2;
|
||||
for(cn.smartjavaai.common.entity.Rectangle rectangle : faceDetectedResult.getRectangles()){
|
||||
graphics.setColor(Color.RED);// 边框颜色
|
||||
graphics.drawRect(rectangle.getPointList().get(0).getX(),
|
||||
rectangle.getPointList().get(0).getY(), rectangle.getWidth(), rectangle.getHeight());
|
||||
drawText(graphics, "face", rectangle.getPointList().get(0).getX(), rectangle.getPointList().get(0).getY(), stroke, 4);
|
||||
}
|
||||
graphics.dispose();
|
||||
ImageIO.write(sourceImage, "jpg", new File(savePath));
|
||||
|
||||
}
|
||||
|
||||
private static void drawText(Graphics2D g, String text, int x, int y, int stroke, int padding) {
|
||||
FontMetrics metrics = g.getFontMetrics();
|
||||
x += stroke / 2;
|
||||
y += stroke / 2;
|
||||
int width = metrics.stringWidth(text) + padding * 2 - stroke / 2;
|
||||
int height = metrics.getHeight() + metrics.getDescent();
|
||||
int ascent = metrics.getAscent();
|
||||
java.awt.Rectangle background = new java.awt.Rectangle(x, y, width, height);
|
||||
g.fill(background);
|
||||
g.setPaint(Color.WHITE);
|
||||
g.drawString(text, x + padding, y + ascent);
|
||||
}
|
||||
}
|
||||
BIN
examples/src/main/resources/largest_selfie.jpg
Normal file
BIN
examples/src/main/resources/largest_selfie.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 463 KiB |
14
examples/src/main/resources/logback.xml
Normal file
14
examples/src/main/resources/logback.xml
Normal file
@@ -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="INFO">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user