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_light.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(); } }