В этой статье описывается, как применить машинное обучение к Android с помощью Fritz.ai. Прежде чем углубляться в детали разработки Android-приложения для машинного обучения, полезно кратко описать, что такое платформа Fritz.ai. Как вы, возможно, знаете, машинное обучение является интересной темой, которая приобретает все большее значение и обещает изменить несколько областей, включая то, как мы взаимодействуем с приложениями для Android.
Чтобы экспериментировать, как применить машинное обучение к Android с помощью Fritz.ai, мы разработаем приложение для Android, которое использует классификацию изображений машинного обучения .
Машинное обучение — это приложение искусственного интеллекта, которое дает системе возможность выполнять задачи, не используя четких инструкций, но изучая данные и улучшая свой опыт.
Что такое платформа машинного обучения Fritz.ai?
Fritz.ai — это платформа машинного обучения для Android и iOS, которая упрощает разработку приложения машинного обучения для Android . При разработке приложения Android с машинным обучением обычно необходимо создать ML-модель, которая будет использоваться приложением Android. Процесс построения ML-модели утомителен и сложен. Fritz.ai предоставляет набор встроенных моделей, готовых к использованию, что ускоряет разработку приложения Machine Learning для Android.
Встроенные ML-модели, представленные Fritz.ai:
- Маркировка изображения
- Обнаружение объекта
- Стиль передачи
- Сегментация изображения
- Оценка позы
Кроме того, можно загрузить пользовательскую модель, если мы хотим использовать конкретную модель.
Как настроить Fritz.ai
Первым шагом для использования платформы Fritz.ai Machine Learning является создание бесплатной учетной записи, а затем создание нового проекта Android для машинного обучения, как показано на рисунке ниже:
Теперь можно добавить новый проект:
Вы должны предоставить название проекта. После того, как проект создан, необходимо предоставить пакет проекта:
Как настроить проект Android с помощью Fritz.ai
После того, как проект правильно настроен в консоли Fritz.ai, мы можем настроить проект Android на включение Fritz.ai. На уровне проекта необходимо изменить build.gradle
следующим образом:
1
2
3
4
5
6
7
8
9
|
... allprojects { repositories { google() jcenter() maven { url "https://raw.github.com/fritzlabs/fritz-repository/master" } } } ... |
и в build.gradle
на уровне приложения:
1
2
3
4
5
|
dependencies { .... implementation 'ai.fritz:core:3.0.1' implementation 'ai.fritz:vision:3.0.1' } |
Последний шаг — регистрация службы, чтобы приложение Android могло получать обновления модели. Для этого в Manifest.xml
необходимо добавить:
1
2
3
4
|
< service android:name = "ai.fritz.core.FritzCustomModelService" android:exported = "true" android:permission = "android.permission.BIND_JOB_SERVICE" /> |
Это все. Теперь мы готовы начать разработку нашего Android-приложения для машинного обучения.
Больше полезных ресурсов
Firebase ML Kit: создание приложения для определения особенностей лица с помощью Face Detection API
9 способов машинного обучения революционизируют управление цепочками поставок
Внедрение машинного обучения для маркировки изображений в Android
Чтобы реализовать приложение Android, которое использует маркировку изображений машинного обучения, мы должны выполнить следующие шаги:
- Настройте Fritz.ai SDK в приложении для Android
- Пометьте изображение как обнаруженное
Настроить Fritz.ai SDK в приложении для Android
Первым шагом является настройка Fritz.ai SDK в нашем приложении для Android, чтобы мы могли использовать его позже, когда нам понадобится пометить захваченное изображение. Давайте создадим действие и в onCreate()
добавим следующие строки:
1
2
3
4
5
6
|
protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); Fritz.configure( this , "your_fritz.ai_key" ); downloadModel(); } |
В строке 4 необходимо настроить Fritz с помощью API_KEY, который мы получаем во время настройки проекта в консоли. Следующий шаг, это загрузка модели из облака:
01
02
03
04
05
06
07
08
09
10
11
|
private void downloadModel() { FritzManagedModel model = new ImageLabelManagedModel(); Log.d(TAG, "Download model..." ); FritzVision.ImageLabeling.loadPredictor(model, new PredictorStatusListener<FritzVisionLabelPredictor>() { @Override public void onPredictorReady(FritzVisionLabelPredictor predictor) { Log.d(TAG, "Model downloaded" ); MainActivity. this .predictor = predictor; } }); } |
В этом случае приложение Android использует ImageLabelManageModel
потому что мы хотим пометить изображение с помощью машинного обучения.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity" > < TextureView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignParentTop = "true" android:id = "@+id/preview" /> < Button android:layout_width = "match_parent" android:layout_height = "wrap_content" android:id = "@+id/btnLabel" android:text = "Label it" android:layout_alignParentBottom = "true" /> </ RelativeLayout > |
TextureView
буду
удерживайте поток изображения, поступающий с камеры, пока кнопка будет использоваться для маркировки изображения, как мы увидим позже.
Как использовать машинное обучение для маркировки изображения
Чтобы использовать машинное обучение для классификации изображения, когда у нас есть изображение с камеры, необходимо создать экземпляр FritzVisionImage
. Предположим, к настоящему времени, что у нас есть экземпляр ImageReader
который содержит изображение, снятое с камеры. Необходимо преобразовать его в растровое изображение, а затем использовать предиктор для маркировки изображения:
1
2
3
4
5
6
7
|
Image image = reader.acquireLatestImage(); ByteBuffer buffer = image.getPlanes()[ 0 ].getBuffer(); byte [] bytes = new byte [buffer.capacity()]; buffer.get(bytes); Bitmap bitmapImage = BitmapFactory.decodeByteArray(bytes, 0 , bytes.length, null ); FritzVisionImage fvi = FritzVisionImage.fromBitmap(bitmapImage); |
Наконец, в строке 8 предиктор, который пометит изображение, готов к использованию. Теперь приложение Android может получить список меток с
Относительная
точность:
1
2
3
4
5
6
|
FritzVisionLabelResult labels = predictor.predict(fvi); List<FritzVisionLabel> labelList = labels.getVisionLabels(); if (labelList != null && labelList.size() > 0 ) { FritzVisionLabel label = labels.getVisionLabels().get( 0 ); System.out.println( "Label [" + label.getText() + "]" ); } |
Приложение получает первый элемент списка, который имеет более высокую точность. Теперь мы можем описать, как использовать камеру в Android для захвата изображения.
Управление камерой в Android
Когда механизм машинного обучения готов, мы должны сосредоточить наше внимание на том, как сделать снимок. Как говорилось ранее,
TextureView
буду
удерживать поток изображения, поступающий с камеры. Необходимо добавить слушателя к TextureView, чтобы знать, когда мы можем использовать камеру:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
TextureView.SurfaceTextureListener surfaceListener = new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { Log.d(TAG, "Surface available" ); openCamera(); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {} @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { return false ; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } }; |
Когда поверхность готова, приложение может открыть камеру и начать использовать ее. Пожалуйста, обратите внимание, что:
1
2
|
preview = (TextureView) findViewById(R.id.preview); preview.setSurfaceTextureListener(surfaceListener); |
Теперь можно открыть камеру:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
private void openCamera() { CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); // We get the first available camera try { cameraId = manager.getCameraIdList()[ 0 ]; CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); StreamConfigurationMap streamConfMap = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); imageDimension = streamConfMap.getOutputSizes(SurfaceTexture. class )[ 0 ]; // We can open the camera now manager.openCamera(cameraId, new cameraDevice.StateCallback() { @Override public void onOpened( @NonNull CameraDevice camera) { Log.i(TAG, "Camera opened" ); cameraDevice = camera; createPreview(); } @Override public void onDisconnected( @NonNull CameraDevice camera) { } @Override public void onError( @NonNull CameraDevice camera, int error) { Log.e(TAG, "Error opening the camera" ); } }, null ); } catch (CameraAccessException cae) { // Let us handle the error } catch (SecurityException se) { } } |
Когда камера открыта и готова к использованию, приложение Android может начать потоковую передачу изображений:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
private void createPreview() { SurfaceTexture surfaceTexture = preview.getSurfaceTexture(); surfaceTexture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight()); Surface surface = new Surface(surfaceTexture); try { previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); previewRequestBuilder.addTarget(surface); cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() { public void onConfigured( @NonNull CameraCaptureSession cameraCaptureSession) { cameraSession = cameraCaptureSession; previewRequestBuilder.set( CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // Flash is automatically enabled when necessary. previewRequestBuilder.set( CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); // Finally, we start displaying the camera preview. CaptureRequest previewRequest = previewRequestBuilder.build(); try { cameraSession.setRepeatingRequest( previewRequest, new CameraCaptureSession.CaptureCallback() { @Override public void onCaptureProgressed( final CameraCaptureSession session, final CaptureRequest request, final CaptureResult partialResult) { } @Override public void onCaptureCompleted( final CameraCaptureSession session, final CaptureRequest request, final TotalCaptureResult result) { } }, backgroundHandler); } catch (CameraAccessException cae) {} } @Override public void onConfigureFailed( @NonNull CameraCaptureSession cameraCaptureSession) { Log.e(TAG, "Configuration failed" ); } }, null ); } catch (CameraAccessException cae) {} } |
Маркировка изображения, полученного камерой
На этом последнем шаге необходимо сделать снимок и пометить его с помощью машинного обучения. Для этого приложение Android использует кнопку, определенную в предыдущем макете:
1
2
3
4
5
6
7
|
labelBtn = (Button) findViewById(R.id.btnLabel); labelBtn.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { takePicture(); } }); |
В
takePicture
метод
приложение для Android берет изображение и маркирует его (как показано выше). Если вы хотите получить полный код, вы можете зайти на Github и скачать его.
Резюме
В конце этой статьи вы, надеюсь, получили знания о том, как применить машинное обучение к Android с помощью Fritz.ai. Вы узнали, как использовать классификацию изображений с помощью машинного обучения для маркировки изображений, полученных камерой.
Опубликовано на Java Code Geeks с разрешения Франческо Аццолы, партнера по нашей программе JCG. Смотрите оригинальную статью здесь: Как применить Machine Learning к Android с помощью Fritz.ai Мнения, высказанные участниками Java Code Geeks, являются их собственными. |