
Как интегрировать машинное обучение в приложение для Android: лучшие инструменты для распознавания изображений
Машинное обучение и распознавание объектов - две самые актуальные темы в мобильной разработке сегодня. Распознавание объектов является важной частью машинного обучения и может использоваться в таких областях, как электронная коммерция, здравоохранение, СМИ и образование. В этой статье мы покажем вам процесс интеграции машинного обучения в приложение для Android на примере маркировки изображений.
Рынок машинного зрения стремительно растет, и многие крупнейшие технологические компании мира вкладывают средства в новые инструменты машинного обучения. Эти инструменты позволяют разработчикам интегрировать машинное обучение и машинное зрение в свои мобильные приложения.
По данным Grand View Research, ожидается, что рынок машинного зрения вырастет до 18,24 млрд долларов к 2025 году при среднегодовом темпе роста 7,7%. Давайте посмотрим, в каких отраслях машинное зрение наиболее эффективно.
Отрасли, в которых машинное зрение используется в мобильных приложениях
Машинное зрение часто используется на производстве для контроля качества и безопасности. Программа анализирует изображения с камеры в режиме реального времени и замечает, если что-то не так.
Машинное зрение используется во многих других отраслях, и в этой статье мы рассмотрим, как различные типы мобильных приложений могут использовать машинное зрение.
Склады и логистика
Машинное зрение используется для сканирования штрих-кода на складах. Сканеры штрих-кода могут быть встроены в носимые или мобильные приложения для мобильности на складе.

Обычно сканеры штрих-кода встроены в носимые наручные часы для рабочих, поскольку они не занимают места и не требуют использования рук.
Розничная торговля
Розничная торговля - это большая отрасль, в которой машинное зрение может принести пользу. Как?
Во-первых, машинное зрение отлично подходит для интернет-магазинов: пользователь может загрузить изображение того, что он хочет, в мобильное приложение, а машинное зрение может распознать этот предмет или найти похожий.
Мобильное приложение ASOS делает именно это.

Его функция визуального поиска основана на машинном зрении.
Вы также можете использовать машинное зрение в своем приложении для электронной коммерции для оффлайн-магазина. Сканер штрих-кода может позволить покупателям найти дополнительную информацию о товарах, когда они совершают покупки в вашем магазине. Есть много других способов творчески использовать машинное зрение.
сельское хозяйство
В сельском хозяйстве также есть немало интересных способов использования машинного обучения и машинного зрения. Например, мобильное приложение с возможностями машинного зрения может помочь идентифицировать растения, просто сфотографировав их. Например, LeafSnap помогает идентифицировать деревья.

С более профессиональной точки зрения приложение от CROPTIX использует машинное зрение, чтобы помочь фермерам диагностировать болезни сельскохозяйственных культур.

Это всего лишь несколько примеров того, как вы можете использовать машинное зрение в мобильном приложении для достижения различных целей. Машинное зрение также используется для перевода, развлечений и дополненной реальности. Это помогает создавать умные идеи приложений дополненной реальности и воплощать их в жизнь. Давайте подробнее узнаем, на что способно машинное зрение и какие инструменты позволяют разработчикам интегрировать его в мобильные приложения.
Обзор машинного зрения
Машинное зрение позволяет устройствам находить, отслеживать, классифицировать и идентифицировать объекты на изображениях. Сложные алгоритмы машинного зрения позволяют получать данные из изображений и анализировать их.
Машинное зрение можно использовать для
- признавая,
- идентификация,
- обнаружение объектов,
- распознавание текста,
- реконструкция 3D-форм на основе 2D-изображений,
- распознавание и анализ движения,
- реконструкция изображений,
- сегментирование изображений,
- и многое другое.
Давайте посмотрим, какие инструменты и библиотеки вы можете использовать для реализации машинного зрения в своем приложении для Android.
Лучшие инструменты машинного обучения для распознавания изображений
OpenCV: самая известная библиотека машинного обучения

OpenCV - самая популярная библиотека машинного зрения среди разработчиков. Это библиотека с открытым исходным кодом, в которой хранятся тысячи алгоритмов обработки и анализа изображений, в том числе для распознавания объектов на фотографиях. Например, вы можете использовать OpenCV для распознавания лиц и поз людей или для распознавания текста.
Эта библиотека была разработана Intel, и теперь ее поддерживают Willow Garage и Itseez. Он написан на C ++, но также разработан для других языков программирования, включая Python, Java, Ruby и Matlab.
OpenCV содержит более 2500 оптимизированных алгоритмов для машинного обучения и компьютерного зрения. Вы можете использовать алгоритмы OpenCV для
- анализ и обработка изображений,
- распознавание лица,
- идентификация объекта,
- распознавание жестов в видеороликах,
- распознавание движения камеры,
- построение 3D моделей объектов,
- поиск похожих изображений в базе данных,
- отслеживание движения глаз,
- сегментация изображения,
- видео слежение и
- распознавание элементов сцены и добавление маркеров для дополненной реальности.
Но эта библиотека делает даже больше. Если вам нужен продвинутый инструмент для реализации машинного зрения в вашем мобильном приложении, OpenCV - отличный выбор.
TensorFlow: фреймворк для глубокого обучения

TensorFlow - это фреймворк машинного обучения от Google, который можно использовать для проектирования, создания и реализации моделей глубокого обучения. Глубокое обучение - это часть машинного обучения, основанная на том, как работает человеческий мозг.
Вы можете использовать TensorFlow для создания и обучения нейронных сетей любого известного типа.
Библиотека TensorFlow уже работает на множестве платформ, от огромных серверов до крошечных устройств Интернета вещей. Мобильные устройства - не исключение. Для мобильных приложений Google выпустила отдельную библиотеку под названием TensorFlow Lite.
Он был представлен на I / O 2017 и
- легкий и быстрый на мобильных устройствах;
- кроссплатформенный, поэтому работает на многих мобильных платформах, включая Android и iOS;
- поддерживает аппаратное ускорение, повышающее его производительность.
MLKit: новейший фреймворк для машинного обучения

Google представил Firebase MLKit на I / O 2018, и это один из самых простых в использовании фреймворков для машинного обучения. Его API позволяет разработчикам использовать
- распознавание текста,
- распознавание лица,
- распознавание штрих-кода,
- знаковое признание,
- маркировка изображений и
- распознавание объектов.
Независимо от того, являетесь ли вы начинающим разработчиком или опытным разработчиком, вы можете легко использовать MLKit в своих мобильных приложениях.
Позвольте мне показать вам пример того, как я использовал MLKit для маркировки изображений.
Учебник по маркировке изображений
1. Первый шаг - подключиться к сервисам Firebase. Для этого вам нужно войти в консоль Firebase и создать новый проект.
2. Затем вам нужно добавить следующие зависимости в ваш файл gradle:
implementation 'com.google.firebase:firebase-ml-vision:18.0.1' implementation 'com.google.firebase:firebase-ml-vision-image-label-model:17.0.2'
3. Если вы используете API на устройстве, настройте приложение для автоматической загрузки модели машинного обучения на устройство после установки приложения из Play Store.
Для этого добавьте следующее объявление в Файл AndroidManifest.xml:
<meta-data android:name="com.google.firebase.ml.vision.DEPENDENCIES" android:value="label" />
4. Пришло время создать макет экрана.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/layout_preview"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_take_picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="16dp"
android:text="Take Photo"
android:textSize="15sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/txt_result"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textAlignment="center"
android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_take_picture" />
</android.support.constraint.ConstraintLayout>
5. Используйте SurfaceView, чтобы отобразить предварительный просмотр камеры. Вы также должны добавить разрешение камеры в Manifest.xml:
android:name="android.permission.CAMERA
6. Создайте класс, расширяющий SurfaceView и реализующий интерфейс SurfaceHolder.Callback:
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
// create the surface and start camera preview
if (mCamera == null) {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
} catch (IOException e) {
Log.d(VIEW_LOG_TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void refreshCamera(Camera camera) {
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
setCamera(camera);
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
refreshCamera(mCamera);
}
public void setCamera(Camera camera) {
//method to set a camera instance
mCamera = camera;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
7. Последнее, что вам нужно сделать, это добавить логику для главного экрана приложения:
- Спросите у пользователя разрешение камеры.
- Если разрешение предоставлено, покажите предварительный просмотр камеры.
- После того, как пользователь нажмет кнопку «Сделать фото», отправьте растровое изображение в FirebaseVisionImage и покажите результат после завершения обработки.
import android.Manifest;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.ml.vision.FirebaseVision;
import com.google.firebase.ml.vision.common.FirebaseVisionImage;
import com.google.firebase.ml.vision.label.FirebaseVisionLabel;
import com.google.firebase.ml.vision.label.FirebaseVisionLabelDetector;
import com.google.firebase.ml.vision.label.FirebaseVisionLabelDetectorOptions;
import com.gun0912.tedpermission.PermissionListener;
import com.gun0912.tedpermission.TedPermission;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
private Camera mCamera;
private CameraPreview mPreview;
private Camera.PictureCallback mPicture;
@BindView(R.id.layout_preview)
LinearLayout cameraPreview;
@BindView(R.id.txt_result)
TextView txtResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
//keep screen always on getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
checkPermission();
}
//camera permission is a dangerous permission, so the user should grant this permission directly in real time. Here we show a permission pop-up and listen for the user’s response.
private void checkPermission() {
//Set up the permission listener
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
setupPreview();
}
@Override
public void onPermissionDenied(ArrayList deniedPermissions) {
Toast.makeText(MainActivity.this, "Permission Denied\n" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
}
};
//Check camera permission
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setDeniedMessage("If you reject permission,you can not use this service\n\nPlease turn on permissions at [Setting] > [Permission]")
.setPermissions(Manifest.permission.CAMERA)
.check();
}
//Here we set up the camera preview
private void setupPreview() {
mCamera = Camera.open();
mPreview = new CameraPreview(getBaseContext(), mCamera);
try {
//Set camera autofocus
Camera.Parameters params = mCamera.getParameters();
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
mCamera.setParameters(params);
}catch (Exception e){
}
cameraPreview.addView(mPreview);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
// take photo when the users tap the button
@OnClick(R.id.btn_take_picture)
public void takePhoto() {
mCamera.takePicture(null, null, mPicture);
}
@Override
protected void onPause() {
super.onPause();
//when on Pause, release camera in order to be used from other applications
releaseCamera();
}
private void releaseCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
//Here we get the photo from the camera and pass it to mlkit processor
private Camera.PictureCallback getPictureCallback() {
return new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
mlinit(BitmapFactory.decodeByteArray(data, 0, data.length));
mPreview.refreshCamera(mCamera);
}
};
}
//the main method that processes the image from the camera and gives labeling result
private void mlinit(Bitmap bitmap) {
//By default, the on-device image labeler returns at most 10 labels for an image.
//But it is too much for us and we wants to get less
FirebaseVisionLabelDetectorOptions options =
new FirebaseVisionLabelDetectorOptions.Builder()
.setConfidenceThreshold(0.5f)
.build();
//To label objects in an image, create a FirebaseVisionImage object from a bitmap
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);
//Get an instance of FirebaseVisionCloudLabelDetector
FirebaseVisionLabelDetector detector = FirebaseVision.getInstance()
.getVisionLabelDetector(options);
detector.detectInImage(image)
.addOnSuccessListener(
new OnSuccessListener>() {
@Override
public void onSuccess(List labels) {
StringBuilder builder = new StringBuilder();
// Get information about labeled objects
for (FirebaseVisionLabel label : labels) {
builder.append(label.getLabel())
.append(" ")
.append(label.getConfidence()).append("\n");
}
txtResult.setText(builder.toString());
}
})
.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
txtResult.setText(e.getMessage());
}
});
}
}
Вот как выглядит результат:

Я использовал офлайн-версию MLKit. Облачная версия доступна только при платной подписке.
Ключевые выводы
Внедрить MLKit в мобильное приложение для Android оказалось довольно просто. Когда я его протестировал, я обнаружил, что он не очень точен, но все же отлично работает для офлайн-сервиса.
Одна забавная вещь, которую я заметил во время работы с MLKit, заключается в том, что каждый раз, когда он не распознавал объект на фотографии, классификатор помечал его как музыкальный инструмент.
Разработчики MLKit позаботились о том, чтобы их решение машинного обучения было удобно интегрировать в мобильное приложение. Чтобы сделать его более продвинутым и настраиваемым, вам нужно будет использовать TensorFlow. В этом случае MLKit станет уровнем API для вашей системы машинного обучения, позаботится о хостинге и принесет модель TensorFlow в ваше мобильное приложение.
Хотите узнать, как создать расширенную модель машинного обучения или машинного зрения и интегрировать ее в свое мобильное приложение? Свяжитесь с Mobindustry. Мы поможем вам создать интеллектуальное решение для мобильного бизнеса.
Получите бесплатную консультацию!
[email protected]