Getting started with ML KIT — QR CODE DETECTION

AJAY J G
3 min readJun 30, 2018

--

Bar-code/Qr Code detection using ML KIT

Firebase launched ML Kit to recognize and decode barcodes(and much more). This article helps you to integrate bar-code detection using ML KIT.

1.Configure Build.gradle

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

2.Update Manifest file

Add the following declaration to your app’s AndroidManifest.xml file under <application> to automatically download the ML model to the device after your app is installed from the Play Store.

  <meta-data
android:name="com.google.firebase.ml.vision.DEPENDENCIES"
android:value="barcode" />

3. Configure Bar-code 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.

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

The following formats are supported:

  • 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)

4. Create a FirebaseVisionImage object from your image.

  • To create a FirebaseVisionImage object from a Bitmap/ByteBuffer/ByteArray/File:
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);FirebaseVisionImage image = FirebaseVisionImage.fromByteBuffer(buffer, metadata);FirebaseVisionImage image = FirebaseVisionImage.fromByteArray(byteArray, metadata);FirebaseVisionImage image;
try {
image = FirebaseVisionImage.fromFilePath(context, uri);
} catch (IOException e) {
e.printStackTrace();
}

To create a FirebaseVisionImage object from a ByteBuffer or a byte array, first calculate the image rotation as described below.

private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}

/**
* Get the angle by which an image must be rotated given the device's current
* orientation.
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private int getRotationCompensation(String cameraId, Activity activity, Context context)
throws CameraAccessException {
// Get the device's current rotation relative to its "native" orientation.
// Then, from the ORIENTATIONS table, look up the angle the image must be
// rotated to compensate for the device's rotation.
int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int rotationCompensation = ORIENTATIONS.get(deviceRotation);

// On most devices, the sensor orientation is 90 degrees, but for some
// devices it is 270 degrees. For devices with a sensor orientation of
// 270, rotate the image an additional 180 ((270 + 270) % 360) degrees.
CameraManager cameraManager = (CameraManager) context.getSystemService(CAMERA_SERVICE);
int sensorOrientation = cameraManager
.getCameraCharacteristics(cameraId)
.get(CameraCharacteristics.SENSOR_ORIENTATION);
rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360;

// Return the corresponding FirebaseVisionImageMetadata rotation value.
int result;
switch (rotationCompensation) {
case 0:
result = FirebaseVisionImageMetadata.ROTATION_0;
break;
case 90:
result = FirebaseVisionImageMetadata.ROTATION_90;
break;
case 180:
result = FirebaseVisionImageMetadata.ROTATION_180;
break;
case 270:
result = FirebaseVisionImageMetadata.ROTATION_270;
break;
default:
result = FirebaseVisionImageMetadata.ROTATION_0;
Log.e(TAG, "Bad rotation value: " + rotationCompensation);
}
return result;
}

Then, create a FirebaseVisionImageMetadata object that contains the image's height, width, color encoding format, and rotation:

FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
.setWidth(1280)
.setHeight(720)
.setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
.setRotation(rotation)
.build();

5. Get an instance of FirebaseVisionBarcodeDetector:

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

6. Finally, pass the image to the detectInImage method:

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

7. Detected Bar-code Information:

If the barcode detector was able to determine the type of data encoded by the barcode, you can get an object containing parsed data.

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;
}
}

And that’s it, you are ready to scan Bar-Codes/QR Codes/Data Matrix codes using ML VISION no need to have deep knowledge of neural networks or model optimization to get started.

--

--

AJAY J G

I'm extremely passionate about Android, building machine learning and computer vision technologies that have impact on the "Real-World".