package com.code2roc.fastface.util;
|
|
import com.code2roc.fastface.eums.FaceEnum;
|
import com.seeta.proxy.FaceDetectorProxy;
|
import com.seeta.proxy.FaceLandmarkerProxy;
|
import com.seeta.proxy.FaceRecognizerProxy;
|
import com.seeta.sdk.*;
|
import com.seeta.sdk.util.LoadNativeCore;
|
import com.seeta.sdk.util.SeetafaceUtil;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Component;
|
|
import javax.annotation.PostConstruct;
|
import java.awt.image.BufferedImage;
|
import java.io.File;
|
import java.nio.file.Path;
|
import java.nio.file.Paths;
|
|
@Component
|
public class SeetaFaceHepler {
|
@Autowired
|
private FaceDetectorProxy faceDetectorProxy;
|
@Autowired
|
private FaceRecognizerProxy faceRecognizerProxy;
|
@Autowired
|
private FaceLandmarkerProxy faceLandmarkerProxy;
|
@Value("${face.modelPath}")
|
private String modelPath;
|
@Value("${face.dataBasePath}")
|
private String dataBasePath;
|
private FaceDatabase faceDatabase;
|
private float CHECK_SIM = new Float(0.62);
|
|
@PostConstruct
|
public void init() throws Exception {
|
Path tempDir = Paths.get(System.getProperty("user.dir"), modelPath);
|
LoadNativeCore.LOAD_NATIVE(SeetaDevice.SEETA_DEVICE_CPU);
|
faceDatabase = new FaceDatabase(new SeetaModelSetting(0, new String[]{tempDir + File.separator + "face_recognizer.csta"}, SeetaDevice.SEETA_DEVICE_CPU));
|
File file = new File(Paths.get(System.getProperty("user.dir"), dataBasePath).toString());
|
if (!file.exists()) {
|
file.createNewFile();
|
}
|
faceDatabase.Load(Paths.get(System.getProperty("user.dir"), dataBasePath).toString());
|
}
|
|
public FaceEnum.CheckImageFaceStatus getFace(BufferedImage image) throws Exception {
|
SeetaImageData imageData = SeetafaceUtil.toSeetaImageData(image);
|
SeetaRect[] detects = faceDetectorProxy.detect(imageData);
|
if (detects.length == 0) {
|
return FaceEnum.CheckImageFaceStatus.NoFace;
|
} else if (detects.length == 1) {
|
return FaceEnum.CheckImageFaceStatus.OneFace;
|
} else {
|
return FaceEnum.CheckImageFaceStatus.MoreFace;
|
}
|
}
|
|
public FaceEnum.CompareImageFaceStatus compareFace(BufferedImage source, BufferedImage compare) throws Exception {
|
float[] sourceFeature = extract(source);
|
float[] compareFeature = extract(compare);
|
if (sourceFeature != null && compareFeature != null) {
|
float calculateSimilarity = faceRecognizerProxy.calculateSimilarity(sourceFeature, compareFeature);
|
System.out.printf("相似度:%f\n", calculateSimilarity);
|
if (calculateSimilarity >= CHECK_SIM) {
|
return FaceEnum.CompareImageFaceStatus.Same;
|
} else {
|
return FaceEnum.CompareImageFaceStatus.Different;
|
}
|
} else {
|
return FaceEnum.CompareImageFaceStatus.LostFace;
|
}
|
}
|
|
public long registFace(BufferedImage image) throws Exception {
|
long result = -1;
|
SeetaImageData imageData = SeetafaceUtil.toSeetaImageData(image);
|
SeetaRect[] detects = faceDetectorProxy.detect(imageData);
|
if (detects.length > 0) {
|
SeetaPointF[] pointFS = faceLandmarkerProxy.mark(imageData, detects[0]);
|
result = faceDatabase.Register(imageData, pointFS);
|
faceDatabase.Save(Paths.get(System.getProperty("user.dir"), dataBasePath).toString());
|
}
|
return result;
|
|
|
}
|
|
public long queryFace(BufferedImage image) throws Exception {
|
long result = -1;
|
SeetaImageData imageData = SeetafaceUtil.toSeetaImageData(image);
|
SeetaRect[] detects = faceDetectorProxy.detect(imageData);
|
if (detects.length > 0) {
|
SeetaPointF[] pointFS = faceLandmarkerProxy.mark(imageData, detects[0]);
|
long[] index = new long[1];
|
float[] sim = new float[1];
|
result = faceDatabase.QueryTop(imageData, pointFS, 1, index, sim);
|
if (result > 0) {
|
float similarity = sim[0];
|
if (similarity >= CHECK_SIM) {
|
result = index[0];
|
} else {
|
result = -1;
|
}
|
}
|
}
|
return result;
|
}
|
|
public long deleteFace(long index) throws Exception {
|
long result = faceDatabase.Delete(index);
|
faceDatabase.Save(Paths.get(System.getProperty("user.dir"), dataBasePath).toString());
|
return result;
|
}
|
|
private float[] extract(BufferedImage image) throws Exception {
|
SeetaImageData imageData = SeetafaceUtil.toSeetaImageData(image);
|
SeetaRect[] detects = faceDetectorProxy.detect(imageData);
|
if (detects.length > 0) {
|
SeetaPointF[] pointFS = faceLandmarkerProxy.mark(imageData, detects[0]);
|
float[] features = faceRecognizerProxy.extract(imageData, pointFS);
|
return features;
|
}
|
return null;
|
}
|
|
public void resetFaceDataBase() {
|
faceDatabase.Clear();
|
}
|
}
|