[Huawei Developers] John Wo:
Introduction

In today's world, it has become vital for mobile applications to have intelligent capabilities. Machine learning enables us to bring such capabilities to light, one such capability is to recognise the text in a picture.

In this article we will explore Huawei ML Kit MLTextAnalyzer and Google's ML Kit FirebaseVisionTextRecognizer side by side. We will see the integration of text recognition APIs and compare the pricing as well.

Steps to begin with:

1. Register your app in AGC and add the agconnect-service.json to your project.

2. Include Huawei developers Maven repository in both your buildscript and allprojects sections of your project-level build.gradle file. Preparations to integrate HMS core is mentioned here

3. Add the below dependencies for the ML Kit Android libraries at app-level Gradle file.

//AGC Core
implementation 'com.huawei.agconnect:agconnect-core:1.4.0.300'

//ML OCR Base SDK
implementation 'com.huawei.hms:ml-computer-vision-ocr:2.0.5.300'

4. After the user installs the app from HUAWEI AppGallery, the machine learning model is automatically updated to the user's device. To do that add the following in AndroidManifest.xml

<manifest>
...
<meta-data
android:name="com.huawei.hms.ml.DEPENDENCY"
android:value= "ocr"/>
...
</manifest>

5. We include an ImageView, a TextView to display the extracted text from the image and relative buttons for respective operations.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/captured_image_view"
android:layout_width="match_parent"
android:layout_height="400dp"
android:contentDescription="@string/content_description" />
<TextView
android:id="@+id/detected_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/captured_image_view"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:maxLines="10"
android:textAlignment="center"
android:textSize="20sp" />
<Button
android:id="@+id/capture_image"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:layout_above="@+id/detect_text_from_image"
android:layout_centerHorizontal="true"
android:layout_marginBottom="11dp"
android:background="@drawable/button_background"
android:text="@string/capture_image"
android:textAllCaps="false"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="@android:color/widget_edittext_dark"
android:textSize="26sp" />
<Button
android:id="@+id/detect_text_from_image"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="15dp"
android:background="@drawable/button_background"
android:text="@string/detect_text"
android:textAllCaps="false"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="@android:color/widget_edittext_dark"
android:textSize="26sp" />
</RelativeLayout>

6. Before we delve into the MainActivity, let us apply required permissions in our AndroidManifest.xml.

<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.camera" android:required="true" />

7. MainActivity will be as follows.

* Here dispatchTakePictureIntent() method is invoked to take a picture.

* onActivityResult() retrieves the image captured and displays it in an ImageView.

* runTextRecognition() will convert the image in bitmap format to text using an object of MLTextAnalyser.

* asyncAnalyzeText() will display the extracted text from the image.

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.huawei.hmf.tasks.OnFailureListener;
import com.huawei.hmf.tasks.OnSuccessListener;
import com.huawei.hmf.tasks.Task;
import com.huawei.hms.mlsdk.MLAnalyzerFactory;
import com.huawei.hms.mlsdk.common.MLFrame;
import com.huawei.hms.mlsdk.text.MLLocalTextSetting;
import com.huawei.hms.mlsdk.text.MLText;
import com.huawei.hms.mlsdk.text.MLTextAnalyzer;

import java.io.IOException;

public class MainActivity extends AppCompatActivity {
static final int REQUEST_IMAGE_CAPTURE = 1;
Bitmap myBitmapImage;
private MLTextAnalyzer mTextAnalyzer;
private Button captureImageBtn, detectBtn;
private ImageView capturedImageView;
private TextView detectedTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
captureImageBtn = findViewById(R.id.capture_image);
detectBtn = findViewById(R.id.detect_text_from_image);
capturedImageView = findViewById(R.id.captured_image_view);
detectedTextView = findViewById(R.id.detected_text_view);
captureImageBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dispatchTakePictureIntent();
detectedTextView.setText("");
}
});
detectBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
createMLTextAnalyzer();
}
});
}

private void dispatchTakePictureIntent() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK && data != null) {
Bundle extras = data.getExtras();
Bitmap selectedBitmap = (Bitmap) extras.get("data");
capturedImageView.setImageBitmap(selectedBitmap);
asyncAnalyzeText(selectedBitmap);
}
}

private void createMLTextAnalyzer() {
MLLocalTextSetting setting = new MLLocalTextSetting.Factory()
.setOCRMode(MLLocalTextSetting.OCR_DETECT_MODE)
.setLanguage("en")
.create();
mTextAnalyzer = MLAnalyzerFactory.getInstance().getLocalTextAnalyzer(setting);

}

private void asyncAnalyzeText(Bitmap bitmap) {
if (mTextAnalyzer == null) {
createMLTextAnalyzer();
}
MLFrame frame = MLFrame.fromBitmap(bitmap);
Task<MLText> task = mTextAnalyzer.asyncAnalyseFrame(frame);
task.addOnSuccessListener(new OnSuccessListener<MLText>() {
@Override
public void onSuccess(MLText text) {
detectedTextView.setText(text.getStringValue());
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
detectedTextView.setText(e.getMessage());
}
});
}

@Override
protected void onDestroy() {
super.onDestroy();
try {
if (mTextAnalyzer != null)
mTextAnalyzer.stop();
} catch (IOException e) {
e.printStackTrace();
}
}
}

8. The result is as follows:

More details, you can check https://forums.developer.huawei.com/forumPortal/en/topic/0203446016529250080