Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit b248acd

Browse files
Add support for ML Kit Object Detection and Tracking #1274
1 parent fe5c0de commit b248acd

File tree

3 files changed

+69
-7
lines changed

3 files changed

+69
-7
lines changed

docs/ML_KIT.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ To be able to use Cloud features you need to do two things:
8181
|---|---|---
8282
|[Text recognition](#text-recognition)|✅|✅
8383
|[Face detection](#face-detection)|✅|
84+
|[Object detection and tracking](#object-detection-and-tracking)|✅|
8485
|[Barcode scanning](#barcode-scanning)|✅|
8586
|[Image labeling](#image-labeling)|✅|✅
8687
|[Landmark recognition](#landmark-recognition)||✅
@@ -269,6 +270,46 @@ registerElement("MLKitFaceDetection", () => require("nativescript-plugin-firebas
269270
</MLKitFaceDetection>
270271
```
271272
273+
### Object detection and tracking
274+
<img src="https://raw.githubusercontent.com/EddyVerbruggen/nativescript-plugin-firebase/master/docs/images/features/mlkit_object_detection.png" height="124px" alt="ML Kit - Object detection and tracking"/>
275+
276+
[Firebase documentation 🌎](https://firebase.google.com/docs/ml-kit/object-detection)
277+
278+
#### Still image
279+
280+
```typescript
281+
import { MLKitObjectDetectionResult } from "nativescript-plugin-firebase/mlkit/objectdetection";
282+
const firebase = require("nativescript-plugin-firebase");
283+
284+
firebase.mlkit.objectdetection.detectObjects({
285+
image: imageSource, // a NativeScript Image or ImageSource, see the demo for examples
286+
classify: true, // default false, attempts to classify the object(s) if true
287+
multiple: true // default false, attempts to detect multiple objects (instead of only the most prominent one) when true
288+
})
289+
.then((result: MLKitObjectDetectionResult) => console.log(JSON.stringify(result.objects)))
290+
.catch(errorMessage => console.log("ML Kit error: " + errorMessage));
291+
```
292+
293+
#### Live camera feed
294+
The basics are explained above for 'Text recognition', so we're only showing the differences here.
295+
296+
```typescript
297+
import { registerElement } from "nativescript-angular/element-registry";
298+
registerElement("MLKitObjectDetection", () => require("nativescript-plugin-firebase/mlkit/objectdetection").MLKitObjectDetection);
299+
```
300+
301+
```html
302+
<MLKitObjectDetection
303+
width="260"
304+
height="380"
305+
classify="true"
306+
multiple="false"
307+
processEveryNthFrame="20"
308+
[torchOn]="torchOn"
309+
(scanResult)="onObjectDetectionResult($event)">
310+
</MLKitObjectDetection>
311+
```
312+
272313
### Barcode scanning
273314
<img src="https://raw.githubusercontent.com/EddyVerbruggen/nativescript-plugin-firebase/master/docs/images/features/mlkit_text_barcode_scanning.png" height="153px" alt="ML Kit - Barcode scanning"/>
274315
19.4 KB
Loading

src/mlkit/objectdetection/index.android.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ImageSource } from "tns-core-modules/image-source";
22
import { MLKitVisionOptions, } from "../";
3+
import { MLKitScanBarcodesResultBounds } from "../barcodescanning";
34
import { MLKitObjectDetectionOptions, MLKitObjectDetectionResult, MLKitObjectDetectionResultItem } from "./";
45
import { MLKitObjectDetection as MLKitObjectDetectionBase, ObjectDetectionCategory } from "./objectdetection-common";
56

@@ -22,9 +23,11 @@ export class MLKitObjectDetection extends MLKitObjectDetectionBase {
2223
objects: []
2324
};
2425

26+
const image: android.graphics.Bitmap = this.lastVisionImage && this.lastVisionImage.getBitmap ? this.lastVisionImage.getBitmap() : null;
27+
2528
// see https://github.com/firebase/quickstart-android/blob/0f4c86877fc5f771cac95797dffa8bd026dd9dc7/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/textrecognition/TextRecognitionProcessor.java#L62
2629
for (let i = 0; i < objects.size(); i++) {
27-
result.objects.push(getMLKitObjectDetectionResultItem(objects.get(i)));
30+
result.objects.push(getMLKitObjectDetectionResultItem(objects.get(i), image));
2831
}
2932

3033
this.notify({
@@ -57,6 +60,9 @@ export function detectObjects(options: MLKitObjectDetectionOptions): Promise<MLK
5760
try {
5861
const firebaseObjectDetector = getDetector(options.classify, options.multiple);
5962

63+
const image: android.graphics.Bitmap = options.image instanceof ImageSource ? options.image.android : options.image.imageSource.android;
64+
const firImage = com.google.firebase.ml.vision.common.FirebaseVisionImage.fromBitmap(image);
65+
6066
const onSuccessListener = new com.google.android.gms.tasks.OnSuccessListener({
6167
onSuccess: objects => {
6268
const result = <MLKitObjectDetectionResult>{
@@ -65,7 +71,7 @@ export function detectObjects(options: MLKitObjectDetectionOptions): Promise<MLK
6571

6672
if (objects) {
6773
for (let i = 0; i < objects.size(); i++) {
68-
result.objects.push(getMLKitObjectDetectionResultItem(objects.get(i)));
74+
result.objects.push(getMLKitObjectDetectionResultItem(objects.get(i), image));
6975
}
7076
}
7177

@@ -79,7 +85,7 @@ export function detectObjects(options: MLKitObjectDetectionOptions): Promise<MLK
7985
});
8086

8187
firebaseObjectDetector
82-
.processImage(getImage(options))
88+
.processImage(firImage)
8389
.addOnSuccessListener(onSuccessListener)
8490
.addOnFailureListener(onFailureListener);
8591

@@ -90,18 +96,33 @@ export function detectObjects(options: MLKitObjectDetectionOptions): Promise<MLK
9096
});
9197
}
9298

93-
function getMLKitObjectDetectionResultItem(obj: com.google.firebase.ml.vision.objects.FirebaseVisionObject): MLKitObjectDetectionResultItem {
99+
function getMLKitObjectDetectionResultItem(obj: com.google.firebase.ml.vision.objects.FirebaseVisionObject, image: android.graphics.Bitmap): MLKitObjectDetectionResultItem {
94100
return {
95101
id: obj.getTrackingId() ? obj.getTrackingId().intValue() : undefined,
96102
confidence: obj.getClassificationConfidence() ? obj.getClassificationConfidence().doubleValue() : undefined,
97103
category: ObjectDetectionCategory[obj.getClassificationCategory()],
98-
// TODO
99-
image: undefined,
100-
bounds: undefined
104+
bounds: boundingBoxToBounds(obj.getBoundingBox()),
105+
image: !image ? null : {
106+
width: image.getWidth(),
107+
height: image.getHeight()
108+
}
101109
};
102110
}
103111

104112
function getImage(options: MLKitVisionOptions): any /* com.google.firebase.ml.vision.common.FirebaseVisionImage */ {
105113
const image: android.graphics.Bitmap = options.image instanceof ImageSource ? options.image.android : options.image.imageSource.android;
106114
return com.google.firebase.ml.vision.common.FirebaseVisionImage.fromBitmap(image);
107115
}
116+
117+
function boundingBoxToBounds(rect: any): MLKitScanBarcodesResultBounds {
118+
return {
119+
origin: {
120+
x: rect.left,
121+
y: rect.top
122+
},
123+
size: {
124+
width: rect.width(),
125+
height: rect.height()
126+
}
127+
};
128+
}

0 commit comments

Comments
 (0)