14.07.2020 г.
Here we place General instructions on how to use Smart IDReader SDK in your applications. If you feel any trouble with it please feel free to send requests or any other questions about the SDK integration process on support@smartengines.com.
To resolve issue that you might be facing we recommend to do the following:
But remember:
support@beta.smartengines.com
(or product manager’s email).RecognitionEngine
instance:se::smartid::RecognitionEngine engine(configuration_bundle_path);
Configuration process might take a while but it only needs to be performed once during the program lifetime. Configured RecognitionEngine
is used to spawn lightweight Recognition Sessions which have actual recognition methods.
See more about configuration bundles in Configuration Bundles.
SessionSettings
from configured RecognitionEngine
:std::unique_ptr settings(engine.CreateSessionSettings());
Note, that RecognitionEngine::CreateSessionSettings()
is a factory method and returns an allocated pointer. You are responsible for deleting it.
settings->AddEnabledDocumentTypes("mrz.*");
See more about document types in Specifying document types for Recognition Session.
settings->SetOption("common.sessionTimeout", "5");
See more about options in Session Options.
class ConcreteResultReporter : public se::smartid::ResultReporterInterface { /* callbacks */ }
ConcreteResultReporter optional_reporter;
See more about result reporter callbacks in Result Reporter Callbacks.
unique_ptr session(engine.SpawnSession(*settings, &optional_reporter));
ProcessSnapshot(...)
, ProcessImageFile(...)
or similar methods:se::smartid::RecognitionResult result = session->ProcessImageFile(image_path);
When performing recognition in video stream you might want to process frames coming from the stream until result.IsTerminal()
is true
.
RecognitionResult
fields to extract recognized information:for (const std::string &field_name : result.GetStringFieldNames()) {
const se::smartid::StringField &string_field = result.GetStringField(field_name);
bool is_accepted = string_field.IsAccepted();
std::string field_value = string_field.GetUtf8Value();
}
Apart from string fields there also are image fields:
for (const std::string &field_name : result.GetImageFieldNames()) {
const se::smartid::ImageField &image_field = result.GetImageField(field_name);
const se::smartid::Image &image = image_field.GetValue();
}
You can either include all-in-one header file or only required ones:
#include <smartIdEngine/smartid_engine.h> // all-in-one
#include <smartIdEngine/smartid_common.h> // common classes
#include <smartIdEngine/smartid_result.h> // result classes
Smart IDReader C++ SDK code is located within se::smartid
namespace.
All classes and functions have useful Doxygen comments.
Other out-of-code documentation is available at doc
folder of your delivery.
For complete compilable and runnable sample usage code and build scripts please see samples
folder.
Our C++ API may throw std::exception
subclasses when user passes invalid input, makes bad state calls or if something else goes wrong. Most exceptions contain useful human-readable information. Please read e.what()
message if exception is thrown.
Several Smart IDReader SDK classes have factory methods which return pointers to heap-allocated objects. Caller is responsible for deleting such objects (a caller is probably the one who is reading this right now).
We recommend using std::unique_ptr
for simple memory management and avoiding memory leaks.
We return const references in getters wherever possible, it’s better to assign them to const references as well to avoid undesirable copying. If there is only getter without setter for some variable then most probably we did this by purpose because configuration is done somewhere else internally.
Every delivery contains one or several configuration bundles – archives containing everything needed for Smart IDReader Recognition Engine to be created and configured.
Usually they are named as bundle_something.zip
and located inside data-zip
folder.
Assuming you already created recognition engine and session settings like this:
// create recognition engine with configuration bundle path
se::smartid::RecognitionEngine engine(configuration_bundle_path);
// create session settings with se::smartid::RecognitionEngine factory method
std::unique_ptr settings(engine.CreateSessionSettings());
In order to call engine.SpawnSession(settings, optional_reporter)
you need to specify enabled document types for session to be spawned using se::smartid::SessionSettings
methods.
By default, all document types are disabled.
A document type is simply a string encoding real world document type you want to recognize, for example, rus.passport.national
or mrz.mrp
. Document types that Smart IDReader SDK delivered to you can potentially recognize can be obtaining using GetSupportedDocumentTypes()
method:
const vector<vector > &supported_document_types = settings->GetSupportedDocumentTypes();
This vector is two-dimensional because of the restrictions of current Smart IDReader SDK version: you can only enable document types that belong to the same vector
of supported document types for a single session.
Since all documents in settings are disabled by default you need to enable some of them.
In order to do so you may use AddEnabledDocumentTypes(string)
and SetEnabledDocumentTypes(vector)
(removes all and adds each string of the vector) methods of SessionSettings
:
// settings->AddEnabledDocumentTypes("*");
settings->AddEnabledDocumentTypes("mrz.*");
// settings->AddEnabledDocumentTypes("card.*");
// settings->AddEnabledDocumentTypes("idmrz.*");
// settings->AddEnabledDocumentTypes("rus.passport.national");
// settings->AddEnabledDocumentTypes("rus.snils.*");
// settings->AddEnabledDocumentTypes("rus.sts.*");
// settings->AddEnabledDocumentTypes("rus.drvlic.*");
You may also use RemoveEnabledDocumentTypes(string)
method to remove already enabled document types.
For convenience it’s possible to use wildcards (using asterisk symbol) while enabling or disabling document types. When using document types related methods, each passed document type is matched against all supported document types. All matches in supported document types are added to the enabled document types list. For example, document type rus.passport.internal
can be matched with rus.*
, *passport*
and of course a single asterisk *
.
In order to get actual enabled document types list after wildcard expression matching you can use:
const std::vector &enabled_doctypes = settings->GetEnabledDocumentTypes();
As it was mentioned earlier, you can only enable document types that belong to the same vector
of supported document types for a single session.
If you do otherwise then informative exception will be thrown on engine.SpawnSession(...)
call.
It’s always better to enable the minimum number of document types as possible if you know exactly what are you going to recognize because the system will spend less time deciding which document type out of all enabled ones has been presented to it.
Based on the list of supported document types in the configuration bundle, and on the document masks provided by the caller, the engine is determining which internal engine to use in the created session. However, what if there have to be multiple engines which support a certain document type? For example, a USA Passport (usa.passport.*
) can be recognized both in the internal engine for recognition of all USA documents, and in the internal engine for recognition of all international passports. To sort this out there is a concept of session modes.
To get the list of available session modes in the provided configuration bundle, you can use the corresponding method of the SessionSettings
:
const std::vector &available_modes = settings->GetAvailableModes();
There is always a mode called default
and it is enabled, well, by default. There are methods for getting the currently enabled mode and to set a new one:
const std::string ¤t_mode = settings->GetCurrentMode();
// Setting a current mode to AnyPassport
settings->SetCurrentMode("anypassport");
// Setting a document type mask _within a mode_
settings->AddEnabledDocumentTypes("*");
Within any given configuration bundle there is a strict invariant: there cannot be internal engines which belong to the same mode and for which the subsets of supported documents types intersect.
Some configuration bundle options can be overriden in runtime using se::smartid::SessionSettings
methods. You can obtain all option names and their values using:
const std::map<std::string, std::string> &options = settings->GetOptions();
You can change option values using settings->SetOption(...)
method:
settings->SetOption("passport.extractTemplateImages", "true");
settings->SetOption("passport.extractRawFields", "true");
Option values are always std::string
so if you want to pass an integer or boolean it should be converted to string first. It’s done like that to avoid unwanted complexity with ‘variant’ classes and so on.
There is a special subset of options which have names in form common.
which are general session options, for example:
settings->SetOption("common.sessionTimeout", "5.0"); // timeout in seconds
Also, you can make any engine-specific option a common option by simply setting its prefix to common
:
settings->SetOption("common.extractTemplateImages", "true");
settings->SetOption("common.extractRawFields", "true");
This way it will affect all internal engines present in the configuration bundle.
Option name | Value type | Default | Description |
---|---|---|---|
common.allowedTypes | String mask, separated with ‘|’ | DEFAULT | List of allowed barcode symbologies. Valid values: CODABAR , CODE_39 , CODE_93 , CODE_128 , EAN_8 , EAN_13 , ITF , UPC_A , UPC_E , AZTEC , PDF_417 , QR_CODE , DATA_MATRIX . By default all these symbologies are enabled. |
common.enableMultiThreading | "true" or "false" | true | Enables parallel execution of internal algorithms |
common.extractRawFields | "true" or "false" | false | Enables output of raw physical field recognition results (without integration or postprocessing) in the RecognitionResult |
common.extractTemplateImages | "true" or "false" | false | Extracts rectified template images (document pages) in the ImageFields section of the RecognitionResult |
common.rgbPixelFormat | String of characters R, G, B, and A | RGB for 3-channel images, BGRA for 4-channel images | Sequence of color channels for session.ProcessSnapshot() method image interpretation |
common.sessionTimeout | Double value | 0.0 for server bundles, 5.0 for mobile bundles | Session timeout in seconds |
common.useMrzControlDigitPostprocessing | "true" or "false" | false | Assumes valid MRZ checksums and uses this assumption for statistical language model postprocessing |
common.extractImageFieldsInSourceResolution | "true" or "false" | false | Extracts ImageFields (such as photo or signature) in the resolution closest to the input image. If disabled, the resolution correposponds to the default internal template dimensions. |
common.enableStoppers | "true" or "false" | true | Enables smart text fields stoppers |
common.useLuhnCodeCheck | "true" or "false" | true | Enables Luhn code validity assumption in bank card number statistical post-processing |
common.maxImageSize | WIDTHxHEIGHT | 15000x15000 | Maximal size of input image in pixels (checked if the image is passed as a file) |
common.anyPassportMrzRequired | "true" or "false" | false | Enabled “light” mode of the AnyPassport module, with a hard restriction that MRZ is required |
Smart IDReader SDK supports optional callbacks during document analysis and recognition process before the ProcessSnapshot(...)
or similar functions are finished.
It allows the user to be more informed about the underlying recognition process and also helps creating more interactive GUI.
To support callbacks you need to subclass ResultReporterInterface
class and implement desirable callback methods:
class ConcreteResultReporter : public se::smartid::ResultReporterInterface {
public:
virtual void SnapshotRejected() override { }
virtual void DocumentMatched(vector &match_results) override { }
virtual void DocumentSegmented(const vector &segmentation_results) override { }
virtual void SnapshotProcessed(const RecognitionResult &recog_result) override { }
virtual void SessionEnded() override { }
};
Methods DocumentMatched(...)
and DocumentSegmented(...)
are especially useful for displaying document zones and fields bounds in GUI during live video stream recognition.
We recommend using override
keyword for C++11 because it greatly helps to avoid typos in function signatures.
You also need to create an instance of ConcreteResultReporter
somewhere in the code and pass it when you spawn the session:
ConcreteResultReporter reporter;
unique_ptr session(engine.SpawnSession(*settings, &reporter));
Important! Your ResultReporterInterface
subclass instance must not be deleted while RecognitionSession
is alive. We recommend to place them in the same scope.
Smart IDReader SDK has Java API which is automatically generated from C++ interface by SWIG tool.
Java interface is the same as C++ except minor differences (e.g. STL containers wrappers), please see Java sample.
There are several drawbacks related to Java memory management that you need to consider.
Even though garbage collection is present and works, it’s strongly advised to manually call obj.delete()
functions for our API objects because they are wrappers to the heap-allocated memory and their heap size is unknown to the garbage collector.
RecognitionEngine engine = new RecognitionEngine(config_path); // or any other object
// ...
engine.delete(); // forces and immediately guarantees wrapped C++ object deallocation
This is important because from garbage collector’s point of view these objects occupy several bytes of Java memory while their actual heap-allocated size may be up to several dozens of megabytes. GC doesn’t know that and decides to keep them in memory – several bytes won’t hurt, right?
You don’t want such objects to remain in your memory when they are no longer needed so call obj.delete()
manually.
When using optional callbacks by subclassing ResultReportingInterface
please make sure that its instance have the same scope as RecognitionSession
. The reason for this is that our API does not own the pointer to the reporter instance which cause premature garbage collection resulting in crash:
// BAD: may cause premature garbage collection of reporter instance
class MyDocumentRecognizer {
private RecognitionEngine engine;
private RecognitionSession session;
private void InitializeSmartIdReader() {
// ...
session = engine.SpawnSession(settings, new MyResultReporter());
// reporter might be garbage collected there because session doesn't own it
}
}
// GOOD: reporter have at least the scope of recognition session
class MyDocumentRecognizer {
private RecognitionEngine engine;
private RecognitionSession session;
private MyResultReporter reporter; // reporter has session's scope
private void InitializeSmartIdReader() {
// ...
reporter = new MyResultReporter();
session = engine.SpawnSession(settings, reporter);
}
}
Smart IDReader SDK supports recognition a large number of document types, and the goal is to extract all document fields in a convenient manner. A significant issue when dealing with different ID document is that different countries issue documents with very different sets of fields. While we try to match the names of the fields as closely as possible to what is written on the document itself, in order for our clients to build use cases with a variety of recognized document types, we are implementing a fields naming convention.
This convention only relates to common fields which occur on multiple documents worldwide. To extract full list of fields per document type, please use the corresponding SDK interface methods.
Field name | Description | Comment |
---|---|---|
name | Personal name in a local language. If the name field is not separated on components (such as last name and first name), this field is used for the whole name. If it is separated, this field contains everything except the last name. For documents with Slavic naming customs the patronymic is not included in this field. For documents where name is written only in English this field is a duplicate of name_eng | Present on any document with a holder’s name |
name_eng | Personal name in English. Duplicated (for document where name is written in multiple languages), or the main name for documents where name is written only in English. If the name field is not separated on components, this field is used, otherwise it contains everything except last name. For documents with Slavic naming customs the patronymic is not included. | Present on any document with a holder’s name written in Latin script |
last_name | Last name in a local language. For documents where the name is written only in English this name is a duplicate of last_name_eng . | Present if document contains a separated last name field. |
last_name_eng | Last name in English. Duplicated (for documents where name is written in multiple languages), or the main last name for documents where last name is written only in English. | Present if document contains a last name written in Latin script |
patronymic | Patronymic in a local language. For documents where the names are written only in English this fields is a duplicate of patronymic_eng . | Present if document contains a patronymic |
patronymic_eng | Patronymic in English. Duplicated (for documents where patronymic is written in multiple languages), or the main patronymic for documents where the patronymic is only written in English. | Present if document contains a patronymic written in Latin script |
birth_date | Birth date in DD.MM.YYYY format | |
expiry_date | Document expiry date in DD.MM.YYYY format | |
issue_date | Document issue date in DD.MM.YYYY format | |
address | Residence address in a local language, combined in a single field. For documents where address is only written in English the field is a duplicate of address_eng | Present if document has a residence address |
address_eng | Residence address in English, combined in a single field. | Present if document has a separate residence address written in Latin script |
authority | Document issuing authority in a local language | |
authority_eng | Document issuing authority in English | Duplicate of authority if it is only written in English. |
issue_place | Issuing authority address in a local language | |
issue_place_eng | Issuing authority address in English | Duplicate of issue_place if it is only written in English |
birth_place | Document holder’s birth place in a local language, combined in a single field | |
birth_place_eng | Document holder’s birth place in English | Duplicate of birth_place if it is only written in English |
gender | Document holder’s gender as a single character M or F | |
nationality | Document holder’s nationality in a local language | |
nationality_eng | Document holder’s nationality in English | Duplicate of nationality if it is only written in English |
ethnicity | Document holder’s ethnicity in a local language | |
ethnicity_eng | Document holder’s ethnicity in English | Duplicate of ethnicity if it is only written in English |
number | Document number formatted to include a minimal number of required separators | Present on all documents with a document number, even if this field is a duplicate of some other fields |
number_back | Document number formatted to include a minimal number of required separators | Present on all documents with a document number written on a back side of the document which is semantically equal to the document number written on the front side |
id_number | Personal number formatted to include a minimal number of required separators | Present on all documents which has a personal number even if this fields is a duplicate of some other field. If the personal number is the only number in the document, it will be named number |
access_number | RFID access number for biometric ID documents | |
categories | Vehicle categories allowed to be utilized by a driving licence holder | |
issue_date_category_* | Driving licence issue date for a specific vehicle category, in format DD.MM.YYYY | |
expiry_date_category_* | Driving licence expiry date for a specific vehicle category, in format DD.MM.YYYY | |
restrictions_category_* | Driving licence restrictions for a specific vehicle category | |
lic_number | Unique driving licence card number assigned by an issuing authority | |
height | Document holder’s height. Metric format: DDD (in centimeters), imperial format: D'-DD'' | |
weight | Document holder’s weight. Metric format: DD or DDD (in kilograms), imperial format: WW lb or WWW lb | |
eyes | Eyes color in a local language. Duplicate of eyes_eng for documents where it is only written in English. | Present if document has an eyes color information |
eyes_eng | Eyes color in English. | Present if document has an English version of eyes color written separately |
hair | Hair color in a local language. Duplicate of hair_eng for documents where it is only written in English. | Present if document has a hair color information |
hair_eng | Hair color in English. | Present if document has an English version of hair color written separately |
endorsements | Specific driving licence endorsements | |
restrictions | Specific driving licence restrictions | |
blood_type | Blood type | |
full_mrz | Full MRZ encoded in a single field | |
mrz_* | Duplicate field extracted from MRZ, the suffix * corresponds to a field name from VIZ | |
photo | Image field of a personal photograph | |
signature | Image field of a personal signature |
Smart IDReader SDK has C API for use cases where C++ is not possible. Please see C sample for details.
Since there are no constructors and destructors in C we use Create/Destroy pairs of functions which are used to allocate and deallocate objects.
C does not have exceptions so every function returns int
which must be 0
when function call was successful. Also, there is CSmartIdErrorMessage *
passed to every function with error buffer containing propagated exception message if any exception has been thrown.
SmartIDReader SDK has PHP API (supports PHP version 5.5, 5.6 and 7). Methods Image::CopyToBuffer and Image::CopyBase64toBuffer was switched off due to memory issues, please use Image::GetBase64String instead. All other functionality is similar to C++ or Java, Please see PHP sample for details and README.txt in PHP sample directory for module build guide.
phpSmartIdEngine module enables with two steps:
phpSmartIdEngine.php
require("phpSmartIdEngine.php"); //in your php file
enable_dl = On
‘extension_dir = ‘ ‘extension = phpSmartIdEngine.so’ in PHP configuration or you should modify your main php.ini to set this options enabled.Smart IDReader SDK has Python API (supports Python 2.7+ and Python 3+) which is similar to APIs for other languages. Please see Python sample for details and README.txt in Python sample directory for module build guide.
Make sure you have the module file pySmartIdEngine.py
and dynamic library _pySmartIdEngine.so
available in your environment, for example like this:
sys.path.append(sys.path[0]+'/../../bindings/python/')
sys.path.append(sys.path[0]+'/../../bin/')
Hints: You should use byte-like objects (e.g. bytearrays) to call Image::CopyToBuffer and Image::CopyBase64ToBuffer methods (see Python sample for details)
Smart IDReader SDK can be used for barcode recognition.
// create engine
RecognitionEngine engine = new RecognitionEngine(bundle_data);
// create settings for the engine
SessionSettings settings = engine.CreateSessionSettings();
settings.SetOption("common.sessionTimeout", "10.0");
settings.SetOption("common.allowedTypes", "AZTEC|QR_CODE");
settings.AddEnabledDocumentTypes("barcode");
// spawn recognition session
RecognitionSession session = engine.SpawnSession(settings);
// recognize a provided snapshot
RecognitionResult result = session.ProcessYUVSnapshot(data, size.width, size.height);
// create controller
let smartIDController : SmartIDViewControllerSwift = {
let smartIDController = SmartIDViewControllerSwift()
smartIDController.captureButtonDelegate = smartIDController
// set a timeout in seconds
smartIDController.sessionTimeout = 5.0
// configure optional visualization properties (they are disabled by default)
smartIDController.displayZonesQuadrangles = true
smartIDController.displayProcessingFeedback = true
return smartIDController
}()
// setup document type
smartIDController.removeEnabledDocTypesMask("*")
smartIDController.addEnabledDocTypesMask("barcode")
// setup session options
smartIDController.sessionOption(withOptionName: "common.allowedTypes", andWithOptionValue: "QR_CODE|AZTEC")
Other blog posts
06.03.202303.03.2023Smart Code Engine: Revolution debit and credit card scanning technology
11.11.2022Stolen passport photos, fraudsters and facial fusion technology pose a threat to national security
All posts »
Green AI-powered scanner SDK of ID cards, passports, driver’s licenses, residence permits, visas, and other ids, more than 1856+ types in total. Provides eco-friendly, fast and precise scanning SDK for a smartphone, web, desktop or server, works fully autonomously. Extracts data from photos and scans, as well as in the video stream from a smartphone or web camera, is robust to capturing conditions. No data transfer — ID scanning is performed on-device and on-premise.
Automatic scanning of machine-readable zones (MRZ); all types of credit cards: embossed, indent-printed, and flat-printed; barcodes: PDF417, QR code, AZTEC, DataMatrix, and others on the fly by a smartphone’s camera. Provides high-quality MRZ, barcode, and credit card scanning in mobile applications on-device regardless of lighting conditions. Supports card scanning of 21 payment systems.
Automatic data extraction from business and legal documents: KYC/AML questionnaires, applications, tests, etc, administrative papers (accounting documents, corporate reports, business forms, and government forms — financial statements, insurance policies, etc). High-quality Green AI-powered OCR on scans and photographs taken in real conditions. Total security: only on-premise installation. Automatically scans document data in 2 seconds on a modern smartphone.
Green AI for Tomographic reconstruction and visualization. Algorithmization of the image reconstruction process directly during the X-ray tomographic scanning process. We aspire to reduce the radiation dose received during the exposure by finding the optimal termination point of scanning.
Send Request
Please fill out the form to get more information about the products,
pricing and trial SDK for Android, iOS, Linux, Windows.