diff --git a/models/face_recognition_sface/demo.java b/models/face_recognition_sface/demo.java
new file mode 100644
index 00000000..218d8693
--- /dev/null
+++ b/models/face_recognition_sface/demo.java
@@ -0,0 +1,121 @@
+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
+ // FaceDetectorYN
+ 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.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);
+
+ // 4.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();
+
+ // 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
+ double match2 = faceRecognizer.match(featureA, featureB, FaceRecognizerSF.FR_NORM_L2);
+ if (match1 >= cosine_similar_threshold && match2 <= l2norm_similar_threshold) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}