├── .dockerignore ├── .env.example ├── .github └── FUNDING.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── docker-compose.yml ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── resources ├── demography.jpg └── tp.jpg ├── scripts ├── compose.sh ├── dockerize.sh └── service.sh └── src ├── App.css ├── App.js ├── App.test.js ├── index.css ├── index.js ├── logo.svg ├── reportWebVitals.js └── setupTests.js /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | npm-debug.log -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # backend deepface service's endpoint, do not change if not necessary 2 | REACT_APP_SERVICE_ENDPOINT=http://localhost:5005 3 | 4 | # Set facial recognition model: VGG-Face, Facenet, Facenet512, OpenFace, DeepFace, DeepId, ArcFace, Dlib, SFace, GhostFaceNet 5 | REACT_APP_FACE_RECOGNITION_MODEL=Facenet 6 | 7 | # Set face detector: opencv, ssd, mtcnn, dlib, mediapipe, retinaface, yolov8, yunet, centerface 8 | REACT_APP_DETECTOR_BACKEND=opencv 9 | 10 | # Set distance metric: cosine, euclidean, euclidean_l2 11 | REACT_APP_DISTANCE_METRIC=cosine 12 | 13 | # Set REACT_APP_ANTI_SPOOFING to 1 if you want to enable anti-spoofing 14 | REACT_APP_ANTI_SPOOFING=0 15 | 16 | # define your facial database 17 | REACT_APP_USER_YOUR_NAME=data:image/png;base64,... 18 | REACT_APP_USER_YOUR_FRIENDS_NAME=data:image/png;base64,... -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: serengil 2 | patreon: serengil 3 | buy_me_a_coffee: serengil -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use an official Node.js runtime as a parent image 2 | FROM node:14-alpine 3 | 4 | # Set the working directory in the container 5 | WORKDIR /app 6 | 7 | # Copy package.json and package-lock.json to the working directory 8 | COPY package*.json ./ 9 | 10 | # Install dependencies 11 | RUN npm install 12 | 13 | # Copy the rest of the application code to the working directory 14 | COPY . . 15 | 16 | # Expose port 3000 to the outside world 17 | EXPOSE 3000 18 | 19 | # Start the React application 20 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Sefik Ilkin Serengil 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DeepFace React UI 2 | 3 |
4 | 5 | [![Stars](https://img.shields.io/github/stars/serengil/deepface-react-ui?color=yellow&style=flat&label=%E2%AD%90%20stars)](https://github.com/serengil/deepface-react-ui/stargazers) 6 | [![License](http://img.shields.io/:license-MIT-green.svg?style=flat)](https://github.com/serengil/deepface-react-ui/blob/main/LICENSE) 7 | [![DOI](http://img.shields.io/:DOI-10.17671/gazibtd.1399077-blue.svg?style=flat)](https://doi.org/10.17671/gazibtd.1399077) 8 | 9 | [![Blog](https://img.shields.io/:blog-sefiks.com-blue.svg?style=flat&logo=wordpress)](https://sefiks.com) 10 | [![YouTube](https://img.shields.io/:youtube-@sefiks-red.svg?style=flat&logo=youtube)](https://www.youtube.com/@sefiks?sub_confirmation=1) 11 | [![Twitter](https://img.shields.io/:follow-@serengil-blue.svg?style=flat&logo=x)](https://twitter.com/intent/user?screen_name=serengil) 12 | 13 | [![Patreon](https://img.shields.io/:become-patron-f96854.svg?style=flat&logo=patreon)](https://www.patreon.com/serengil?repo=deepfacereact) 14 | [![GitHub Sponsors](https://img.shields.io/github/sponsors/serengil?logo=GitHub&color=lightgray)](https://github.com/sponsors/serengil) 15 | [![Buy Me a Coffee](https://img.shields.io/badge/-buy_me_a%C2%A0coffee-gray?logo=buy-me-a-coffee)](https://buymeacoffee.com/serengil) 16 | 17 |
18 | 19 | deepface-react-ui is a comprehensive user interface for facial recognition and facial attribute analysis (age, gender, emotion and race prediction) built with ReactJS, designed specifically for streamlined face verification tasks using the [DeepFace](https://github.com/serengil/deepface) library. This UI not only simplifies the implementation of facial recognition features but also enhances security with built-in [anti-spoofing](https://youtu.be/UiK1aIjOBlQ) capabilities. Whether you're working on identity verification systems, security applications, or simply exploring facial recognition technology, this UI provides an intuitive platform to harness the power of DeepFace within your web applications. 20 | 21 | Facial recognition technology plays a pivotal role in modern applications, from enhancing security measures to enabling personalized user experiences. The deepface-react-ui empowers developers and researchers to harness these capabilities effortlessly within their web applications. 22 | 23 |

24 | 25 | ## Cloning The Service 26 | 27 | Firstly, you should clone both deepface and deepface-react-ui repos in same directory. 28 | 29 | ```shell 30 | # clone deepface repo 31 | git clone https://github.com/serengil/deepface-react-ui.git \ 32 | && git clone https://github.com/serengil/deepface.git 33 | ``` 34 | 35 | ## Facial Database Configuration 36 | 37 | There is `.env.example` file in the root of the project. You should copy this as `.env`. Required modifications are mentioned as comments. You basically need to add your facial database items into this file, prefixing each with `REACT_APP_USER_`, where the identity name with that prefix serves as the key and the base64-encoded string of their images serves as the value. 38 | 39 | ```yaml 40 | # define your facial database 41 | REACT_APP_USER_ALICE=data:image/png;base64,... 42 | REACT_APP_USER_BOB=data:image/png;base64,... 43 | REACT_APP_USER_CAROL=data:image/png;base64,... 44 | ``` 45 | 46 | ## Model Configuration (Optional) 47 | 48 | DeepFace wraps many state-of-the-art facial recognition models: [`VGG-Face`](https://sefiks.com/2018/08/06/deep-face-recognition-with-keras/), [`FaceNet`](https://sefiks.com/2018/09/03/face-recognition-with-facenet-in-keras/), [`OpenFace`](https://sefiks.com/2019/07/21/face-recognition-with-openface-in-keras/), [`DeepFace`](https://sefiks.com/2020/02/17/face-recognition-with-facebook-deepface-in-keras/), [`DeepID`](https://sefiks.com/2020/06/16/face-recognition-with-deepid-in-keras/), [`ArcFace`](https://sefiks.com/2020/12/14/deep-face-recognition-with-arcface-in-keras-and-python/), [`Dlib`](https://sefiks.com/2020/07/11/face-recognition-with-dlib-in-python/), `SFace` and `GhostFaceNet`. According to [`experiments`](https://github.com/serengil/deepface/tree/master/benchmarks), those models reached or passed human-level accuracy. 49 | 50 | Similarly, it wraps many cutting-edge face detectors: [`OpenCV`](https://sefiks.com/2020/02/23/face-alignment-for-face-recognition-in-python-within-opencv/), [`Ssd`](https://sefiks.com/2020/08/25/deep-face-detection-with-opencv-in-python/), [`Dlib`](https://sefiks.com/2020/07/11/face-recognition-with-dlib-in-python/), [`MtCnn`](https://sefiks.com/2020/09/09/deep-face-detection-with-mtcnn-in-python/), `Faster MtCnn`, [`RetinaFace`](https://sefiks.com/2021/04/27/deep-face-detection-with-retinaface-in-python/), [`MediaPipe`](https://sefiks.com/2022/01/14/deep-face-detection-with-mediapipe/), `Yolo`, `YuNet` and `CenterFace`. 51 | 52 | Both facial recognition models and face detectors can be set in the `.env` file. 53 | 54 | ```yaml 55 | # Set facial recognition model: VGG-Face, Facenet, Facenet512, OpenFace, DeepFace, DeepId, ArcFace, Dlib, SFace, GhostFaceNet 56 | REACT_APP_FACE_RECOGNITION_MODEL=Facenet 57 | 58 | # Set face detector: opencv, ssd, mtcnn, dlib, mediapipe, retinaface, yolov8, yunet, centerface 59 | REACT_APP_DETECTOR_BACKEND=opencv 60 | 61 | # Set distance metric: cosine, euclidean, euclidean_l2 62 | REACT_APP_DISTANCE_METRIC=cosine 63 | ``` 64 | 65 | ## Running Service Directly 66 | 67 | Firstly, you should run the deepface service as 68 | 69 | ```shell 70 | # go to project's directory 71 | cd deepface/scripts 72 | 73 | # run the dockerized service 74 | ./dockerize.sh 75 | 76 | # or instead of running dockerized service, run it directly if you installed requirements.txt 77 | # ./service.sh 78 | ``` 79 | 80 | In seperate terminal, you should run deepface react ui as 81 | 82 | ```shell 83 | # go to project's directory 84 | cd deepface-react-ui/scripts 85 | 86 | # run the dockerized service 87 | ./dockerize.sh 88 | 89 | # or instead of running dockerized service, run it directly 90 | # ./service.sh 91 | ``` 92 | 93 | ## Running via Docker Compose 94 | 95 | Instead of running deepface and deepface react ui seperately in different terminals, you can run the standalone docker compose. 96 | 97 | ```shell 98 | # clone source code 99 | git clone https://github.com/serengil/deepface-react-ui.git \ 100 | && git clone https://github.com/serengil/deepface.git 101 | 102 | # go to project's directory 103 | cd deepface-react-ui/scripts 104 | 105 | # run services 106 | ./compose.sh 107 | ``` 108 | 109 | ## Using The App - [`Demo`](https://youtu.be/IXoah6rhxac) 110 | 111 | Once you start the service, the DeepFace service will be accessible at `http://localhost:5005/`, and the DeepFace React UI will be available at `http://localhost:3000/`. 112 | 113 | To use the DeepFace React UI, open `http://localhost:3000/` in your browser. The UI will prompt access to your webcam and search for identities within the current frame using the facial database specified in the `.env` file when you click on the "Verify" button. 114 | 115 | ## Facial Attribute Analysis - [`Demo`](https://youtu.be/_waBA-cH2D4) 116 | 117 | UI also supports demography analysis including age, gender, emotion and race & ethnicity prediction tasks. 118 | 119 |

120 | 121 | ## Support 122 | 123 | There are many ways to support a project - starring⭐️ the GitHub repo is just one 🙏 124 | 125 | If you do like this work, then you can support it on [Patreon](https://www.patreon.com/serengil?repo=deepface), [GitHub Sponsors](https://github.com/sponsors/serengil) or [Buy Me a Coffee](https://buymeacoffee.com/serengil). 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | # Citation 136 | 137 | Please cite deepface-react-ui in your publications if it helps your research. Here is its BibTex entry: 138 | 139 | ```BibTeX 140 | @article{serengil2024lightface, 141 | title = {A Benchmark of Facial Recognition Pipelines and Co-Usability Performances of Modules}, 142 | author = {Serengil, Sefik and Ozpinar, Alper}, 143 | journal = {Journal of Information Technologies}, 144 | volume = {17}, 145 | number = {2}, 146 | pages = {95-107}, 147 | year = {2024}, 148 | doi = {10.17671/gazibtd.1399077}, 149 | url = {https://dergipark.org.tr/en/pub/gazibtd/issue/84331/1399077}, 150 | publisher = {Gazi University} 151 | } 152 | ``` 153 | 154 | ## Licence 155 | 156 | DeepFace React UI is licensed under the MIT License - see [`LICENSE`](https://github.com/serengil/deepface-react-ui/blob/main/LICENSE) for more details. 157 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | deepface: 3 | build: ../deepface 4 | container_name: deepface 5 | ports: 6 | - "5005:5000" # Assuming deepface runs on port 5000 7 | environment: 8 | - CUDA_VISIBLE_DEVICES=-1 # disable gpu 9 | 10 | deepface-react-ui: 11 | build: . 12 | container_name: deepface_react_ui_container 13 | ports: 14 | - "3000:3000" # Assuming deepface-react-ui runs on port 3000 15 | depends_on: 16 | - deepface -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deepface-react-ui", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.3.1", 10 | "react-dom": "^18.3.1", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/serengil/deepface-react-ui/90bdad37e40136c93e9d9d01e4487f34e4e00954/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/serengil/deepface-react-ui/90bdad37e40136c93e9d9d01e4487f34e4e00954/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/serengil/deepface-react-ui/90bdad37e40136c93e9d9d01e4487f34e4e00954/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /resources/demography.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/serengil/deepface-react-ui/90bdad37e40136c93e9d9d01e4487f34e4e00954/resources/demography.jpg -------------------------------------------------------------------------------- /resources/tp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/serengil/deepface-react-ui/90bdad37e40136c93e9d9d01e4487f34e4e00954/resources/tp.jpg -------------------------------------------------------------------------------- /scripts/compose.sh: -------------------------------------------------------------------------------- 1 | cd .. 2 | 3 | docker-compose up --build -------------------------------------------------------------------------------- /scripts/dockerize.sh: -------------------------------------------------------------------------------- 1 | cd .. 2 | 3 | # remove exisiting images 4 | # docker rm -f $(docker ps -a -q --filter "ancestor=deepface-react-app") 5 | 6 | # docker build -t deepface-react-app . 7 | 8 | docker run -p 3000:3000 deepface-react-app -------------------------------------------------------------------------------- /scripts/service.sh: -------------------------------------------------------------------------------- 1 | cd .. 2 | 3 | npm start -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { useRef, useEffect, useState } from 'react'; 2 | 3 | function App() { 4 | const facialRecognitionModel = process.env.REACT_APP_FACE_RECOGNITION_MODEL || "Facenet"; 5 | const faceDetector = process.env.REACT_APP_DETECTOR_BACKEND || "opencv"; 6 | const distanceMetric = process.env.REACT_APP_DISTANCE_METRIC || "cosine"; 7 | 8 | const serviceEndpoint = process.env.REACT_APP_SERVICE_ENDPOINT; 9 | const antiSpoofing = process.env.REACT_APP_ANTI_SPOOFING === "1" 10 | 11 | const videoRef = useRef(null); 12 | const canvasRef = useRef(null); 13 | 14 | const [base64Image, setBase64Image] = useState(''); 15 | 16 | const [isVerified, setIsVerified] = useState(null); 17 | const [identity, setIdentity] = useState(null); 18 | 19 | const [isAnalyzed, setIsAnalyzed] = useState(null); 20 | const [analysis, setAnalysis] = useState([]); 21 | 22 | const [facialDb, setFacialDb] = useState({}); 23 | 24 | useEffect(() => { 25 | const loadFacialDb = async () => { 26 | const envVarsWithPrefix = {}; 27 | for (const key in process.env) { 28 | if (key.startsWith("REACT_APP_USER_")) { 29 | envVarsWithPrefix[key.replace("REACT_APP_USER_", "")] = process.env[key]; 30 | } 31 | } 32 | return envVarsWithPrefix; 33 | }; 34 | 35 | const fetchFacialDb = async () => { 36 | try { 37 | const loadedFacialDb = await loadFacialDb(); 38 | setFacialDb(loadedFacialDb); 39 | } catch (error) { 40 | console.error('Error loading facial database:', error); 41 | } 42 | }; 43 | 44 | fetchFacialDb(); 45 | 46 | }, [facialDb]); 47 | 48 | useEffect(() => { 49 | let video = videoRef.current; 50 | if (video) { 51 | const getVideo = async () => { 52 | try { 53 | const stream = await navigator.mediaDevices.getUserMedia({ video: true }); 54 | video.srcObject = stream; 55 | await video.play(); 56 | } catch (err) { 57 | console.error("Error accessing webcam: ", err); 58 | } 59 | }; 60 | getVideo(); 61 | } 62 | }, []); 63 | 64 | const captureImage = (task) => { 65 | // flush variable states when you click verify 66 | setIsVerified(null); 67 | setIdentity(null); 68 | 69 | const video = videoRef.current; 70 | const canvas = canvasRef.current; 71 | const context = canvas.getContext('2d'); 72 | 73 | canvas.width = video.videoWidth; 74 | canvas.height = video.videoHeight; 75 | 76 | context.drawImage(video, 0, 0, canvas.width, canvas.height); 77 | 78 | const base64Img = canvas.toDataURL('image/png'); 79 | setBase64Image(base64Img); 80 | 81 | // first click causes blank string 82 | if (base64Image === null || base64Image === "") { 83 | return 84 | } 85 | 86 | if (task === "verify") { 87 | verify(base64Image) 88 | console.log(`verification result is ${isVerified} - ${identity}`) 89 | } 90 | else if (task === "analyze") { 91 | analyze(base64Image) 92 | } 93 | 94 | }; 95 | 96 | const verify = async (base64Image) => { 97 | try { 98 | for (const key in facialDb) { 99 | const targetEmbedding = facialDb[key]; 100 | 101 | const requestBody = JSON.stringify( 102 | { 103 | model_name: facialRecognitionModel, 104 | detector_backend: faceDetector, 105 | distance_metric: distanceMetric, 106 | align: true, 107 | img1: base64Image, 108 | img2: targetEmbedding, 109 | enforce_detection: false, 110 | anti_spoofing: antiSpoofing, 111 | } 112 | ); 113 | 114 | console.log(`calling service endpoint ${serviceEndpoint}/verify`) 115 | 116 | const response = await fetch(`${serviceEndpoint}/verify`, { 117 | method: 'POST', 118 | headers: { 119 | 'Content-Type': 'application/json', 120 | }, 121 | body: requestBody, 122 | }); 123 | 124 | const data = await response.json(); 125 | 126 | if (response.status !== 200) { 127 | console.log(data.error); 128 | setIsVerified(false); 129 | return 130 | } 131 | 132 | if (data.verified === true) { 133 | setIsVerified(true); 134 | setIsAnalyzed(false); 135 | setIdentity(key); 136 | break; 137 | } 138 | 139 | } 140 | 141 | // if isVerified key is not true after for loop, then it is false 142 | if (isVerified === null) { 143 | setIsVerified(false); 144 | } 145 | 146 | } 147 | catch (error) { 148 | console.error('Exception while verifying image:', error); 149 | } 150 | 151 | }; 152 | 153 | const analyze = async (base64Image) => { 154 | const result = [] 155 | setIsAnalyzed(false) 156 | try { 157 | const requestBody = JSON.stringify( 158 | { 159 | detector_backend: faceDetector, 160 | align: true, 161 | img: base64Image, 162 | enforce_detection: false, 163 | anti_spoofing: antiSpoofing, 164 | } 165 | ); 166 | 167 | const response = await fetch(`${serviceEndpoint}/analyze`, { 168 | method: 'POST', 169 | headers: { 170 | 'Content-Type': 'application/json', 171 | }, 172 | body: requestBody, 173 | }); 174 | 175 | const data = await response.json(); 176 | 177 | if (response.status !== 200) { 178 | console.log(data.error); 179 | return 180 | } 181 | 182 | for (const instance of data.results){ 183 | const summary = `${instance.age} years old ${instance.dominant_race} ${instance.dominant_gender} with ${instance.dominant_emotion} mood.` 184 | console.log(summary) 185 | result.push(summary) 186 | } 187 | 188 | if (result.length > 0) { 189 | setIsAnalyzed(true); 190 | setIsVerified(null); 191 | setAnalysis(result); 192 | } 193 | 194 | } 195 | catch (error) { 196 | console.error('Exception while analyzing image:', error); 197 | } 198 | return result 199 | 200 | }; 201 | 202 | return ( 203 |
216 |
217 |

DeepFace React App

218 | {/* Conditional rendering based on verification status */} 219 | {isVerified === true &&

Verified. Welcome {identity}

} 220 | {isVerified === false &&

Not Verified

} 221 | {isAnalyzed === true &&

{analysis.join()}

} 222 |
230 |
231 | ); 232 | } 233 | 234 | export default App; 235 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | --------------------------------------------------------------------------------