Skip to content

Using Detector recognizer

dino.gustin edited this page Jun 14, 2016 · 2 revisions

Detector recognizer is used to perform a detection of a document and return position of the detected document on the image or video frame.

If you completed Obtaining scanning results guide, you learned that in order to use a specific recognizer, you need to specify Recognizer Settings object in the initialization stage, and collect Recognizer Result object in the success callback.

Here we explain how to use Detector recognizer, it's settings class PPDetectorRecognizerSettings, and result class PPDetectorRecognizerResult to obtain the location of detected object.

Back to "Getting started" guide.

Initializing Detector recognizer

Initializing PPDecodingInfo

To initialize detector we must start with most specific part of it which is PPDecodingInfo. Each PPDecodingInfo represents one part of document which will dewarped and returned to user. It's property CGRect location specifies the rectangular location which will be returned, while property CGFloat dewarpedHeight defines the height of returned dewarped images (in pixels). Below is the sample source code which initializes one entry.

//Location is attributes are expressed as portions of document's total width and height.
//Entry initialized below  returns whole document.
PPDecodingInfo *decodingInfo = [[PPDecodingInfo alloc] initWithLocation:CGRectMake(0.0, 0.0, 1.0, 1.0) dewarpedHeight:700 uniqueId:@"MRTD"];

Initializing PPDocumentSpecification

PPDocumentSpecifation describes a document which is being detected by PPDocumentDetectorSettings. Each specification describes one document type (i.e. A4 paper, ID card, Cheque, etc.). If you need specific parts of documents, PPDocumentSpecifation should also contain NSArray of PPDecodingInfo objects that describe those specific parts. Below is sample code for creating a single PPDocumentSpecification

PPDocumentSpecification *documentSpecification = [[PPDocumentSpecification] newFromPreset:PPDocumentPresetId1Card];
//set desired decoding info
[documentSpecification setDecodingInfo:@[decodingInfo1, decodingInfo2]];

//adjust specification properties to your need

// Sets portrait scale of document
// Portrait scale defines minimum (scale - tolerance) and maximum (scale + tolerance) size of scanned document as a portion of input image.
documentSpecification.portraitScale = PPMakeScale(0.8,0.2);


documentSpecification.xRange = PPMakeRange ()

Initializing PPDetectorSettings

Final step of using Detector Recognizer is initializing one of PPDetectorSettings subclasses: PPDocumentDetectorSettings, PPMrtdDetectorSettings or PPMultiDetectorSettings.

PPDocumentDetectorSettings is used for detecting and decoding various types of documents.

PPMrtdDetectorSettings is used for detecting and decoding MRTD zone on ID's.

PPMultiDetectorSettings is a special detector which is used only where more than one of other detectors are used. It doesn't do anything by itself, it just contains array of other detectors.

Below is a sample code demonstrating initialization of PPDetectorSettings.

// Document detector
PPDocumentDetectorSettings *documentDetectorSettings = [[PPDocumentDetectorSettings alloc] initWithNumStableDetectionsThreshold:1];

// Add created PPDocumentSpecification classes to list of specifications
[documentDetectorSettings setDocumentSpecifications:@[specification]];

// MRTD detector
// Use previously created PPDocumentDecodingInfo as mrtdInfo
PPMrtdDetectorSettings *mrtdDetectorSettings = [[PPMrtdDetectorSettings alloc] initWithDocumentDecodingInfo:mrtdInfo];

// since we need to use both MRTD and Document Detectors, we need to wrap them in Multi detector
PPMultiDetectorSettings *multiDetectorSettings = [[PPMultiDetectorSettings alloc] initWithSettingsArray:@[documentDetectorSettings, mrtdDetectorSettings]];
multiDetectorSettings.allowMultipleResults = YES;

// Wrap it all in PPDetectorRecognizerSettings and add it to scanSettings
PPDetectorRecognizerSettings *detectorRecognizerSettings = [[PPDetectorRecognizerSettings alloc] initWithDetectorSettings:multiDetectorSettings];
[settings.scanSettings addRecognizerSettings:detectorRecognizerSettings];

Retrieving Detector recognizer results

There are 2 types of results to be caught: PPDetectorResult which contains location of detected object on image and PPImageMetadata which contains dewarped image defined in PPDecodingInfo. Below is a sample code demonstrating retrieving detection location.

- (void)scanningViewController:(UIViewController<PPScanningViewController> *)scanningViewController
              didOutputResults:(NSArray *)results {

    for (PPRecognizerResult* result in results) {

        // Check if detector result is outputted
        if ([result isKindOfClass:[PPDetectorRecognizerResult class]]) {
            PPDetectorRecognizerResult *detectorRecognizerResult = (PPDetectorRecognizerResult *)result;
            PPQuadDetectorResult *quadResult = nil;
            
            // PPQuadDetectorResult contains rectangle of located object
            if ([detectorRecognizerResult.detectorResult isKindOfClass:[PPQuadDetectorResult class]]) {
                quadResult = (PPQuadDetectorResult *)detectorRecognizerResult;
            }
            
            // PPMultiDetectorResult can also contain PPQuadDetectorResult
            if ([detectorRecognizerResult.detectorResult isKindOfClass:[PPMultiDetectorResult class]]) {
                PPMultiDetectorResult *multiResult = (PPMultiDetectorResult *)detectorRecognizerResult;
                for (PPDetectorResult *result in multiResult.detectorResults) {
                    if ([detectorRecognizerResult.detectorResult isKindOfClass:[PPQuadDetectorResult class]]) {
                        quadResult = (PPQuadDetectorResult *)detectorRecognizerResult;
                    }
                }
            }
			NSLog(@"%@", [quadResult.detectionLocation toPointsArray]);
        }
    }
}

Below is a sample code demonstrating retrieving dewarped image of detected object decoding info.

- (void)scanningViewController:(UIViewController<PPScanningViewController> *)scanningViewController didOutputMetadata:(PPMetadata *)metadata {

    // Check if metadata obtained is image
    if ([metadata isKindOfClass:[PPImageMetadata class]]) {
        PPImageMetadata *imageMetadata = (PPImageMetadata *)metadata;
        
        // Check if outputted image is specified by desired PPDocumentDecodingInfoEntry
        if ([imageMetadata.name isEqualToString:uniqueDecodingInfoId]) {
            UIImage *image = imageMetadata.image;
            // Do what you like with dewarped image
        }
    }
}
Clone this wiki locally