Observation Topology

Because observations received in observationHandler of FUITextRecognitionViewController are not ordered and finding relevant observations can become tedious, SAPMLTextObservationTopology provides APIs for finding adjacent observations, making it easy to filter observations.

First of all, let us understand the concept of rows, columns, and blocks in a scanned image.

Rows, Columns, and Blocks

For illustration, a sample business card will be used.

***Sample Business Card***

Topology Example Image

SAPMLTextObservationTopology provides a grid-like topology of the observations that can be traversed easily to find relevant observations. The SAPMLTextObservationTopology instance can be created inside the observation handler using the following code:

recognitionView.observationHandler = { [weak self] observations in

    let topology = SAPMLTextObservationTopology(observations)

    return true
}

This topology instance has three key properties - rows, columns, and blocks. Each represents the observations in an ordered way. Listed below is the topology created for the sample business card.

***Topology of Sample Business Card***

Topology Example Image Values

Finding a Relevant Observation

In the business card, finding the Job Title in the second row becomes easy using the rows property of SAPMLTextObservationTopology.

recognitionView.observationHandler = { [weak self] observations in
    //creating topology of observations
    let topology = SAPMLTextObservationTopology(observations)

    //Second row contains the Job Title
    if (topology.rows.count >= 2)
    {
        let jobTitleObservation = topology.rows[1]
        recognitionView.showTexts(for: [jobTitleObservation], with: nil)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) {
            self.textField.text = (jobTitleObservation.value)
            self.dismiss(animated: true)
        }
        return true
    }
    return false
}

Accessing Adjacent Observations

previousObservationInLine, nextObservationInLine, previousObservationInColumn, and nextObservationInColumn methods of SAPMLTextObservationTopology help to find adjacent observations of a given SAPMLTextObservation.

For example, to fetch the state and ZIP code, which is to the left of Email observation in the same line.

   let stateAndZipcodeObservation = topology.previousObservationInLine(emailObservation)
   // stateAndZipcodeObservation is "South Carolina, 29673" with comma as the delimiter
   let separatedArray = stateAndZipcodeObservation.componentsSeparatedByString(",")
   let stateObservation = separatedArray[0]
   let zipCodeObservation = separatedArray[1]

Setting Custom blockCreationDistance While Creating a Topology

It is possible to influence the block creation within the topology API. blockCreationDistance indicates how far two observations can be placed and still be considered to be in same block. The default value is 0.01. The larger the value, the more observations that are far away will be considered in same block.

   let topology = SAPMLTextObservationTopology(observations, blockCreationDistance: 0.1)
  • When you receive observations in observationHandler, it can be tedious to filter out observations of interest. This class orders the array of SAPMLTextObservation into a grid topology that makes it easier for users to traverse and search observations in observationHandler. SAPMLTextObservationTopology also helps in finding observations that are nearby for a given SAPMLTextObservation.

    ## Example Initialization and Configuration

     recognitionView.observationHandler = { observations
    
        let topology = SAPMLTextObservationTopology(observations)
    
        // Rows, Columns, and Blocks of these observations can be accessed by relevant instance variables
    
        return true;
     }
    
    

    ## Setting Custom blockCreationDistance While Creating a Topology This parameter in init helps in getting blocks that the user desires. blockCreationDistance indicates how far two observations can be from each other and still be in same block. The default value is 0.01. The larger the value, the more observations that are far away will be considered to be in the same block.

        let topology = SAPMLTextObservationTopology(observations, blockCreationDistance: 0.1)
    

    ## Accessing Adjacent Observations previousObservationInLine, nextObservationInLine, previousObservationInColumn, and nextObservationInColumn methods of SAPMLTextObservationTopology help a user get the adjacent observation of a given SAPMLTextObservation.

    For example, to get the last name observation that is known to be in the same line as the first name observation and last name is to the right of the first name. Do the following to get the last name observation from the first name observation.

        let lastNameObservation = topology.nextObservationInLine(firstNameObservation)
    
    See more

    Declaration

    Swift

    public class SAPMLTextObservationTopology
  • Information about block of text detected and corresponding array of SAPMLTextRowObservation in the block.

    See more

    Declaration

    Swift

    public class SAPMLTextBlockObservation : SAPMLTextObservation
  • Information about row in detected text and corresponding elements in the row.

    See more

    Declaration

    Swift

    public class SAPMLTextRowObservation : SAPMLTextObservation
  • Information about column in detected text and corresponding elements in the column.

    See more

    Declaration

    Swift

    public class SAPMLTextColumnObservation : SAPMLTextObservation