Web quality check API

POST /qualitycheck?full=true&issuer=ICAO


With the quality check Web API a single facial media sample can be uploaded to the BWS to perform a rigorous quality check according to ICAO (International Civil Aviation Organization) requirements for machine readable travel documents (MRTDs), which include a standard for the digital image quality of facial images, defining requirements for photographic and digital characteristics (see ISO/IEC 19794-5:2011, ISO/IEC 29794-5:2010 or ICAO Document 9303).

Quality checks for traits other than face are currently not supported with this API.

Remarks

The quality checks performed with this method are descried with the SOAP Quality Check API.

Request Information

Parameters

full Optional, defaults to true. A boolean parameter to select full document mode or token data mode. If set to true, the checks are performed according to the ICAO specifications for travel documents and an output sample is created according to these specifications, whereby the content of the sample is not modified. Otherwise, if set to false, the so called token data is extracted from the given sample, which is typically intended to be stored for later use with a biometric recognition system.
issuer Optional, defaults to ICAO. The quality checks of facial images can be performed according to document-issuer specific settings defined by this parameter. Currently supported issuers are: ICAO (the default settings as specified by ICAO), BioID (similar to ICAO but with a bigger token image) and various ISO 3166-1 alpha-2 country codes specifying the document issuing country.

Request Body Format

The request body contains a single image media sample, encoded into a Data-URL using the data URI scheme as described in RFC 2397 (see also at Wikipedia).

Authentication

This API call requires Basic Authentication, i.e. you have to provide an HTTP authorization header using the authorization method Basic and the base64 encoded string App-ID:App-Secret (therefore the transport is secured using TLS/SSL). To receive the necessary BWS Web API access data (App-ID and App-Secret) you have to register your application on the BWS Management Portal first. This requires a valid BWS subscription.

Response Information

The QualityCheck Web API returns a QualityCheckResult object, which informs about the Success of the check and lists Errors that occurred during the check. Refer to the SOAP Quality Check API for a list of possible error-codes. Additionally the coordinates of the found EyeCenters are returned. Finally the processed image is returned in the ProcessedSample element if possible, encoded into a Data-URL.

Response Body Format

Exemplary QualityCheck response
{
  "Success": true,
  "Errors": [
    {
      "Code": "ImageTooSmall",
      "Message": "The part of the image containing the found face is too small.",
      "Details": "The found face (with an eye-distance of 119 pixels) does not have the required eye-distance of at least 240 pixels."
    },
    {
      "Code": "FaceAsymmetry",
      "Message": "It seems that the face of the found person is somehow asymmetric, maybe due to bad illumination and/or due to a wrong pose.",
      "Details": "An asymmetry of 101.99 was calculated, where only a value up to 50.00 is allowed."
    },
    {
      "Code": "ImageTooBlurry",
      "Message": "The image is too blurry, i.e. it is not sharp enough.",
      "Details": "An image blurring of 10.45% was calculated, where up to 9.00% is allowed. Note that compression artifacts might be the reason for this fuzziness as they reduce the objective sharpness more than the subjective sharpness."
    }
  ],
  "EyeCenters": 
  {
    "RightEyeX": 828.401, "RightEyeY": 584.267, "LeftEyeX": 947.88, "LeftEyeY": 587.003
  },
  "ProcessedSample": "data:image/bmp;base64,..."
}


Response HTTP Status Codes

The call returns one of the standard HTTP status codes. With the success code (200) you receive the QualityCheckResult object in the body text. With erroneous codes you typically receive a Message field within the body text describing the error. The most commonly return codes are:

200 OK The response body contains the QualityCheckResult object.
400 Bad Request No or an invalid sample data has been uploaded.
401 Unauthorized No or an invalid authentication header has been specified. This call requires Basic Authentication.
403 Forbidden Access has been denied (typically due to a wrong or invalid app-id).
500 Internal Server Error A server side exception occurred.

Sample Code

[DataContract]
public class QualityCheckResponse
{
    [DataContract]
    public class Error
    {
        [DataMember] public string Code { get; set; }
        [DataMember] public string Message { get; set; }
        [DataMember] public string Details { get; set; }
    }
 
    [DataContract]
    public class EyeCoordinates
    {
        [DataMember] public double LeftEyeX { get; set; }
        [DataMember] public double LeftEyeY { get; set; }
        [DataMember] public double RightEyeX { get; set; }
        [DataMember] public double RightEyeY { get; set; }
    }
 
    [DataMember] public bool Success { get; set; }
    [DataMember] public string ProcessedSample { get; set; }
    [DataMember] public List<Error> Errors { get; set; }
    [DataMember] public EyeCoordinates EyeCenters { get; set; }
}

// ...

using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
        Convert.ToBase64String(Encoding.ASCII.GetBytes($"{APP_IDENTIFIER}:{APP_SECRET}")));
    byte[] buffer;
    using (var imagestream = image.OpenRead())
    {
        buffer = new byte[imagestream.Length];
        await imagestream.ReadAsync(buffer, 0, buffer.Length);
    }
    using (var content = new StringContent("data:image/png;base64," + Convert.ToBase64String(buffer)))
    using (var response = await client.PostAsync(ENDPOINT + $"qualitycheck?issuer={issuer}", content))
    {
        if (response.StatusCode == HttpStatusCode.OK)
        {
            using (var stream = await response.Content.ReadAsStreamAsync())
            {
                var dcs = new DataContractJsonSerializer(typeof(QualityCheckResponse));
                return (QualityCheckResponse)dcs.ReadObject(stream);
            }
        }
    }
}

// using OkHttpClient from the OkHttp library
HttpUrl url = HttpUrl.parse("https://bws.bioid.com/extension/qualitycheck").newBuilder()
        .addQueryParameter("full", "true")
        .addQueryParameter("issuer", "ICAO")
        .build();
Request request = new Request.Builder()
        .url(url)
        .addHeader("Authorization", Credentials.basic(APP_IDENTIFIER, APP_SECRET))
        .post(RequestBody.create(MediaType.parse("text/plain"), "data:image/png;base64," + Base64.getEncoder().encodeToString(getPngAsByteArray())))
        .build();
OkHttpClient client = new OkHttpClient();
Response response = client.newCall(request).execute();
if (response.code() == 200) {
    // using org.json.JSONObject from JSON-java library
    JSONObject json = new JSONObject(response.body().string());
    if (json.getBoolean("Success")) {
        System.out.println("quality check has been performed");
    } else {
        System.out.println("quality check was not possible");
    }
}