I am trying to setup an ImageAnalyzer with my Android app so I can run object classification using Google's ML Kit API. The issue I am currently facing, as the title suggests, is constantly seeing the error "Failed to initialize detector".
I've reread this tutorial about three times now and followed this post about someone facing the same error (although for a different reason) to no avail. I've also made sure everything with the CameraX API (except the ImageAnalyzer code that I will show in a second) works as expected.
As mentioned in the ML Kit documentation, here is the code I have regarding setting up a LocalModel
, a CustomObjectDetectorOptions
, and an ObjectDetector
:
LocalModel localModel = new LocalModel.Builder()
.setAssetFilePath("mobilenet_v1_1.0_224_quantized_1_metadata_1.tflite")
.build();
CustomObjectDetectorOptions customObjectDetectorOptions =
new CustomObjectDetectorOptions.Builder(localModel)
.setDetectorMode(CustomObjectDetectorOptions.STREAM_MODE)
.enableClassification()
.setClassificationConfidenceThreshold(0.5f)
.setMaxPerObjectLabelCount(3)
.build();
ObjectDetector objectDetector = ObjectDetection.getClient(customObjectDetectorOptions);
Here is the ImageAnalyzer code I have, which basically makes a call to the ML Kit API by way of the processImage
helper method:
// Creates an ImageAnalysis for analyzing the camera preview feed
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setTargetResolution(new Size(224, 224))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(this),
new ImageAnalysis.Analyzer() {
@Override
public void analyze(@NonNull ImageProxy imageProxy) {
@SuppressLint("UnsafeExperimentalUsageError") Image mediaImage =
imageProxy.getImage();
if (mediaImage != null) {
Log.i(TAG, "Obtained ImageProxy object");
processImage(mediaImage, imageProxy)
.addOnCompleteListener(new OnCompleteListener<List<DetectedObject>>() {
@Override
public void onComplete(@NonNull Task<List<DetectedObject>> task) {
imageProxy.close();
}
});
}
}
});
Here is the processImage
helper method, where I actually call objectDetector.process(...)
, the line of code that actually runs the tflite model.
private Task<List<DetectedObject>> processImage(Image mediaImage, ImageProxy imageProxy) {
InputImage image =
InputImage.fromMediaImage(mediaImage,
imageProxy.getImageInfo().getRotationDegrees());
return objectDetector.process(image)
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
String error = "Failed to process. Error: " + e.getMessage();
Log.i(TAG, error);
}
})
.addOnSuccessListener(new OnSuccessListener<List<DetectedObject>>() {
@Override
public void onSuccess(List<DetectedObject> results) {
String success = "Object(s) detected successfully!";
Log.i(TAG, success);
for (DetectedObject detectedObject : results) {
Rect boundingBox = detectedObject.getBoundingBox();
Integer trackingId = detectedObject.getTrackingId();
for (DetectedObject.Label label : detectedObject.getLabels()) {
String text = label.getText();
int index = label.getIndex();
float confidence = label.getConfidence();
Log.i(TAG, "Object detected: " + text + "; "
+ "Confidence: " + confidence);
}
}
}
});
}
Essentially, once I run the app, logcat just keeps logging these two lines on repeat. I know it means the ImageAnalyzer is continuously trying to analyze the image input, but for some reason the LocalModel
just cannot process the input
2021-01-21 22:02:24.020 9328-9328/com.example.camerax I/MainActivity: Obtained ImageProxy object
2021-01-21 22:02:24.036 9328-9328/com.example.camerax I/MainActivity: Failed to process. Error: Failed to initialize detector.
I have only just started to work with Android, especially ML in Android, so any sort of help would be appreciated!
I managed to fix my issue before anyone answered, but in case anyone who just started to learn Android like me I'll leave my solution here.
Basically, remember to create an asset folder in the /src/main directory rather than the /src/androidTest directory :P
Once I did that, the model loaded correctly and now I just have to figure out how to display the results in my application.