Integration with Face SDK
The integration of the Document Reader with the Face SDK adds an automatic face match and search features using portraits from the document's visual zone (such as the portrait and ghost portrait), barcode, RFID chip, an external source (gallery, database, etc.), or taken on the mobile device camera.
- Enable integration with Face SDK
- Enable One-Shot Identification
- Add external and live portraits
- Configure parameters
How to Enable
To enable the integration with the Face SDK, use the parameter:
DocReader.shared.processParams.useFaceApi = true
[RGLDocReader shared].processParams.useFaceApi = @YES;
DocumentReader.Instance().processParams().useFaceApi = true
DocumentReader.Instance().processParams().useFaceApi = true;
DocumentReader.instance.processParams.useFaceApi = true;
var params = new ProcessParams()
params.useFaceApi = true
DocumentReader.setProcessParams(params, _ => { }, _ => { })
var params = new ProcessParams()
params.useFaceApi = true
DocumentReader.setProcessParams(params)
var params = new ProcessParams()
params.useFaceApi = true
DocumentReader.setProcessParams(params, function (m) { }, function (e) { })
// Android
DocumentReader.Instance().ProcessParams().UseFaceApi = (Java.Lang.Boolean)true;
// iOS
RGLDocReader.Shared.ProcessParams.UseFaceApi = true;
After the integration is enabled, the Face API is applied with default configurations that can be further customized. For details, see the Configure Parameters section.
One-Shot Identification
One-Shot Identification mode allows you to recognize the document, automatically extract portraits from the document and live photo, and then compare them to each other. This simplifies the integration and usage of both SDKs: Document Reader and Face.
The functionality works only in the single-frame processing mode, but not during live video stream capturing.
To enable One-Shot Identification mode, do:
let config = DocReader.RecognizeConfig(images: images)
config.scenario = RGL_SCENARIO_FULL_PROCESS
config.oneShotIdentification = true
RGLRecognizeConfig *config = [[RGLRecognizeConfig alloc] initWithImages:images];
config.scenario = RGL_SCENARIO_FULL_PROCESS;
config.oneShotIdentification = YES;
val recognizeConfig = RecognizeConfig.Builder(Scenario.SCENARIO_FULL_PROCESS).setBitmaps(bitmaps).setOneShotIdentification(true).build()
RecognizeConfig recognizeConfig = new RecognizeConfig.Builder(Scenario.SCENARIO_FULL_PROCESS).setBitmaps(bitmaps).setOneShotIdentification(true).build();
var config = RecognizeConfig.withScenario(
Scenario.FULL_PROCESS,
image: image,
oneShotIdentification: true,
);
var config = new RecognizeConfig()
config.scenario = ScenarioIdentifier.SCENARIO_FULL_PROCESS
config.image = image
config.oneShotIdentification = true
var config = new RecognizeConfig()
config.scenario = ScenarioIdentifier.SCENARIO_FULL_PROCESS
config.image = image
config.oneShotIdentification = true
var config = new RecognizeConfig()
config.scenario = ScenarioIdentifier.SCENARIO_FULL_PROCESS
config.image = image
config.oneShotIdentification = true
// Android
DocumentReader.Instance().ProcessParams().Scenario = Scenario.ScenarioFullProcess;
DocumentReader.Instance().ProcessParams().OneShotIdentification = true;
// iOS
RGLDocReader.Shared.ProcessParams.Scenario = Constants.RGL_SCENARIO_FULL_PROCESS;
RGLDocReader.Shared.ProcessParams.OneShotIdentification = true;
Then you can pick the image from Gallery or Files, and process it.
External and Live Portraits
When the Face SDK integration is enabled as described in the previous section, you can add either one or both portraits for the face match and search:
- External is a portrait taken from the gallery, database, etc.
- Live is a portrait captured directly from the mobile device camera
The portraits have to be added at the moment of the Config object creation and before starting the document processing.
The samples below demonstrate the creation of the RecognizeConfig for picking the document image from the gallery. As the config object cannot be created without setting the processing scenario, the Full Processing scenario is applied as an example.
let config = DocReader.RecognizeConfig(images: images)
config.scenario = RGL_SCENARIO_FULL_PROCESS
config.extPortrait = UIImage(named: "external-portrait")
config.livePortrait = UIImage(named: "live-portrait")
RGLScannerConfig *config = [[RGLScannerConfig alloc] init];
config.scenario = RGL_SCENARIO_FULL_PROCESS;
config.extPortrait = [UIImage imageNamed:@"external-portrait"];
config.livePortrait = [UIImage imageNamed:@"live-portrait"];
val externalPortrait = BitmapFactory.decodeResource(context.resources,
R.drawable.external_portrait)
val livePortrait = BitmapFactory.decodeResource(context.resources,
R.drawable.live_portrait)
val config = ScannerConfig.Builder(Scenario.SCENARIO_FULL_PROCESS)
.setExtPortrait(externalPortrait)
.setLivePortrait(livePortrait)
.build()
Bitmap externalPortrait = BitmapFactory.decodeResource(context.getResources(),
R.drawable.external_portrait);
Bitmap livePortrait = BitmapFactory.decodeResource(context.getResources(),
R.drawable.live_portrait);
ScannerConfig config = new ScannerConfig.Builder(Scenario.SCENARIO_FULL_PROCESS)
.setExtPortrait(externalPortrait)
.setLivePortrait(livePortrait)
.build();
var config = ScannerConfig.withScenario(Scenario.FULL_PROCESS);
config.extPortrait = externalPortrait;
config.livePortrait = livePortrait;
var config = new ScannerConfig()
config.scenario = Enum.ScenarioIdentifier.SCENARIO_FULL_PROCESS
config.extPortrait = externalPortraitBase64
config.livePortrait = livePortraitBase64
var config = new ScannerConfig()
config.scenario = Enum.ScenarioIdentifier.SCENARIO_FULL_PROCESS
config.extPortrait = externalPortraitBase64
config.livePortrait = livePortraitBase64
var config = new ScannerConfig()
config.scenario = Enum.ScenarioIdentifier.SCENARIO_FULL_PROCESS
config.extPortrait = externalPortraitBase64
config.livePortrait = livePortraitBase64
// Android
ScannerConfig config = new ScannerConfig.Builder(Scenario.SCENARIO_FULL_PROCESS)
.SetExtPortrait(externalPortrait)
.SetLivePortrait(livePortrait)
.Build();
// iOS
RGLScannerConfig config = new(Constants.RGL_SCENARIO_FULL_PROCESS);
config.ExtPortrait = externalPortrait;
config.LivePortrait = livePortrait;
In the examples above both livePortrait
and extPortrait
processing parameters are set, but you can use either one or both of them.
Then you can pick the image from Gallery or Files, and process it.
Configure Parameters
└── FaceApiParams
| └── url
| └── mode
| └── search
| | └── limit
| | └── threshold
| | └── groupIds
| └── threshold
| └── serviceTimeout
| └── proxy
| └── proxyUserPwd
| └── proxyType
Parameter | Default | Description |
---|---|---|
url | https://faceapi.regulaforensics.com | The URL of the Regula Face SDK service instance to be used. Note that the default https://faceapi.regulaforensics.com can be used for demo purposes only. For production use, you should purchase an appropriate license. Please contact us here. |
mode | match | The processing mode: "match" or "match+search". match is a comparison of persons that are passed in the request, works by default. match+search performs both matching and searching by image. If only one person is available, match is not performed and only the search is carried out. If no search parameters are specified, the search is conducted over the entire database with the default parameters. Learn more in OpenAPI documentation |
search | not set | A search filter that can be applied if the "match+search" mode is enabled. May include limit, threshold, group_ids. If the group_ids are specified, the search is performed only in these groups. Find more information in the OpenAPI documentation. |
threshold | 75 | The similarity threshold, 0-100. Above 75 means that the faces' similarity is verified, below 75 is not. |
serviceTimeout | 3000 | The service request timeout, ms. |
proxy | not set | Proxy to use, should be set according to the cURL standard. |
proxyUserPwd | not set | Username and password to use for proxy authentication, should be set according to the cURL standard. |
proxyType | not set | Proxy protocol type, should be set according to the cURL standard. |
To add the Face API integration, invoke:
let faceApiParams = FaceAPIParams()
faceApiParams.url = "url"
faceApiParams.mode = "match"
faceApiParams.threshold = 90
faceApiParams.proxy = "proxy"
faceApiParams.proxyPassword = "user_pwd"
faceApiParams.proxyType = 1
let faceApiSearchParams = RGLFaceAPISearchParams()
faceApiSearchParams.limit = 100
faceApiSearchParams.threshold = 0.9
faceApiSearchParams.groupIDs = [1, 2, 3]
faceApiParams.searchParams = faceApiSearchParams
DocReader.shared.processParams.useFaceApi = true
DocReader.shared.processParams.faceApiParams = faceApiParams
RGLFaceAPIParams *faceApiParams = [[RGLFaceAPIParams alloc] init];
faceApiParams.url = @"url";
faceApiParams.mode = @"match";
faceApiParams.threshold = @90;
faceApiParams.proxy = @"proxy";
faceApiParams.proxyPassword = @"user_pwd";
faceApiParams.proxyType = @1;
RGLFaceAPISearchParams *faceApiSearchParams = [[RGLFaceAPISearchParams alloc] init];
faceApiSearchParams.limit = @100;
faceApiSearchParams.threshold = @0.9f;
faceApiSearchParams.groupIDs = @[@1, @2, @3];
faceApiParams.searchParams = faceApiSearchParams;
RGLDocReader.shared.processParams.useFaceApi = @YES;
RGLDocReader.shared.processParams.faceApiParams = faceApiParams;
val faceApiParams = FaceApiParams()
faceApiParams.url = "url"
faceApiParams.mode = "mode"
faceApiParams.serviceTimeout = 4000
faceApiParams.threshold = 90
faceApiParams.proxy = "proxy"
faceApiParams.proxyUserPwd = "user_pwd"
faceApiParams.proxyType = 1
val search = FaceApiParams.Search()
search.limit = 100
search.threshold = 0.9f
search.groupIds = intArrayOf(1, 2, 3)
faceApiParams.search = search
DocumentReader.Instance().processParams().faceApiParams = faceApiParams
FaceApiParams faceApiParams = new FaceApiParams();
faceApiParams.setUrl("url");
faceApiParams.setMode("mode");
faceApiParams.setServiceTimeout(4000);
faceApiParams.setThreshold(90);
faceApiParams.setProxy("proxy");
faceApiParams.setProxyUserPwd("user_pwd");
faceApiParams.setProxyType(1);
FaceApiParams.Search search = new FaceApiParams.Search();
search.setLimit(100);
search.setThreshold(0.9f);
search.setGroupIds(new int[]{1, 2, 3});
faceApiParams.setSearch(search);
DocumentReader.Instance().processParams().faceApiParams = faceApiParams;
var faceApiParams = FaceApiParams(
url: "https://faceapi.regulaforensics.com/",
mode: "match+search",
serviceTimeout: 2000,
threshold: 90,
proxy: "https://example.com/",
proxyPassword: "Regula%20user:StrongPassword",
proxyType: 2,
searchParams: FaceApiSearchParams(
limit: 100,
threshold: 0.9,
groupIds: [1, 2, 3],
));
DocumentReader.instance.processParams.useFaceApi = true;
DocumentReader.instance.processParams.faceApiParams = faceApiParams;
var faceApiParams = new FaceApiParams()
faceApiParams.url = "https://faceapi.regulaforensics.com/"
faceApiParams.mode = "match+search"
faceApiParams.serviceTimeout = 2000
faceApiParams.threshold = 90
faceApiParams.proxy = "https://example.com/"
faceApiParams.proxyPassword = "Regula%20user:StrongPassword"
faceApiParams.proxyType = 2
var search = new Search()
search.limit = 100
search.threshold = 0.9
search.groupIds = [1, 2, 3]
faceApiParams.searchParams = search
DocumentReader.setProcessParams({
useFaceApi: true,
faceApiParams: faceApiParams,
}, _ => { }, _ => { })
var faceApiParams = new FaceApiParams()
faceApiParams.url = "https://faceapi.regulaforensics.com/"
faceApiParams.mode = "match+search"
faceApiParams.serviceTimeout = 2000
faceApiParams.threshold = 90
faceApiParams.proxy = "https://example.com/"
faceApiParams.proxyPassword = "Regula%20user:StrongPassword"
faceApiParams.proxyType = 2
var search = new Search()
search.limit = 100
search.threshold = 0.9
search.groupIds = [1, 2, 3]
faceApiParams.searchParams = search
DocumentReader.setProcessParams({
useFaceApi: true,
faceApiParams: faceApiParams,
})
var faceApiParams = new FaceApiParams()
faceApiParams.url = "https://faceapi.regulaforensics.com/"
faceApiParams.mode = "match+search"
faceApiParams.serviceTimeout = 2000
faceApiParams.threshold = 90
faceApiParams.proxy = "https://example.com/"
faceApiParams.proxyPassword = "Regula%20user:StrongPassword"
faceApiParams.proxyType = 2
var search = new Search()
search.limit = 100
search.threshold = 0.9
search.groupIds = [1, 2, 3]
faceApiParams.searchParams = search
DocumentReader.setProcessParams({
useFaceApi: true,
faceApiParams: faceApiParams,
}, function (s) { }, function (e) { })
// Android
FaceApiParams faceApiParams = new()
{
Url = "url",
Mode = "mode",
ServiceTimeout = 4000,
Threshold = 90,
Proxy = "proxy",
ProxyUserPwd = "user_pwd",
ProxyType = (Java.Lang.Integer)1
};
FaceApiParams.Search search = new()
{
Limit = 100,
Threshold = 0.9f
};
search.SetGroupIds(new int[] { 1, 2, 3 });
faceApiParams.SetSearch(search);
DocumentReader.Instance().ProcessParams().UseFaceApi = (Java.Lang.Boolean)true;
DocumentReader.Instance().ProcessParams().FaceApiParams = faceApiParams;
// iOS
RGLFaceAPIParams faceApiParams = new()
{
Url = "url",
Mode = "match",
Threshold = 90,
Proxy = "proxy",
ProxyPassword = "user_pwd",
ProxyType = 1
};
RGLFaceAPISearchParams faceApiSearchParams = new()
{
Limit = 100,
Threshold = 0.9f,
GroupIDs = new NSNumber[] { 1, 2, 3 }
};
faceApiParams.SearchParams = faceApiSearchParams;
RGLDocReader.Shared.ProcessParams.UseFaceApi = true;
RGLDocReader.Shared.ProcessParams.FaceApiParams = faceApiParams;
Then start the document processing.