SPCompare.h File Reference
Detailed Description
SignWare Dynamic Development toolkit, SPCompare object.
- Author:
- uko
Use SPCompareCreate to create SPCompare objects. SPCompare instances save all properties such as match quality or projection factor within the instance object for later usage in the compare functions.
The application will typically select the engines to use (SPCompareSetMode), set compare parameters (SPCompareSetMatchQualityEx) and perform the comparison (SPCompareCompare).
The final result (SPCompareGetResult) is composed from the result of all engines, the final result will be false (no match) if any of the selected engines calculated a match rate less than the minimum match quality for the engine.
The application may query the detailed results of all selected engines (SPCompareGetDetailResult, SPCompareGetNumResults) and implement another match algorithm based on the detail results.
The SPCompare class uses several engines to compare signatures, a dynamic, a static and a statistic engine. The match quality of all engines is normalized in the range 0 ... 100, where 0 means very low match quality, and 100 means high probability that signature and reference were entered by the same person.
Do not assume that there is a linear relation of match quality and signature similarity.
// Example (C) static void GetDetailResult(pSPCOMPARE_T pComp, int iEngine, const char *pszEngine); int Compare(pSPREFERENCE_T pRef, pSPSIGNATURE_T pSig, int iMode) { pSPCOMPARE_T pComp = 0; int rc; int iRes; rc = SPCompareCreate(&pComp); if(rc != SP_NOERR) return rc; if(iMode & SP_COMPARE_DYNAMIC) { pSPSIGNATURE_T aSig = 0; int iNumSigno, iSRSigno, iSRRef, iPressSigno, iPressRef; SPSignatureCreateFromReference(&aSig pRef, 0); SPSignatureGetMaxPress(pSig, &iPressSigno); SPSignatureGetSampleRate(pSig, &iSRSigno); SPSignatureGetMaxPress(aSig, &iPressRef); SPSignatureGetSampleRate(aSig, &iSRRef); SPSignatureFree(&aSig); SPReferenceGetSignatureCount(pRef, &iNumSigno); if(iNumSigno < 2 || !iSRSigno || !iSRRef || iPressSigno <= 2 || iPressRef <= 2) { iMode &= ~SP_COMPARE_DYNAMIC; iMode |= SP_COMPARE_DSTAT; } } SPCompareSetMode(pComp, iMode); rc = SPCompareReference(pComp, pRef, pSig); if(rc != SP_NOERR) { SPCompareFree(&pComp); return rc; } // Get the final result from the compare object rc = SPCompareGetResult(pComp, &iRes); if(rc != SP_NOERR) { SPCompareFree(&pComp); return rc; } // Dump Detailed results GetDetailResult(pComp, SP_COMPARE_DYNAMIC_ENGINE, "Dynamic"); GetDetailResult(pComp, SP_COMPARE_DSTAT_ENGINE, "Statistic"); GetDetailResult(pComp, SP_COMPARE_STATIC_ENGINE, "Static"); SPCompareFree(&pComp); return iRes > 0 ? 1 : 0; } static void GetDetailResult(pSPCOMPARE_T pComp, int iEngine, const char *pszEngine) { char szBuff[2048]; int iNumResults, iBuff; int rc, ik; rc = SPCompareGetNumResults(pComp, iEngine, &iNumResults); if(iNumResults > 0) { iBuff = sprintf(szBuff, "%s Engine:", pszEngine); for(ik = 0; ik < iNumResults; ik++) { int iRes; rc = SPCompareGetDetailResult(pComp, iEngine, ik, &iRes); if(rc == SP_NOERR) { if(iRes < 0) { iBuff += sprintf(szBuff + iBuff, " %d - %s", iRes, SPSignwareGetErrorString(iRes)); } else { iBuff += sprintf(szBuff + iBuff, " %d", iRes); } } else { iBuff += sprintf(szBuff + iBuff, " %s", SPSignwareGetErrorString(rc)); } } fprintf(stdout, szBuff); } }
Performance aspects
Typically a static image will be scanned from e. g. a contract. The contract includes a small field for the signature, typically outlined with a rectangle or a line. The scanned image will thus include the signature plus some unwanted artefacts, noise and dirt, which will definitely have an impact on the compare quality.The application will therefor have to preprocess the scanned image to improve the results of the compare engine:
- scan the image with at least 200 DPI
- crop the image as small as possible without clipping the signature
- clean the image as good as possible, you may use some cleaning methods as provided in SignWare SPImage class e. g. to remove lines and dirt.
Note: the better the cleaning the better the compare results - ideally use the same resolution for both images, the reference and the signature. Resize the image with higher resolution to match the image with lower resolution
- assure that the images pass resolution, some image formats such as png do not include tags to pass the resolution
- assure that the image data follows the engines image requirement, (b/w 1 equals white, gray 255 equals white), else call SPImageInvert(SP_INVERT_AUTO) to invert the image if required
CPU performance may be another important aspect when you have to compare many signatures and references. Please see Static engine performance, the engine for dynamic signature compare does not need any optimization.
If you need to compare many dynamic signatures against many references with the static engine then the application can improve CPU performance by creating all static images (one static image per signature and one static image for all signatures in a reference) and call the compare function once with SP_COMPARE_STATIC for the static signature image and all static signatures within a reference, and another time with SP_COMPARE_DYNAMIC for the dynamic signature and reference.
Creation of the static images and the corrresponding preprocessed static 'description' will thus be called once, while it will else be called for each static compare.
You should turn off the mode flags SP_COMPARE_AUTOZOOM if the signatures are already resized.
If the application needs to classify the match quality according to other factors (such as amount of a transaction) then it is recommended to save the match quality of the compare result and classify the signature match according to the application logic.
Static engine performance
The static engine creates a preprocessed 'description' of the image; the verification uses this 'description' as input. A high percentage of the total verification time is used to create this 'description', you may thus gain performance when reusing the preprocessed image 'description'.Follow these steps to prevent recalculation of the image 'description' and to reuse the preprocessed image 'description':
- save and reuse the instance of the SPImage object
- binarize and clean the SPImage object during initialisation.
Clone and Crop images during initialisation and save the cropped image, if you need to compare against the original and the cropped clone. - Mirror and or invert the image once during initialisation
- Resize all images to a 'normalized' resolution
- Do not turn on SP_COMPARE_MIRROR or SP_COMPARE_AUTOZOOM during a compare function
This also applies when calling static compares on dynamic signatures and references. Create and preprocess (resize if required) the image during initialisation and use these SPImage objects as input for the static compares.
// Example pSPIMAGE_T pSignatures[20]; pSPIMAGE_T pReferences[30]; int batchCompare() { for(int ik = 0; ik < sizeof(pSignatures) / sizeof(pSPIMAGE_T); ik++) { char *pImData = 0; int iImLen = 0; // load the signature into memory.... // readfile(szSignatureName, &pImData, &iImLen); loadImage(pImData, iImLen, &pSignatures[ik]); // do any resizing, cropping and cleaning } for(int ik = 0; ik < sizeof(pReferences) / sizeof(pSPIMAGE_T); ik++) { char *pImData = 0; int iImLen = 0; // load the reference into memory.... // readfile(szReferenceName, &pImData, &iImLen); loadImage(pImData, iImLen, &pReferences[ik]); // do any resizing and cleaning } int iNumMatches = 0; // Match each Signature against each Reference for(int ir = 0; ir < sizeof(pReferences) / sizeof(pSPIMAGE_T); ir++) { for(int is = 0; is < sizeof(pSignatures) / sizeof(pSPIMAGE_T); is++) { if(compare(pReferences[ir], pSignatures[is]) > 0) iNumMatches++; } } printf("Total matches: %d\n", iNumMatches); for(int ik = 0; ik < sizeof(pSignatures) / sizeof(pSPIMAGE_T); ik++) { SPImageFree(&pSignatures[ik]; } for(int ik = 0; ik < sizeof(pReferences) / sizeof(pSPIMAGE_T); ik++) { SPImageFree(&pReferences[ik]; } } // Create a SPImage object, do all preprocessing on the images during initialisation int loadImage(const char *pImData, int iImLen, pSPIMAGE_T *ppImage) { int rc = SPImageCreate(ppImage); if(rc != SP_NOERR) return rc; rc = SPImageSetBitmap(*ppImage, pImData, iImLen); if(rc != SP_NOERR) return rc; SPImageBinarize(*ppImage, 2, 35); SPImageMirror(*ppImage, 2); SPImageInvert(*ppImage, SP_INVERT_AUTO); // any other cleaning should be performed here ... return rc; } // Compare a signature against the reference, set compare mode to SP_COMPARE_STATIC, // The input images are already mirrored and inverted int compare(pSPIMAGE_T pRef, pSPIMAGE_T pSig) { pSPCOMPARE_T pCompare = 0; SPCompareCreate(&pCompare); SPCompareSetMode(pCompare, SP_COMPARE_STATIC); int rc = SPCompareStaticImage(pCompare, pRef, pSig); if(rc != SP_NOERR) { // Error occured ... } else { int iMatchRate = 0; SPCompareGetDetailResult(pCompare, SP_COMPARE_STATIC_ENGINE, 0, &iMatchRate); // May want to do some error checking: if(iMatchRate < 0) { // process errors, e.g. SP_IDENTIC_ERR rc = iMatchRate == SP_IDENTIC_ERR ? 1 : 0; } else { rc = iMatchRate > 80 ? 1 : 0; } } SPCompareFree(&pCompare); return rc; }
Defines | |
#define | SP_COMPARE_AUTO_ENGINE 0x80 |
Flag to use all engines available for the according compare objects. | |
#define | SP_COMPARE_AUTOZOOM 0x20 |
Flag to size the projected signature and reference images for static comparison. | |
#define | SP_COMPARE_DESKEW 4 |
Flag to deskew signatures, references, and templates. | |
#define | SP_COMPARE_DSTAT 0x40 |
Flag to enable dstat (statistic) comparison. | |
#define | SP_COMPARE_DSTAT_ENGINE 1 |
Engine specifyer: use dstat (statistic) engine. | |
#define | SP_COMPARE_DYNAMIC 2 |
Flag to enable dynamic comparison. | |
#define | SP_COMPARE_DYNAMIC_ENGINE 2 |
Engine specifyer: use dynamic (adsv) engine. | |
#define | SP_COMPARE_MIRROR 0x10 |
Flag to compare signatures and references/templates that are written from right to left. | |
#define | SP_COMPARE_NORMALIZE_SAMPLERATE 8 |
Flag to normalize the sample rates of the signatures, references, and templates. | |
#define | SP_COMPARE_STATIC 1 |
Flag to enable static comparison. | |
#define | SP_COMPARE_STATIC_ENGINE 3 |
Engine specifyer: use static (sival) engine. | |
Functions | |
SPINT32 __cdecl | SPCompareCompare (pSPCOMPARE_T pCompare, SPVPTR pReference, SPVPTR pSignature) |
Compare a signature with a reference. | |
SPINT32 __cdecl | SPCompareCreate (pSPCOMPARE_T *ppCompare) |
Create an SPCompare object. | |
SPINT32 __cdecl | SPCompareFree (pSPCOMPARE_T *ppCompare) |
Free an SPCompare object. | |
SPINT32 __cdecl | SPCompareGetDetailResult (pSPCOMPARE_T pCompare, int iEngine, int iIndex, int *piResult) |
Get a detail result of a comparison. | |
SPINT32 __cdecl | SPCompareGetDynamicMatchQuality (pSPCOMPARE_T pCompare, SPINT32 *piMinDynamicQuality) |
Get the minimum match rate for dynamic verification. | |
SPINT32 __cdecl | SPCompareGetDynamicResult (pSPCOMPARE_T pCompare, int *piResult) |
Get the result of a dynamic comparison. | |
SPINT32 __cdecl | SPCompareGetMatchQuality (pSPCOMPARE_T pCompare, SPINT32 *piMinDynamicQuality, SPINT32 *piMinStaticQuality) |
Get the minimum match rate for static and dynamic verification. | |
SPINT32 __cdecl | SPCompareGetMatchQualityEx (pSPCOMPARE_T pCompare, SPINT32 iEngine, SPINT32 *piMinQuality) |
Get the minimum match rate for the specified engine. | |
SPINT32 __cdecl | SPCompareGetMode (pSPCOMPARE_T pCompare, int *piMode) |
Get the compare mode. | |
SPINT32 __cdecl | SPCompareGetNumResults (pSPCOMPARE_T pCompare, int iEngine, int *piNum) |
Get the number of results for the specified engine. | |
SPINT32 __cdecl | SPCompareGetNumStaticResults (pSPCOMPARE_T pCompare, int *piNum) |
Get the number of static results. | |
SPINT32 __cdecl | SPCompareGetResult (pSPCOMPARE_T pCompare, int *piResult) |
Get the final result of a comparison. | |
SPINT32 __cdecl | SPCompareGetStaticMatchQuality (pSPCOMPARE_T pCompare, SPINT32 *piMinStaticQuality) |
Get the minimum match rate for static verification. | |
SPINT32 __cdecl | SPCompareGetStaticResult (pSPCOMPARE_T pCompare, int iIndex, int *piResult) |
Get the result of a static comparison. | |
SPINT32 __cdecl | SPCompareImage (pSPCOMPARE_T pCompare, pSPIMAGE_T pImage, pSPSIGNATURE_T pSignature) |
Compare a signature with an image. | |
SPINT32 __cdecl | SPCompareReference (pSPCOMPARE_T pCompare, pSPREFERENCE_T pReference, pSPSIGNATURE_T pSignature) |
Compare a signature with a reference. | |
SPINT32 __cdecl | SPCompareSetDynamicMatchQuality (pSPCOMPARE_T pCompare, SPINT32 iMinDynamicQuality) |
Set the minimum match rate for dynamic verification. | |
SPINT32 __cdecl | SPCompareSetMatchQuality (pSPCOMPARE_T pCompare, SPINT32 iMinDynamicQuality, SPINT32 iMinStaticQuality) |
Set the minimum match rate for static and dynamic verification. | |
SPINT32 __cdecl | SPCompareSetMatchQualityEx (pSPCOMPARE_T pCompare, SPINT32 iEngine, SPINT32 iMinQuality) |
Set the minimum match rate for a specified engine. | |
SPINT32 __cdecl | SPCompareSetMaximumResolution (pSPCOMPARE_T pCompare, int iMaximumResolution) |
Set the maximum Resolution for signature and reference which are passed to the engines. | |
SPINT32 __cdecl | SPCompareSetMode (pSPCOMPARE_T pCompare, int iMode) |
Set the compare mode. | |
SPINT32 __cdecl | SPCompareSetStaticMatchQuality (pSPCOMPARE_T pCompare, SPINT32 iMinStaticQuality) |
Set the minimum match rate for static verification. | |
SPINT32 __cdecl | SPCompareSetTicket (pSPCOMPARE_T pCompare, pSPTICKET_T pTicket) |
Pass a license ticket for the next compare(s). | |
SPINT32 __cdecl | SPCompareStaticImage (pSPCOMPARE_T pCompare, pSPIMAGE_T pImage, pSPIMAGE_T pSignature) |
Compare an image with an image. | |
SPINT32 __cdecl | SPCompareStaticReference (pSPCOMPARE_T pCompare, pSPREFERENCE_T pReference, pSPIMAGE_T pSignature) |
Compare a reference with an image. | |
SPINT32 __cdecl | SPCompareStaticTemplate (pSPCOMPARE_T pCompare, pSPTEMPLATE_T pTemplate, pSPIMAGE_T pSignature) |
Compare a template with an image. | |
SPINT32 __cdecl | SPCompareTemplate (pSPCOMPARE_T pCompare, pSPTEMPLATE_T pTemplate, pSPSIGNATURE_T pSignature) |
Compare a signature with a template. |
Define Documentation
|
Flag to use all engines available for the according compare objects.
The SPCompare functions will do a at least static comparison with the reference.
|
|
Flag to size the projected signature and reference images for static comparison. The signature and reference will be resized to the lowest resolution value of signaure, reference and MaxResolution.
|
|
Flag to deskew signatures, references, and templates. The SPCompare functions will deskew signatures, references and templates before doing a static comparison. This flag is ignored unless SP_COMPARE_STATIC is also set. Static signature or reference images will not be deskewed.
|
|
Flag to enable dstat (statistic) comparison. The SPCompare functions will do a statistic comparison with the reference.
|
|
Engine specifyer: use dstat (statistic) engine.
|
|
Flag to enable dynamic comparison. The SPCompare functions will do a dynamic comparison with the reference or the template.
|
|
Engine specifyer: use dynamic (adsv) engine.
|
|
Flag to compare signatures and references/templates that are written from right to left. Some languages write from right to left. This flag will optimize the static signature compare engine for signatures that were entered writing from right to left. The SPCompare functions will mirror the signature and the reference/template before doing a static comparison. This flag is ignored unless SP_COMPARE_STATIC is also set.
|
|
Flag to normalize the sample rates of the signatures, references, and templates. The SPCompare functions will normalize the tablet sample rate of the signature and the reference/template before doing a dynamic comparison. This flag is ignored unless SP_COMPARE_DYNAMIC is also set.
|
|
Flag to enable static comparison. The SPCompare functions will do a static comparison of the signature with all signatures of the reference or with the template.
|
|
Engine specifyer: use static (sival) engine.
|
Function Documentation
|
Compare a signature with a reference. This is a convenience function that allows for passing a reference that may be an SPReference, SPTemplate or SPImage object, and a signature that may be an SPSignature or SPImage object. The compare will be delegated to the appropriate specialized function for the passed objects.
|
|
Create an SPCompare object. Initially, the comparison mode of the SPCompare object is set to SP_COMPARE_STATIC | SP_COMPARE_DYNAMIC | SP_COMPARE_DESKEW.
|
|
Free an SPCompare object. The SPCompare object must have been created by SPCompareCreate.
|
|
Get a detail result of a comparison.
|
|
Get the minimum match rate for dynamic verification.
|
|
Get the result of a dynamic comparison. The threshold for a match is typically set at a match rate of 80.
|
|
Get the minimum match rate for static and dynamic verification.
|
|
Get the minimum match rate for the specified engine. The value must be within 0 and 100.
|
|
Get the compare mode.
|
|
Get the number of results for the specified engine.
|
|
Get the number of static results.
|
|
Get the final result of a comparison.
|
|
Get the minimum match rate for static verification.
|
|
Get the result of a static comparison. The threshold for a match is typically set at a match rate of 80. Static comparison is called for each signature of the reference. The result of each comparison is accessible via parameter iIndex. Please pass iIndex = 0 for the first comparison. Templates only contain one signature, resulting in one comparison.
|
|
Compare a signature with an image. This function supports static compares only.
|
|
Compare a signature with a reference.
|
|
Set the minimum match rate for dynamic verification. The default value for the dynamic match rate is 80. The value must be within 0 and 100.
|
|
Set the minimum match rate for static and dynamic verification. Default values for static and dynamic match rates are 80. Values must be within 0 and 100.
|
|
Set the minimum match rate for a specified engine. Values must be within 0 and 100.
|
|
Set the maximum Resolution for signature and reference which are passed to the engines. The default maximum resolution is 300 DPI. This parameter will be ignored if the flag SP_COMPARE_AUTOZOOM is not set If maximum resolution is set to 0 and flag SP_COMPARE_AUTOZOOM is set, then signature and reference will be resized to the lower resolution of signature and reference.
|
|
Set the compare mode. The default compare mode is: SP_COMPARE_DESKEW | SP_COMPARE_AUTOZOOM
|
|
Set the minimum match rate for static verification. The default value for the static match rate is 80. Values must be within 0 and 100.
|
|
Pass a license ticket for the next compare(s). You must pass the ticket before you call one of the compare functions. This function copies the SPTicket object. The ticket must be charged for SP_TICKET_COMPARE_DYNAMIC or SP_TICKET_COMPARE_STATIC.
|
|
Compare an image with an image. This function supports static compares only.
|
|
Compare a reference with an image. This function supports static compares only.
|
|
Compare a template with an image. This function supports static compares only.
|
|
Compare a signature with a template.
|