ML Kit Tutorial: How to recognize and decode barcodes(Barcode Scanning)

ML Kit Tutorial: How to recognize and decode barcodes(Barcode Scanning)

If you are a seasoned Android developer, you probably have come across some cool barcode scanning libraries like ZXing, ZBar and Google’s Mobile Vision API. All of them works pretty well and have their own pros and cons. With these cool libraries already available, the question is, what is ML Kit offering?

What's new in the ML Kit Barcode Scanning API?

ML Kit Barcode Scanning API is same as Mobile Vision API but ML Kit comes with new capabilities like on-device image labeling. Google is ultimately closing down Mobile Vision API which is now part of ML Kit. The main advantage of using ML Kit is that ML Kit can automatically detect all supported barcode formats at once, without having to specify the format you're looking for. This can help your app trigger intelligent response when a user scans a barcode. Intelligent response is what makes the ML Kit Barcode Scanning API stands out.

Following are the key capabilities of ML Kit Barcode Scanning API:

  1. ML Kit is a superset of Mobile Vision API. It can read all the standard formats(1D formats: Codabar, Code 39, Code 93, Code 128, EAN-8, EAN-13, ITF, UPC-A, UPC-E; and 2D formats: Aztec, Data Matrix, PDF417, QR Code) that Mobile Vision API can

  2. It can automatically scan for all supported barcode formats at once, without having to specify the format you're looking for. Or, boost scanning speed by restricting the detector to only the formats you're interested in.

  3. Structured data stored using one of the supported 2D formats are automatically parsed. Supported information types include URLs, contact information, calendar events, email addresses, phone numbers, SMS message prompts, ISBNs, WiFi connection information, geographic location, and AAMVA-standard driver information.

  4. Barcodes are recognized and scanned regardless of their orientation: right-side-up, upside-down, or sideways.

In this lesson, we are going to learn how to use the ML Kit Barcode Scanning API to scan and process barcodes. This tutorial does not require you prior knowledge or experience in Machine Learning. But you should be well familiar with Android Studio and its directory structures. If not, then you may refer Android Studio Project Overview.

Before we start, have a look at what we are going to build in the end:

1. Follow steps 1 to 7 of ML Kit Tutorial: How to detect faces with ML Kit API and identify key facial features. For Barcode API, we need only one of the ML Kit dependencies in the app-level build.gradle file.

dependencies {
  // ...
  implementation 'com.google.firebase:firebase-ml-vision:17.0.0'
}

2.There is an option to enable downloading of the ML model right after installation by adding the following declaration to the AndroidManifest.xml file:

<meta-data
      android:name="com.google.firebase.ml.vision.DEPENDENCIES"
      android:value="barcode" />
<!-- To use multiple models: android:value="barcode,model2,model3" -->

If this declaration is absent, the model will be downloaded the first time you run the detector. Requests made before the model is downloaded will produce no results.

3. Now we can just go to the action part:

Configuring the barcode detector

If you know which barcode formats you expect to read, you can improve the speed of the barcode detector by configuring it to only detect those formats.For example, to detect only Aztec code and QR codes, build a FirebaseVisionBarcodeDetectorOptions object as follows:

FirebaseVisionBarcodeDetectorOptions options =
	new FirebaseVisionBarcodeDetectorOptions.Builder()
	.setBarcodeFormats(
		FirebaseVisionBarcode.FORMAT_QR_CODE,
		FirebaseVisionBarcode.FORMAT_AZTEC)
	.build();

The supported formats are:

  • Code 128 (FORMAT_CODE_128)

  • Code 39 (FORMAT_CODE_39)

  • Code 93 (FORMAT_CODE_93)

  • Codabar (FORMAT_CODABAR)

  • EAN-13 (FORMAT_EAN_13)

  • EAN-8 (FORMAT_EAN_8)

  • ITF (FORMAT_ITF)

  • UPC-A (FORMAT_UPC_A)

  • UPC-E (FORMAT_UPC_E)

  • QR Code (FORMAT_QR_CODE)

  • PDF417 (FORMAT_PDF417)

  • Aztec (FORMAT_AZTEC)

  • Data Matrix (FORMAT_DATA_MATRIX)

Running the barcode detector

To recognize barcodes in an image, get an instance of FirebaseVisionBarcodeDetector as follows:

FirebaseVisionBarcodeDetector detector = FirebaseVision.getInstance()
        .getVisionBarcodeDetector();
// Or, to specify the formats to recognize:
// FirebaseVisionBarcodeDetector detector = FirebaseVision.getInstance()
//        .getVisionBarcodeDetector(options);

Now you can pass the image to the detectInImage method as follows:

Task> result = detector.detectInImage(image)
	.addOnSuccessListener(new OnSuccessListener>() {
		@Override
		public void onSuccess(List barcodes) {
			// Task completed successfully
			// ...
		}
	})
	.addOnFailureListener(new OnFailureListener() {
		@Override
		public void onFailure(@NonNull Exception e) {
			// Task failed with an exception
			// ...
		}
	});

All these tasks are defined in BarcodeScanningProcessor.java. You can include this file directly in main java package for quick setup. For convenience, you may put this in a separate package folder(in my case "barcodescanning").

If the barcode recognition operation succeeds, the detector returns a list of FirebaseVisionBarcode objects. Each FirebaseVisionBarcode object represents a barcode that was detected in the image. For each barcode, you can get its bounding coordinates in the input image, as well as the raw data encoded by the barcode. Also, if the barcode detector was able to determine the type of data encoded by the barcode, you can get an object containing parsed data. The following example illustrates this:

for (FirebaseVisionBarcode barcode: barcodes) {
    Rect bounds = barcode.getBoundingBox();
    Point[] corners = barcode.getCornerPoints();

    String rawValue = barcode.getRawValue();

    int valueType = barcode.getValueType();
    // See API reference for complete list of supported types
    switch (valueType) {
        case FirebaseVisionBarcode.TYPE_WIFI:
            String ssid = barcode.getWifi().getSsid();
            String password = barcode.getWifi().getPassword();
            int type = barcode.getWifi().getEncryptionType();
            break;
        case FirebaseVisionBarcode.TYPE_URL:
            String title = barcode.getUrl().getTitle();
            String url = barcode.getUrl().getUrl();
            break;
    }
}

This task along with methods for rendering a barcode information within an associated graphic overlay view are defined in the BarcodeGraphic.java. You can include this file in the same package folder as BarcodeScanningProcessor.java.

5. Now we can use BarcodeScanningProcessor.java in the MainActivity.java like this. This is the full and final code of MainActivity.java.

6. Now run the project. You should see that the app is now completed exactly as shown in the video above.

And thats it! You have just learnt how to use the ML Kit's barcode scanning API to detect recognize and decode barcodes. This is the fourth tutorial of the ML Kit Tutorial Series. If you have any issue while running the project or setting it up, just leave a comment below.






Author:


Ratul Doley
Ratul Doley
Entrepreneur and AI researcher. Currently learning and working on Unsupervised learning and Data Clustering. Professional Android app developer and designer. Updated Nov 15, 2018