fritz
本文介绍如何使用Fritz.ai将机器学习应用于Android 。 在深入探讨如何开发机器学习Android应用程序的细节之前,简要介绍一下什么是Fritz.ai平台很有用。 如您所知,机器学习是一个有趣的话题,它正变得越来越重要,并有望改变几个领域,包括我们与Android应用程序交互的方式。
为了实验如何使用Fritz.ai将机器学习应用于Android,我们将开发一个使用机器学习图像分类的Android应用。
机器学习是AI的一种应用,它使系统无需使用明确的指令即可完成任务,而可以从数据中学习并从经验中获得改进。
什么是Fritz.ai机器学习平台?
Fritz.ai是适用于Android和iOS的机器学习平台,可简化Android机器学习应用程序的开发。 在开发机器学习Android应用程序时,通常需要创建将由Android应用程序使用的ML模型。 建立ML模型的过程既繁琐又困难。 Fritz.ai提供了一组可供使用的内置模型,这些模型可以加快机器学习Android应用的开发速度。
Fritz.ai提供的内置ML模型是:
- 图像标注
- 物体检测
- 风格转移
- 图像分割
- 姿势刺激
此外,如果我们要使用特定模型,则可以上传自定义模型。
如何配置Fritz.ai
使用Fritz.ai机器学习平台的第一步是创建一个免费帐户,然后创建一个新的机器学习Android项目,如下图所示:
现在,可以添加一个新项目:
您必须提供项目名称。 创建项目后,有必要提供项目包:
如何使用Fritz.ai设置Android项目
在Fritz.ai控制台中正确配置项目后,我们可以将Android项目设置为包括Fritz.ai。 在项目级别,必须以这种方式修改build.gradle
:
...
allprojects {
repositories {
google()
jcenter()
maven { url "https://raw.github.com/fritzlabs/fritz-repository/master" }
}
}
...
并在应用程序级别的build.gradle
中:
dependencies {
....
implementation 'ai.fritz:core:3.0.1'
implementation 'ai.fritz:vision:3.0.1'
}
最后一步是注册服务,以便Android应用可以接收模型更新。 为此,需要在Manifest.xml
中添加:
<service
android:name="ai.fritz.core.FritzCustomModelService"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" />
就这样。 现在,我们准备开始开发我们的机器学习Android应用程序。
更多有用的资源
Firebase ML Kit:使用人脸检测API构建人脸特征检测应用
在Android中实现机器学习图像标签
要实现使用机器学习图像标签的Android应用,请执行以下步骤:
- 在Android应用中配置Fritz.ai SDK
- 标记检测到的图像
在Android应用中配置Fritz.ai SDK
第一步是在我们的Android应用程序中配置Fritz.ai SDK,以便以后需要标记所捕获图像时可以使用它。 让我们创建一个活动,并在onCreate()
方法中添加以下行:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Fritz.configure(this, "your_fritz.ai_key");
downloadModel();
}
在第4行中,有必要使用控制台中设置项目期间获得的API_KEY配置Fritz。 下一步,它是从云下载模型:
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
因为我们要使用机器学习来标记图像。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
<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
实例,该实例保存从相机捕获的图像。 有必要将其转换为位图,然后使用预测变量标记图像:
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应用程序可以使用
相对的准确性:
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中添加一个侦听器,以了解何时可以使用相机:
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) {
}
};
准备好表面后,应用程序可以打开相机并开始使用。 请注意:
preview = (TextureView) findViewById(R.id.preview);
preview.setSurfaceTextureListener(surfaceListener);
现在可以打开相机了:
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应用可以开始流式传输图像:
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应用程序使用先前布局中定义的按钮:
labelBtn = (Button) findViewById(R.id.btnLabel);
labelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePicture();
}
});
在
的takePicture
方法,Android应用程序会拍照并标记标签(如上所示)。 如果您想获得完整的代码,可以转到Github并下载。
概要
在本文的最后,您希望获得有关如何使用Fritz.ai将机器学习应用于Android的知识。 您已经发现了如何使用机器学习图像分类来标记相机拍摄的图像。
翻译自: https://www.javacodegeeks.com/2019/03/machine-learning-android-using-fritz-ai.html
fritz