From 0df7ab99133a89e773e1d2fca62a3f387ce87370 Mon Sep 17 00:00:00 2001
From: yangbr <74187378+12341234-yangboran@users.noreply.github.com>
Date: Fri, 10 May 2024 14:34:46 +0800
Subject: [PATCH 1/2] Create demo.java
---
models/face_recognition_sface/demo.java | 143 ++++++++++++++++++++++++
1 file changed, 143 insertions(+)
create mode 100644 models/face_recognition_sface/demo.java
diff --git a/models/face_recognition_sface/demo.java b/models/face_recognition_sface/demo.java
new file mode 100644
index 00000000..1dfb8ff4
--- /dev/null
+++ b/models/face_recognition_sface/demo.java
@@ -0,0 +1,143 @@
+import nu.pattern.OpenCV;
+import org.opencv.core.Mat;
+import org.opencv.core.Size;
+import org.opencv.imgcodecs.Imgcodecs;
+import org.opencv.objdetect.FaceDetectorYN;
+import org.opencv.objdetect.FaceRecognizerSF;
+
+/**
+ * the java demo of FaceRecognizerSF
+ *
+ * you need the dependencies of maven:
+ *
+ * *OpenCV Java bindings packaged with native libraries,
+ * seamlessly delivered as a turn-key Maven dependency.
+ * You don't need to download OpenCV to support the relevant features.
+ * doc:https://github.com/openpnp/opencv?tab=readme-ov-file
+ *
+ * https://mvnrepository.com/artifact/org.openpnp/opencv
+ *
+ * org.openpnp
+ * opencv
+ * 4.9.0-0
+ *
+ */
+public class FaceRecognizer {
+
+ private static double cosine_similar_threshold = 0.363;
+
+ private static double l2norm_similar_threshold = 1.128;
+
+ // Your full path of yunet model
+ private static String faceDetectModelPath = "/face_detection_yunet_2023mar.onnx";
+ // state faceDetector
+ private static FaceDetectorYN faceDetector = null;
+
+ // Your full path of sface model
+ private static String faceRecognizModelPath = "/face_recognition_sface_2021dec.onnx";
+ // state faceRecognizer
+ private static FaceRecognizerSF faceRecognizer = null;
+
+ public static void main(String[] args) {
+ // You need to use the full path of img please
+ boolean b = faceRecognizer("imgPathA", "imgPathB");
+ System.out.println(b);
+ }
+
+ public static boolean faceRecognizer(String imgPathA, String imgPathB) {
+ // Load for opencv
+ OpenCV.loadLocally();
+ // Load for faceDetector
+ loadFaceDetector();
+ // Load for faceRecognizer
+ loadFaceRecognizer();
+
+ return faceRecognizerUtil(imgPathA, imgPathB);
+ }
+
+ // Load of faceDetector
+ private static void loadFaceDetector() {
+ if (faceDetector != null) {
+ return;
+ }
+ // You could use the full path for faceDetect model instead to get the resource
+ faceDetector = FaceDetectorYN.create(faceDetectModelPath, "", new Size());
+ }
+
+ // Load for faceRecognizer
+ private static void loadFaceRecognizer() {
+ if (faceRecognizer != null) {
+ return;
+ }
+ // You could use the full path for faceRecogniz model instead to get the resource
+ faceRecognizer = FaceRecognizerSF.create(faceRecognizModelPath, "");
+ }
+
+ /**
+ * FaceRecogniz. Calculating the distance between two face features
+ *
+ * @param imgPathA the path of imgA
+ * @param imgPathB the path of imgB
+ */
+ private static boolean faceRecognizerUtil(String imgPathA, String imgPathB) {
+ // 1.Read img convert to a mat
+ Mat imgA = Imgcodecs.imread(imgPathA);
+ Mat imgB = Imgcodecs.imread(imgPathB);
+
+ // 2.Detect face from given image
+ Mat faceA = new Mat();
+ faceDetector.setInputSize(imgA.size());
+ faceDetector.detect(imgA, faceA);
+ Mat faceB = new Mat();
+ faceDetector.setInputSize(imgB.size());
+ faceDetector.detect(imgB, faceB);
+
+ /*
+ // 3.Draw face info in img
+ // FaceDetectorYN
+ // Draw a face frame in imgA
+ Imgproc.rectangle(imgA, new Rect((int) (faceA.get(0, 0)[0]), (int) (faceA.get(0, 1)[0]), (int) (faceA.get(0, 2)[0]), (int) (faceA.get(0, 3)[0])), new Scalar(0, 255, 0), 2);
+ // Draw eyes/nose/mouth points on imgB
+ Imgproc.circle(imgA, new Point(faceA.get(0, 4)[0], faceA.get(0, 5)[0]), 2, new Scalar(255, 0, 0), 2);
+ Imgproc.circle(imgA, new Point(faceA.get(0, 6)[0], faceA.get(0, 7)[0]), 2, new Scalar(0, 0, 255), 2);
+ Imgproc.circle(imgA, new Point(faceA.get(0, 8)[0], faceA.get(0, 9)[0]), 2, new Scalar(0, 255, 0), 2);
+ Imgproc.circle(imgA, new Point(faceA.get(0, 10)[0], faceA.get(0, 11)[0]), 2, new Scalar(255, 0, 255), 2);
+ Imgproc.circle(imgA, new Point(faceA.get(0, 12)[0], faceA.get(0, 13)[0]), 2, new Scalar(0, 255, 255), 2);
+ // Imgcodecs.imwrite("", imgA);
+
+ // Draw a face frame in imgB
+ Imgproc.rectangle(imgB, new Rect((int) (faceB.get(0, 0)[0]), (int) (faceB.get(0, 1)[0]), (int) (faceB.get(0, 2)[0]), (int) (faceB.get(0, 3)[0])), new Scalar(0, 255, 0), 2);
+ // Draw eyes/nose/mouth in imgB
+ Imgproc.circle(imgB, new Point(faceB.get(0, 4)[0], faceB.get(0, 5)[0]), 2, new Scalar(255, 0, 0), 2);
+ Imgproc.circle(imgB, new Point(faceB.get(0, 6)[0], faceB.get(0, 7)[0]), 2, new Scalar(0, 0, 255), 2);
+ Imgproc.circle(imgB, new Point(faceB.get(0, 8)[0], faceB.get(0, 9)[0]), 2, new Scalar(0, 255, 0), 2);
+ Imgproc.circle(imgB, new Point(faceB.get(0, 10)[0], faceB.get(0, 11)[0]), 2, new Scalar(255, 0, 255), 2);
+ Imgproc.circle(imgB, new Point(faceB.get(0, 12)[0], faceB.get(0, 13)[0]), 2, new Scalar(0, 255, 255), 2);
+ // Imgcodecs.imwrite("", imgB);*/
+
+ // 4.Aligning image to put face on the standard position
+ Mat alignFaceA = new Mat();
+ faceRecognizer.alignCrop(imgA, faceA.row(0), alignFaceA);
+ Mat alignFaceB = new Mat();
+ faceRecognizer.alignCrop(imgB, faceB.row(0), alignFaceB);
+
+ // 5.Extracting face feature from aligned image
+ Mat featureA = new Mat();
+ faceRecognizer.feature(alignFaceA, featureA);
+ featureA = featureA.clone();
+ Mat featureB = new Mat();
+ faceRecognizer.feature(alignFaceB, featureB);
+ featureB = featureB.clone();
+
+ // 6.FaceRecogniz. Calculating the distance between two face features. If the condition is met, it returns true
+ // Get cosine similar
+ double match1 = faceRecognizer.match(featureA, featureB, FaceRecognizerSF.FR_COSINE);
+ // Get l2norm similar
+ double match2 = faceRecognizer.match(featureA, featureB, FaceRecognizerSF.FR_NORM_L2);
+ if (match1 >= cosine_similar_threshold && match2 <= l2norm_similar_threshold) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
From e09a04ea2d62e5f922a4615af4c0eded12e616f0 Mon Sep 17 00:00:00 2001
From: yangbr <74187378+12341234-yangboran@users.noreply.github.com>
Date: Fri, 10 May 2024 14:57:42 +0800
Subject: [PATCH 2/2] Update demo.java
Remove redundant comments
---
models/face_recognition_sface/demo.java | 30 ++++---------------------
1 file changed, 4 insertions(+), 26 deletions(-)
diff --git a/models/face_recognition_sface/demo.java b/models/face_recognition_sface/demo.java
index 1dfb8ff4..218d8693 100644
--- a/models/face_recognition_sface/demo.java
+++ b/models/face_recognition_sface/demo.java
@@ -29,6 +29,7 @@ public class FaceRecognizer {
private static double l2norm_similar_threshold = 1.128;
// Your full path of yunet model
+ // FaceDetectorYN
private static String faceDetectModelPath = "/face_detection_yunet_2023mar.onnx";
// state faceDetector
private static FaceDetectorYN faceDetector = null;
@@ -92,36 +93,13 @@ private static boolean faceRecognizerUtil(String imgPathA, String imgPathB) {
faceDetector.setInputSize(imgB.size());
faceDetector.detect(imgB, faceB);
- /*
- // 3.Draw face info in img
- // FaceDetectorYN
- // Draw a face frame in imgA
- Imgproc.rectangle(imgA, new Rect((int) (faceA.get(0, 0)[0]), (int) (faceA.get(0, 1)[0]), (int) (faceA.get(0, 2)[0]), (int) (faceA.get(0, 3)[0])), new Scalar(0, 255, 0), 2);
- // Draw eyes/nose/mouth points on imgB
- Imgproc.circle(imgA, new Point(faceA.get(0, 4)[0], faceA.get(0, 5)[0]), 2, new Scalar(255, 0, 0), 2);
- Imgproc.circle(imgA, new Point(faceA.get(0, 6)[0], faceA.get(0, 7)[0]), 2, new Scalar(0, 0, 255), 2);
- Imgproc.circle(imgA, new Point(faceA.get(0, 8)[0], faceA.get(0, 9)[0]), 2, new Scalar(0, 255, 0), 2);
- Imgproc.circle(imgA, new Point(faceA.get(0, 10)[0], faceA.get(0, 11)[0]), 2, new Scalar(255, 0, 255), 2);
- Imgproc.circle(imgA, new Point(faceA.get(0, 12)[0], faceA.get(0, 13)[0]), 2, new Scalar(0, 255, 255), 2);
- // Imgcodecs.imwrite("", imgA);
-
- // Draw a face frame in imgB
- Imgproc.rectangle(imgB, new Rect((int) (faceB.get(0, 0)[0]), (int) (faceB.get(0, 1)[0]), (int) (faceB.get(0, 2)[0]), (int) (faceB.get(0, 3)[0])), new Scalar(0, 255, 0), 2);
- // Draw eyes/nose/mouth in imgB
- Imgproc.circle(imgB, new Point(faceB.get(0, 4)[0], faceB.get(0, 5)[0]), 2, new Scalar(255, 0, 0), 2);
- Imgproc.circle(imgB, new Point(faceB.get(0, 6)[0], faceB.get(0, 7)[0]), 2, new Scalar(0, 0, 255), 2);
- Imgproc.circle(imgB, new Point(faceB.get(0, 8)[0], faceB.get(0, 9)[0]), 2, new Scalar(0, 255, 0), 2);
- Imgproc.circle(imgB, new Point(faceB.get(0, 10)[0], faceB.get(0, 11)[0]), 2, new Scalar(255, 0, 255), 2);
- Imgproc.circle(imgB, new Point(faceB.get(0, 12)[0], faceB.get(0, 13)[0]), 2, new Scalar(0, 255, 255), 2);
- // Imgcodecs.imwrite("", imgB);*/
-
- // 4.Aligning image to put face on the standard position
+ // 3.Aligning image to put face on the standard position
Mat alignFaceA = new Mat();
faceRecognizer.alignCrop(imgA, faceA.row(0), alignFaceA);
Mat alignFaceB = new Mat();
faceRecognizer.alignCrop(imgB, faceB.row(0), alignFaceB);
- // 5.Extracting face feature from aligned image
+ // 4.Extracting face feature from aligned image
Mat featureA = new Mat();
faceRecognizer.feature(alignFaceA, featureA);
featureA = featureA.clone();
@@ -129,7 +107,7 @@ private static boolean faceRecognizerUtil(String imgPathA, String imgPathB) {
faceRecognizer.feature(alignFaceB, featureB);
featureB = featureB.clone();
- // 6.FaceRecogniz. Calculating the distance between two face features. If the condition is met, it returns true
+ // 5.FaceRecogniz. Calculating the distance between two face features. If the condition is met, it returns true
// Get cosine similar
double match1 = faceRecognizer.match(featureA, featureB, FaceRecognizerSF.FR_COSINE);
// Get l2norm similar