SmartScan Library (v3.0.2)

SmartScan is a real-time video stream decoder, allowing to scan various type of content.

Depending on the version you ordered, you will be able to use it to decode any combination of the following codes :

  • 1D/2D barcodes (EAN8, EAN13, UPC, Code39, Code128, Datamatrix, databars, QRCodes, Aztec codes, … )

  • Multiple OCR types :

    • OCR-B MRZ used on official papers (Swiss ID Cards, Swiss Passports, Swiss Driving license)
    • Swiss Inpayment Slips
    • Theia License plate (deep trained AI model)
    • Swiss and EU car plates (Deprecated in favor of Theia License plate)
  • Our decoder never stops growing, ask us about what’s new in SmartScan !

Requirements

This project has been tested with iOS 12+ and build with xCode 15. If your project supports lower versions of the iOS framework, SmartID Scan may not work as expected and could show unexpected behaviour in your application.

Integration steps

This project is a demo iOS app to show how to integrate our decoding library in an iOS application. To make it work, just follow the few steps below :

  1. Add the xcframework to your project and the license file icare_smartscan.lic in your project. (The license file should be present in your app release)
  2. Project Settings : a. Disable bitcode in your project settings b. C++ language Dialect should be switched to Compiler Default c. C++ Standard Library should be libc++ (LLVM c++… )

  3. In the linked framwork you want to add libc++.tbd from the system libraries

  4. You can import the module

  5. Add an entry with the key “Privacy - Camera Usage Description” in your -info.plist file to allow your app to access the camera

  6. You can Import the necessay dependcies by module or header

  7. If you’re using qrcode, it’s now needed to use the -all_load in the “other compiler flags” in your project.

    @import SmartIDScanner;
    

    or

    #import <SmartIDScanner/SmartIDScanner.h>
    

Minimal implementation (See the example project for more details)

Interaction with the SmartScan library is done with a SmartScanner object. Instantiate it inside a view controller, when you want to use it :

Start to scan

Objc

//Create the SmartScanner object reference
SmartScanner* sc;

//Init SmartScanner when needed, and set the delegate
sc = [[SmartScanner alloc] init];
sc.scDelegate = self;

//Retrieve the preview screen and display it on your view
UIView* preview = [sc previewViewWithViewSize:self.view.bounds];
[self.view addSubview:preview];

UIView* preview = [sc previewViewWithViewSize:self.view.bounds andAVCaptureSeesionPreset:self.lastStreamQuality];
[self.view insertSubview:preview atIndex:0];
[sc setDecodingType: SmartDecodingTypes  andSubType: SmartDecodingSubtimes];

//Eventually set a custom ROI (This must be done after setting the decoding type)
[sc setRegionOfInterest:CGRectMake(0, 0, 300, 300)] ;

Swift

scan  = SmartScanner()

preview = scan.previewView(withViewSize: self.view.bounds)
scan.scDelegate = self
self.view.insertSubview(preview!, at: 0)

//Set the type of code to decode
scan.setDecodingType(CODE_EU_PLATES.rawValue andSubType:  CODE_PLT_CHE.rawValue)

//Customize your ROI if needed, this need to be done after setting the type of code
let regionOfInterest = CGRect(x: 0.0, y: 0.0, width: 160, height: 160)
scan.setRegionOfInterest(regionOfInterest)



//confguring the orientation.
scan.setDecoding(UIApplication.shared.statusBarOrientation)
//    scan.setDecoding(.landscapeRight)  //For forcing the orientation in one direction



//assuming you have a targetRect to display the user where is the active zone of decoding (ROI)
targetRect.frame = scan.regionOfInterest()

scan.enableDecoding(true)

//Configuring the behavior and number of same successful scan to return a success
scan.setSmartScannerResultBehavior(SmartScannerResultBehaviorContinuous)
scan.enableMultipleResultsConfirmation(3)

Select the type of code you want to decode

You can use a combination of any type or subtype that is enabled in the version you have. At any point you can set another decoding type (Verify the enabled types of your SmartScan version by calling the version function).

Thoses are referenced in the enums

SmartDecodingSubTypes
SmartDecodingTypes 

For example

objc

    #define TypeToDecode    (CODE_OCRB  | CODE_EU_PLATES )
    #define SubTypeToDecode (CODE_PLT_ALL  | CODE_ICAO_9303_PASSPORT | CODE_ICAO_9303_IDCARD | CODE_FRENCH_IDS | CODE_ROMANIAN_IDS | CODE_ROMANIAN_IDS | CODE_ROMANIAN_IDS)
    [sc setDecodingType: TypeToDecode  andSubType: SubTypeToDecode];

swift

//Since there is no defines in swift, you should put the values in a var/let

var typeOfCode : UInt64 = CODE_OCRB.rawValue
var subtypeOfCode : UInt64 = CODE_BVR.rawValue | CODE_ICAO_9303_IDCARD.rawValue

//Configuring what type of content to scan.
scan.setDecodingType(typeOfCode, andSubType: subtypeOfCode)

included in IcareDecodersCodes.h

Retrieve the results by implementing the delegate protocol

objc

- (void)SmartScan:(SmartScanner *)smartScanner foundResult:(SmartScanResult *)smartScannerResult
{
    NSLog(@"result : %@  (%@)", smartScannerResult.content, smartScannerResult.codeDescription);
    NSLog(@"--- With metadata : %@", smartScannerResult.metadata);
}

swift

func smartScan(_ smartScanner: SmartScanner, found smartScannerResult: SmartScanResult) {
    print("Result : \(smartScannerResult.content) type : \(smartScannerResult.codeDescription)")
}

Release the resources when you don’t need to use the smartscanner anymore

objc

[sc closeCameraStream];
sc = nil; 

swift

sc?.closeCameraStream()
sc = nil

Important notes regarding the Quick response codes (QR Codes):

  • QRCodes content is now processed to try to interprate the multiple variation of the spec. (Since QR Code Reader, Version 2.0.0)
    • We try to interpret the qrcode content regarding the specifications. This includes ECI information (to interpret the character encoding) and the FNC1-1 / FNC1-2 informations.
    • It the processing fails (might be due to some unexpected character, or some encoding not supported by the iOS platforme), the warning variable form the SmartScanResult will indicate a potential error, the content will be empty, And you’ll have to use the data (raw output of the qrcode).
  • The raw data will contains some variations.
    • The qr code type is added if missing in the original qrcode. ( ]Q1,]Q2,]Q3,]Q4,]Q5,]Q6 )
    • All backslash that are not part of an ECI are doubled for QRCode type 2, 4 and 6. To allow you to process ECI data if you need to.

Notes regarding theia

  • The license information are no longer embedded into the library, but provided in a separate file. This means the library no longer need to be updated at each license renewal.
  • A new plate reader based on deep learning has been developed. Compared to the legacy reader, the new reader :
    • Is approximately 30% more accurate than the legacy plate reader. Being based on deep learning, it should continue evolving toward more accuracy (no data gathering or learning is done in SmartScan library, all learning is done on our own data and offline).
    • Performs better than in challenging conditions like low visibility, blur, strong shadows.
    • Recognizes and reads more countries. This is the current list of recognized countries : ALA, ALB, AND, AUT, BEL, BGR, BIH, BLR, CHE, CYP, CZE, DEU, DNK, ESP, EST, FIN, FRA, FRO, GBG, GBJ, GBM, GBR, GIB, GEO, GRC, HRV, HUN, ITA, IRL, ISL, LIE, LTU, LUX, LVA, MCO, MDA, MKD, MLT, MNE, NLD, NOR, POL, PRT, RKS, ROU, RUS, SMR, SRB, SVK, SVN, SWE, TUR, UKR.
    • The reader now detects the separators “-” and “.” and always return them.
    • Is more prone to false positives (reading general text as a plate).
    • Uses the GPU for running the models. This may lead to consuming more resources than the legacy reader on some platforms.

(1) The demonstration decoding libraries replace some characters in the result string with the character ‘X’


Migration from Smartscan iOS V 2.x.y

  • Remove your opencv dependencies
  • Add the new xcframework and your license file and your project
  • If you’re using the license plates, you can migrate to theia. Replace the CODE_EU_PLATES with CODE_THEIA_PLATE_READER as reading type, and you can also remove all the CODE_PLT_XYZ in the subtypes. All countries are included by default.
  • Migrate to use the SmartScanResult.metadata to get informations (like the plate country) instead of code SmartScanResult.codeDescription .

Changes

3.0.2

  • Update Theia plate reader (v1.0.0) with new Liechtenstein formatter.

3.0.1

  • Add a -(void)setFlashLevel:(float)aValue function allowing to enable flash to different levels

3.0.0

  • Now includes the opencv dependencies (no more need to add it manually)
  • License changes : now the build are generic and need you to add a license file. (easier to renew, or add / remove features)
  • The build are a little biger (mainly when having Theia included), but the resultat binary should not be after much more than 10-20 Mo
  • Instead of using codeType and subtype, more informations are now returned via the metadata parameters of smartscanresult. Which is a dictionnary. For theia the country will be in there under the “country” key.

2.5.4

  • Added a few presets, to try to take advantage of devices that have a close range camera. (Mostly the pro devices)

2.5.3

  • Changed the default behavior for camera session from AVCaptureDeviceTypeBuiltInDualWideCamera to AVCaptureDeviceTypeBuiltInDualCamera

2.5.2

  • Fixed an issue regarding focus on newer iphones
  • Added the function setFramesToProcess that allows to reduce the number of processed frames

2.5.1

  • Update OpenCV requirements to version 4.5.5

2.5.0

  • The library is know delivered as a xcframework it should work the same as before. You might need to delete the old framework and drag and drop the xcframework instead. We’re now supporting M1 simulator too.
  • We will now ship an appropriate compiled version of OpenCV with the library. (Or you might eventually compile it by yourself by downloading the sources at https://github.com/opencv/opencv and executing there pythonscript opencv/platforms/apple/build_xcframework.py ). It’s also a xcframework. You might need to delete the old one and drag and drop the new on your project.
  • We had a lot of internal changes into our building process. Let us know if you any issues (We haven’t :D )

2.4.2

  • Fix for mac silicon: Will now work on mac’s M1 using the mac embeded camera with an horizontal flip to make it usable.

2.4.1

QRCode :

  • “fixed” some qrcode behavior to fit the common codes. If the encoding is not specified we’re now trying to interpret it as UTF-8 first, and then latin1. (With is contradictory regarding the QR Code specifications, but it seems that a lot of the online generator generate UTF-8 content content by default.)

2.4.0

QRCode :

  • Thanks to some qrbill printer that don’t know how to print the right way, we’ve now added support for qrcode that are mirrored and/or printed with reversed black/white colors

2.3.0

Due to some refactoring to match the last spec of the qrcode there are a few breaking changes :

  • It’s now needed to use the -all_load in the “other linker flags” in your project, if you intend to use qrcodes.
  • The QR code returns have now changed. Please refer to the Important notes regarding the Quick response codes chapter.
  • -(void)SmartScannerFoundResult:( SmartScanner*)smartScan code:(NSString*) aCode ofType:(uint64_t)aType andSubType:(uint64_t)aSubType; have been removed. and you should use -(void)SmartScan:(SmartScanner*) smartScanner foundResult:(SmartScanResult*)smartScannerResult;

2.2.3

  • Added a “data” property to the SmartScanResult object containing the NSData of the content. (It can help when the qrdata or aztek data are pure data)

2.2.2

  • Added a new function in the delegate protocol. Retuning a new SmartScanResult object. This is meant, at long term to replace the previous function.
  • If you’re using the car license plate reader, we have added the CODE_PLT_ASTRA_FMT what will try to keep the dashes in German and Austria plates.

2.2.1

  • Fixed a strange issue on iphone XS related to some strange behavior of the UIImagePicker.

2.2.0

  • Internal refactoring on the cpp part.
  • Updated OpenCV to 4.3.0

2.1.2

  • Added a message in the console, if the current license does not match the build (BundleID or may have expired) Be sure to check the sdk description if it’s happening
  • Fix : torch light mode not disabling

2.1.1

  • Updated internal scanner libs
  • Updated OpenCV to 3.4.8

2.1.0

  • Removed iOS9 support ( And replaced the related deprecated calls)

2.0.9

  • Changed some function names to be more in sync with android SDK
  • Fixed the build of internal component targetting the current SDK instead of the iOS10

2.0.8

  • Switched to Xcode 11 (tell us if you see any issue with it)

2.0.7

  • Updated to openCV 3.4.7
  • Added bundleID referencing as regex

2.0.6

  • Added a new function to set the ROI (region of interest) that is more firendly to use.

    setRegionOfInterestInPreviewViewCoordinates:...
    
  • Changed the documentation engine from appledoc to jazzy

  • Added camera framerate option. (might be usefull for plates (moving vehicules)

2.0.5

  • Updated sample app and documentation (obj-c and swift sample)
  • Updated nullability in smartscan headers. (If you’re using swift you might need to change a few checks)

2.0.4

  • Updated to openCV 3.4.6

2.0.3

  • Reversed some enums types ( SmartDecodingTypes SmartDecodingSubTypes) to uint64_t. You might need to make some changes where this enums were used.

  • Added 3 scanning behavior see setSmartScannerResultBehavior function

  • Updated to openCV 3.4.5

  • Added a “Changes” section in the readme :)


Licenses

SmartScan uses :

OpenCV, Apache 2 License
tensorflow, Apache 2 License