├── Android ├── PresentIDFaceVerificationAPI.java └── PresentIDPostURLUtils.java ├── CSharp ├── FaceVerificationResponseResult.cs └── PresentIDFaceVerificationAPI.cs ├── Java └── FaceVerificationResponseResult.java ├── Python └── FaceVerification.py └── README.md /Android/PresentIDFaceVerificationAPI.java: -------------------------------------------------------------------------------- 1 | package YourPackageName; 2 | 3 | import com.loopj.android.http.JsonHttpResponseHandler; 4 | import com.loopj.android.http.RequestParams; 5 | import org.json.JSONException; 6 | 7 | import java.io.BufferedInputStream; 8 | import java.io.ByteArrayInputStream; 9 | import java.io.ByteArrayOutputStream; 10 | import java.io.File; 11 | import java.io.FileInputStream; 12 | import java.io.FileNotFoundException; 13 | import java.io.IOException; 14 | import java.net.InetAddress; 15 | import java.util.List; 16 | 17 | 18 | public class PresentIDFaceVerificationAPI{ 19 | private static int resultCode; 20 | 21 | public static void faceVerification(String imageFile1, String imageFile2){ 22 | resultCode = -100; 23 | post(imageFile1, imageFile2); 24 | return; 25 | } 26 | 27 | public static getFaceVerificationResult(){ 28 | return resultCode; 29 | } 30 | 31 | private byte[] getByteArrayFromFile (String aFileName){ 32 | File vFile = new File(aFileName); 33 | int size = (int) vFile.length(); 34 | byte[] bytes = new byte[size]; 35 | 36 | try { 37 | BufferedInputStream buf = new BufferedInputStream(new FileInputStream(vFile)); 38 | buf.read(bytes, 0, bytes.length); 39 | buf.close(); 40 | return bytes; 41 | } catch (FileNotFoundException e) { 42 | e.printStackTrace(); 43 | } catch (IOException e) { 44 | e.printStackTrace(); 45 | } 46 | return null; 47 | } 48 | 49 | private void post(String imageFile1, String imageFile2) { 50 | try{ 51 | 52 | byte[] photo1ByteArray = getByteArrayFromFile(imageFile1); 53 | byte[] photo2ByteArray = getByteArrayFromFile(imageFile2); 54 | 55 | RequestParams params = new RequestParams(); 56 | params.put("photo1", new ByteArrayInputStream(photo1ByteArray), "photo1.jpg"); 57 | params.put("photo2", new ByteArrayInputStream(photo2ByteArray), "photo2.jpg"); 58 | HiBrainyPostURLUtils.post("iamhere/", params, new JsonHttpResponseHandler() { 59 | @Override 60 | public void onStart() { 61 | super.onStart(); 62 | } 63 | 64 | @Override 65 | public void onSuccess(int statusCode, Header[] headers, org.json.JSONObject obj) { 66 | try { 67 | int VerificationResult = obj.getJSONObject("VerificationResult").getInt(("resultIndex")); 68 | switch (VerificationResult){ 69 | case -2 : resultCode = -2; /* Your Code... */ break; //in the second photo, the FACE was Not Found 70 | case -1 : resultCode = -1; /* Your Code... */ break; //in the first photo, the FACE was Not Found 71 | case 0 : resultCode = 0; /* Your Code... */ break; //2 faces belong to the same person. 72 | case 1 : resultCode = 1; /* Your Code... */ break; //2 faces belong to the same person probabely. 73 | case 2 : resultCode = 2; /* Your Code... */ break; //2 faces belong to the different people probabely. 74 | case 3 : resultCode = 3; /* Your Code... */ break; //2 faces belong to the different people. 75 | } 76 | } catch (JSONException e) { 77 | e.printStackTrace(); 78 | } 79 | } 80 | 81 | @Override 82 | public void onFailure(int statusCode, Header[] headers, 83 | Throwable throwable, org.json.JSONObject errorResponse) { 84 | resultCode = -200; 85 | Toast.makeText(getApplicationContext(),"Your Error Message....",Toast.LENGTH_LONG).show(); 86 | } 87 | 88 | @Override 89 | public void onFinish() { 90 | } 91 | }); 92 | 93 | } catch (Exception e) { 94 | e.printStackTrace(); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Android/PresentIDPostURLUtils.java: -------------------------------------------------------------------------------- 1 | package YourPackageName; 2 | 3 | import com.loopj.android.http.AsyncHttpClient; 4 | import com.loopj.android.http.AsyncHttpResponseHandler; 5 | import com.loopj.android.http.RequestParams; 6 | 7 | import cz.msebera.android.httpclient.Header; 8 | import cz.msebera.android.httpclient.message.BasicHeader; 9 | 10 | public class HiBrainyPostURLUtils { 11 | private static final String apiURL = "http://api.hibrainy.com/api/v1/Face/FaceVerification/"; 12 | private static final String apiKey = "Your API Key"; 13 | 14 | private static AsyncHttpClient client = new AsyncHttpClient(); 15 | 16 | public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { 17 | client.get(getAbsoluteUrl(url), params, responseHandler); 18 | } 19 | 20 | public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { 21 | client.removeAllHeaders(); 22 | client.addHeader("API-Key", apiKey); 23 | client.post(getAbsoluteUrl(url), params, responseHandler); 24 | } 25 | 26 | public static void getByUrl(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { 27 | client.get(url, params, responseHandler); 28 | } 29 | 30 | public static void postByUrl(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { 31 | client.removeAllHeaders(); 32 | client.addHeader("API-Key", apiKey); 33 | client.post(url, params, responseHandler); 34 | } 35 | 36 | private static String getAbsoluteUrl(String relativeUrl) { 37 | return apiURL + relativeUrl; 38 | } 39 | } 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /CSharp/FaceVerificationResponseResult.cs: -------------------------------------------------------------------------------- 1 | public class FaceVerificationResponseResult 2 | { 3 | public int StatusCode { set; get; } 4 | public string StatusMessage { set; get; } 5 | public bool HasError { set; get; } 6 | public FaceVerificationResult VerificationResult { set; get; } 7 | public List Features { set; get; } 8 | } 9 | 10 | public class FaceVerificationResult 11 | { 12 | public int resultIndex { set; get; } 13 | public string resultMessage { set; get; } 14 | public double similarPercent { set; get; } 15 | } 16 | 17 | public class Features 18 | { 19 | public Gender Gender { get; set; } 20 | public AgeBoundary Age { get; set; } 21 | public RectPoints Framepoints { get; set; } 22 | } 23 | 24 | public class RectPoints 25 | { 26 | public Dot LeftTop { get; set; } 27 | public Dot RightTop { get; set; } 28 | public Dot RightBottom { get; set; } 29 | public Dot LeftBottom { get; set; } 30 | } 31 | 32 | public class Dot 33 | { 34 | public int x { set; get; } 35 | public int y { set; get; } 36 | } 37 | 38 | public class Gender 39 | { 40 | public int index { set; get; } 41 | public string title { set; get; } 42 | } 43 | 44 | public class AgeBoundary 45 | { 46 | public int minAge { set; get; } 47 | public int maxAge { set; get; } 48 | } -------------------------------------------------------------------------------- /CSharp/PresentIDFaceVerificationAPI.cs: -------------------------------------------------------------------------------- 1 | class PresentIDFaceVerificationAPI 2 | { 3 | string apiKey; 4 | 5 | public PresentIDFaceVerificationAPI(string apiKey) 6 | { 7 | this.apiKey = apiKey; 8 | } 9 | 10 | public async Task FaceVerificationAsync(string FileName1st, string FileName2nd) 11 | { 12 | var content = new MultipartFormDataContent(); 13 | var response = new HttpResponseMessage(); 14 | string apiUrl = "http://api.hibrainy.com/api/v1/Face/FaceVerification"; 15 | FaceVerificationResponseResult faces = new FaceVerificationResponseResult(); 16 | try 17 | { 18 | content.Headers.Add("API-Key", apiKey); 19 | content.Add(new ByteArrayContent(File.ReadAllBytes(FileName1st)), "photo1", FileName1st.Split('\\').LastOrDefault()); 20 | content.Add(new ByteArrayContent(File.ReadAllBytes(FileName2nd)), "photo2", FileName2nd.Split('\\').LastOrDefault()); 21 | } 22 | catch (Exception ex) { throw new Exception(ex.Message); } 23 | try 24 | { 25 | using (var http = new HttpClient()) 26 | { 27 | response = await http.PostAsync(apiUrl, content); 28 | } 29 | string resMessage = await response.Content.ReadAsStringAsync(); 30 | if (response.IsSuccessStatusCode) 31 | { 32 | faces = JsonConvert.DeserializeObject(resMessage); 33 | return faces; 34 | } 35 | else 36 | { throw new Exception(resMessage); } 37 | } 38 | catch (Exception ex) { throw new Exception(ex.Message); } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Java/FaceVerificationResponseResult.java: -------------------------------------------------------------------------------- 1 | public class FaceVerificationResponseResult { 2 | //Connection Status 3 | boolean hasError; 4 | int StatusCode; 5 | String StatusMessage; 6 | 7 | //Verification Result 8 | int resultIndex; 9 | String resultMessage; 10 | float similarPercent; 11 | 12 | //FacePoints 13 | int [][] LeftTop; 14 | int [][] RightTop; 15 | int [][] RightBottom; 16 | int [][] LeftBottom; 17 | 18 | 19 | public boolean gethasError() { 20 | return hasError; 21 | } 22 | 23 | public void sethasError(boolean hasError) { 24 | this.hasError = hasError; 25 | } 26 | public int getStatusCode() { 27 | return StatusCode; 28 | } 29 | 30 | public void setStatusCode(int StatusCode) { 31 | this.StatusCode = StatusCode; 32 | } 33 | 34 | public String getStatusMessage() { 35 | return StatusMessage; 36 | } 37 | 38 | public void setStatusMessage(String StatusMessage) { 39 | this.StatusMessage = StatusMessage; 40 | } 41 | 42 | public int getresultIndex() { 43 | return resultIndex; 44 | } 45 | 46 | public void setresultIndex(int resultIndex) { 47 | this.resultIndex = resultIndex; 48 | } 49 | 50 | public String getresultMessage() { 51 | return resultMessage; 52 | } 53 | 54 | public void setresultMessage(String resultMessage) { 55 | this.resultMessage = resultMessage; 56 | } 57 | 58 | 59 | public float getsimilarPercent() { 60 | return similarPercent; 61 | } 62 | 63 | public void setsimilarPercent(float similarPercent) { 64 | this.similarPercent = similarPercent; 65 | } 66 | 67 | public int [][] getLeftTop() { 68 | return LeftTop; 69 | } 70 | 71 | public void setLeftTop(int LeftTop[][]) { 72 | this.LeftTop[0][0] = LeftTop[0][0]; 73 | this.LeftTop[0][1] = LeftTop[0][1]; 74 | 75 | } 76 | 77 | public int [][] getRightTop() { 78 | return RightTop; 79 | } 80 | 81 | public void setRightTop(int RightTop[][]) { 82 | this.RightTop[0][0] = RightTop[0][0]; 83 | this.RightTop[0][1] = RightTop[0][1]; 84 | 85 | } 86 | 87 | public int [][] getRightBottom() { 88 | return RightTop; 89 | } 90 | 91 | public void setRightBottom(int RightBottom[][]) { 92 | this.RightBottom[0][0] = RightBottom[0][0]; 93 | this.RightBottom[0][1] = RightBottom[0][1]; 94 | 95 | } 96 | 97 | public int [][] getLeftBottom() { 98 | return RightTop; 99 | } 100 | 101 | public void setLeftBottom(int LeftBottom[][]) { 102 | this.LeftBottom[0][0] = LeftBottom[0][0]; 103 | this.LeftBottom[0][1] = LeftBottom[0][1]; 104 | 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /Python/FaceVerification.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | url = "https://face-verification2.p.rapidapi.com/FaceVerification" 4 | 5 | payload = "-----011000010111000001101001\r 6 | Content-Disposition: form-data; name=\"photo1\"\r 7 | \r 8 | \r 9 | -----011000010111000001101001\r 10 | Content-Disposition: form-data; name=\"photo2\"\r 11 | \r 12 | \r 13 | -----011000010111000001101001--\r 14 | \r 15 | " 16 | headers = { 17 | 'content-type': "multipart/form-data; boundary=---011000010111000001101001", 18 | 'x-rapidapi-key': "f485496ab8msh2ea068a0bbe333cp179f86jsn2b4afe8962dd", 19 | 'x-rapidapi-host': "face-verification2.p.rapidapi.com" 20 | } 21 | 22 | response = requests.request("POST", url, data=payload, headers=headers) 23 | 24 | print(response.text) 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## PresentID Photo ID Matching (Face Verification) 2 | PresentID Photo ID matching API evaluates whether two faces belong to the same person or not. Face verification ensures a one-to-one (1:1) match of a face image captured at the time of onboarding with an image captured from a trusted credential such as a driver’s license, or a passport. 3 | 4 | We have created a very deep convolutional neural network to extract very high-level features from a face for each person. We have provided a large-scale image database of faces from many sources e.g. web crowdsourcing, our built-in house dataset. There is a lot of diversity of races in the database. Our model inference time is 115ms on Intel CPU corei7 6700k. Especially in our solution, we save some frames that come from client SDK that is selected based on our own algorithm. This feature makes our matching stronger. Moreover, we save a checksum from a video to check duplicated videos. 5 | 6 | Our method has got promising results under large appearance variations e.g. pose, age gaps, skin, glass, makeup, and beard. 7 | 8 | 9 | 10 | **Youtube Videos** 11 | - https://www.youtube.com/embed/RqKJVjiaQhQ 12 | 13 | **Input:** 14 | - Image file 15 | - Image URL link 16 | - Base64 image 17 | 18 | **Output:** 19 | - Result index 20 | - Image specs 21 | - Similar percent 22 | - Result message 23 | 24 | **Features:** 25 | - Less than 10 seconds. 26 | - Accuracy is %99.76 on the LFW face verification dataset, a very popular benchmark. 27 | - Support IOS, Android, Windows and Mac devices. 28 | - The smallest faces are detected (48px * 48px). 29 | - Easy integration with your app. 30 | 31 | **Use Cases:** 32 | - Access Control 33 | - Onboarding 34 | - Fintech 35 | - Car sharing & Taxi 36 | - Online Brokers 37 | - Health Care 38 | - Dating Apps 39 | - Customer Support 40 | 41 | **Rules & Restrictions:** 42 | - Send data via Base64 or an image URL or an image file. 43 | - Image size should not exceed 8 MB. 44 | - Also, the images should not be larger than 5000 pixels and smaller than 50 pixels. 45 | 46 | ## Free try in RapidAPI 47 | https://rapidapi.com/PresentID/api/face-verification2 48 | --------------------------------------------------------------------------------