Skip to content

Commit 6e1cfeb

Browse files
committed
created a multi-tracker vision demo
This app creates both a face detector and a barcode detector, and uses two different types of trackers/graphics to show the result of detecting faces and/or barcodes. Change-Id: Ie4c5193e218bd72a26f7e94dad226d33a963dd0d
1 parent 1d3ef76 commit 6e1cfeb

22 files changed

+1271
-0
lines changed

face/multi-tracker/.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.gradle
2+
/local.properties
3+
/.idea/workspace.xml
4+
/.idea/libraries
5+
.DS_Store
6+
/build
7+
/captures

face/multi-tracker/app/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

face/multi-tracker/app/build.gradle

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
apply plugin: 'com.android.application'
2+
3+
android {
4+
compileSdkVersion 22
5+
buildToolsVersion "22.0.1"
6+
7+
defaultConfig {
8+
applicationId "com.google.android.gms.samples.vision.face.multitracker"
9+
minSdkVersion 21
10+
targetSdkVersion 22
11+
versionCode 1
12+
versionName "1.0"
13+
}
14+
buildTypes {
15+
release {
16+
minifyEnabled false
17+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18+
}
19+
}
20+
}
21+
22+
dependencies {
23+
compile fileTree(dir: 'libs', include: ['*.jar'])
24+
compile 'com.android.support:appcompat-v7:22.2.0'
25+
compile 'com.google.android.gms:play-services:7.8.+'
26+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Add project specific ProGuard rules here.
2+
# By default, the flags in this file are appended to flags specified
3+
# in /usr/local/google/home/wilkinsonclay/android/adt-bundle-linux-x86_64-20140702/sdk/tools/proguard/proguard-android.txt
4+
# You can edit the include path and order by changing the proguardFiles
5+
# directive in build.gradle.
6+
#
7+
# For more details, see
8+
# http://developer.android.com/guide/developing/tools/proguard.html
9+
10+
# Add any project specific keep options here:
11+
12+
# If your project uses WebView with JS, uncomment the following
13+
# and specify the fully qualified class name to the JavaScript interface
14+
# class:
15+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16+
# public *;
17+
#}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.google.android.gms.samples.vision.face.multitracker"
4+
android:installLocation="auto"
5+
android:versionCode="1"
6+
android:versionName="1">
7+
8+
<uses-feature android:name="android.hardware.camera" />
9+
10+
<uses-permission android:name="android.permission.CAMERA" />
11+
12+
<uses-sdk
13+
android:minSdkVersion="21"
14+
android:targetSdkVersion="21" />
15+
16+
<application
17+
android:allowBackup="true"
18+
android:hardwareAccelerated="true"
19+
android:icon="@drawable/icon"
20+
android:label="MultiTrackerApp">
21+
22+
<meta-data
23+
android:name="com.google.android.gms.vision.DEPENDENCIES"
24+
android:value="barcode,face" />
25+
26+
<activity
27+
android:name="com.google.android.gms.samples.vision.face.multitracker.MultiTrackerActivity"
28+
android:icon="@drawable/icon"
29+
android:label="Multi-Tracker"
30+
android:theme="@android:style/Theme.Black.NoTitleBar"
31+
android:screenOrientation="fullSensor">
32+
<intent-filter>
33+
<action android:name="android.intent.action.MAIN" />
34+
35+
<category android:name="android.intent.category.LAUNCHER" />
36+
</intent-filter>
37+
</activity>
38+
</application>
39+
40+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright (C) The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.android.gms.samples.vision.face.multitracker;
17+
18+
import android.graphics.Canvas;
19+
import android.graphics.Color;
20+
import android.graphics.Paint;
21+
import android.graphics.RectF;
22+
23+
import com.google.android.gms.samples.vision.face.multitracker.ui.camera.GraphicOverlay;
24+
import com.google.android.gms.vision.MultiProcessor;
25+
import com.google.android.gms.vision.Tracker;
26+
import com.google.android.gms.vision.barcode.Barcode;
27+
28+
/**
29+
* Factory for creating a tracker and associated graphic to be associated with a new barcode. The
30+
* multi-processor uses this factory to create barcode trackers as needed -- one for each barcode.
31+
*/
32+
class BarcodeTrackerFactory implements MultiProcessor.Factory<Barcode> {
33+
private GraphicOverlay mGraphicOverlay;
34+
35+
BarcodeTrackerFactory(GraphicOverlay graphicOverlay) {
36+
mGraphicOverlay = graphicOverlay;
37+
}
38+
39+
@Override
40+
public Tracker<Barcode> create(Barcode barcode) {
41+
BarcodeGraphic graphic = new BarcodeGraphic(mGraphicOverlay);
42+
return new GraphicTracker<>(mGraphicOverlay, graphic);
43+
}
44+
}
45+
46+
/**
47+
* Graphic instance for rendering barcode position, size, and ID within an associated graphic
48+
* overlay view.
49+
*/
50+
class BarcodeGraphic extends TrackedGraphic<Barcode> {
51+
private static final int COLOR_CHOICES[] = {
52+
Color.BLUE,
53+
Color.CYAN,
54+
Color.GREEN
55+
};
56+
private static int mCurrentColorIndex = 0;
57+
58+
private Paint mRectPaint;
59+
private Paint mTextPaint;
60+
private volatile Barcode mBarcode;
61+
62+
BarcodeGraphic(GraphicOverlay overlay) {
63+
super(overlay);
64+
65+
mCurrentColorIndex = (mCurrentColorIndex + 1) % COLOR_CHOICES.length;
66+
final int selectedColor = COLOR_CHOICES[mCurrentColorIndex];
67+
68+
mRectPaint = new Paint();
69+
mRectPaint.setColor(selectedColor);
70+
mRectPaint.setStyle(Paint.Style.STROKE);
71+
mRectPaint.setStrokeWidth(4.0f);
72+
73+
mTextPaint = new Paint();
74+
mTextPaint.setColor(selectedColor);
75+
mTextPaint.setTextSize(36.0f);
76+
}
77+
78+
/**
79+
* Updates the barcode instance from the detection of the most recent frame. Invalidates the
80+
* relevant portions of the overlay to trigger a redraw.
81+
*/
82+
void updateItem(Barcode barcode) {
83+
mBarcode = barcode;
84+
postInvalidate();
85+
}
86+
87+
/**
88+
* Draws the barcode annotations for position, size, and raw value on the supplied canvas.
89+
*/
90+
@Override
91+
public void draw(Canvas canvas) {
92+
Barcode barcode = mBarcode;
93+
if (barcode == null) {
94+
return;
95+
}
96+
97+
// Draws the bounding box around the barcode.
98+
RectF rect = new RectF(barcode.getBoundingBox());
99+
rect.left = translateX(rect.left);
100+
rect.top = translateY(rect.top);
101+
rect.right = translateX(rect.right);
102+
rect.bottom = translateY(rect.bottom);
103+
canvas.drawRect(rect, mRectPaint);
104+
105+
// Draws a label at the bottom of the barcode indicate the barcode value that was detected.
106+
canvas.drawText(barcode.rawValue, rect.left, rect.bottom, mTextPaint);
107+
}
108+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright (C) The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.android.gms.samples.vision.face.multitracker;
17+
18+
import android.graphics.Canvas;
19+
import android.graphics.Color;
20+
import android.graphics.Paint;
21+
22+
import com.google.android.gms.vision.MultiProcessor;
23+
import com.google.android.gms.vision.Tracker;
24+
import com.google.android.gms.vision.face.Face;
25+
import com.google.android.gms.samples.vision.face.multitracker.ui.camera.GraphicOverlay;
26+
27+
/**
28+
* Factory for creating a tracker and associated graphic to be associated with a new face. The
29+
* multi-processor uses this factory to create face trackers as needed -- one for each individual.
30+
*/
31+
class FaceTrackerFactory implements MultiProcessor.Factory<Face> {
32+
private GraphicOverlay mGraphicOverlay;
33+
34+
FaceTrackerFactory(GraphicOverlay graphicOverlay) {
35+
mGraphicOverlay = graphicOverlay;
36+
}
37+
38+
@Override
39+
public Tracker<Face> create(Face face) {
40+
FaceGraphic graphic = new FaceGraphic(mGraphicOverlay);
41+
return new GraphicTracker<>(mGraphicOverlay, graphic);
42+
}
43+
}
44+
45+
/**
46+
* Graphic instance for rendering face position, size, and ID within an associated graphic overlay
47+
* view.
48+
*/
49+
class FaceGraphic extends TrackedGraphic<Face> {
50+
private static final float FACE_POSITION_RADIUS = 10.0f;
51+
private static final float ID_TEXT_SIZE = 40.0f;
52+
private static final float ID_Y_OFFSET = 50.0f;
53+
private static final float ID_X_OFFSET = -50.0f;
54+
private static final float BOX_STROKE_WIDTH = 5.0f;
55+
56+
private static final int COLOR_CHOICES[] = {
57+
Color.MAGENTA,
58+
Color.RED,
59+
Color.YELLOW
60+
};
61+
private static int mCurrentColorIndex = 0;
62+
63+
private Paint mFacePositionPaint;
64+
private Paint mIdPaint;
65+
private Paint mBoxPaint;
66+
67+
private volatile Face mFace;
68+
69+
FaceGraphic(GraphicOverlay overlay) {
70+
super(overlay);
71+
72+
mCurrentColorIndex = (mCurrentColorIndex + 1) % COLOR_CHOICES.length;
73+
final int selectedColor = COLOR_CHOICES[mCurrentColorIndex];
74+
75+
mFacePositionPaint = new Paint();
76+
mFacePositionPaint.setColor(selectedColor);
77+
78+
mIdPaint = new Paint();
79+
mIdPaint.setColor(selectedColor);
80+
mIdPaint.setTextSize(ID_TEXT_SIZE);
81+
82+
mBoxPaint = new Paint();
83+
mBoxPaint.setColor(selectedColor);
84+
mBoxPaint.setStyle(Paint.Style.STROKE);
85+
mBoxPaint.setStrokeWidth(BOX_STROKE_WIDTH);
86+
}
87+
88+
/**
89+
* Updates the face instance from the detection of the most recent frame. Invalidates the
90+
* relevant portions of the overlay to trigger a redraw.
91+
*/
92+
void updateItem(Face face) {
93+
mFace = face;
94+
postInvalidate();
95+
}
96+
97+
/**
98+
* Draws the face annotations for position, size, and ID on the supplied canvas.
99+
*/
100+
@Override
101+
public void draw(Canvas canvas) {
102+
Face face = mFace;
103+
if (face == null) {
104+
return;
105+
}
106+
107+
// Draws a circle at the position of the detected face, with the face's track id below.
108+
float cx = translateX(face.getPosition().x + face.getWidth() / 2);
109+
float cy = translateY(face.getPosition().y + face.getHeight() / 2);
110+
canvas.drawCircle(cx, cy, FACE_POSITION_RADIUS, mFacePositionPaint);
111+
canvas.drawText("id: " + getId(), cx + ID_X_OFFSET, cy + ID_Y_OFFSET, mIdPaint);
112+
113+
// Draws an oval around the face.
114+
float xOffset = scaleX(face.getWidth() / 2.0f);
115+
float yOffset = scaleY(face.getHeight() / 2.0f);
116+
float left = cx - xOffset;
117+
float top = cy - yOffset;
118+
float right = cx + xOffset;
119+
float bottom = cy + yOffset;
120+
canvas.drawOval(left, top, right, bottom, mBoxPaint);
121+
}
122+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (C) The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.android.gms.samples.vision.face.multitracker;
17+
18+
import com.google.android.gms.samples.vision.face.multitracker.ui.camera.GraphicOverlay;
19+
import com.google.android.gms.vision.Detector;
20+
import com.google.android.gms.vision.Tracker;
21+
22+
/**
23+
* Generic tracker which is used for tracking either a face or a barcode (and can really be used for
24+
* any type of item). This is used to receive newly detected items, add a graphical representation
25+
* to an overlay, update the graphics as the item changes, and remove the graphics when the item
26+
* goes away.
27+
*/
28+
class GraphicTracker<T> extends Tracker<T> {
29+
private GraphicOverlay mOverlay;
30+
private TrackedGraphic<T> mGraphic;
31+
32+
GraphicTracker(GraphicOverlay overlay, TrackedGraphic<T> graphic) {
33+
mOverlay = overlay;
34+
mGraphic = graphic;
35+
}
36+
37+
/**
38+
* Start tracking the detected item instance within the item overlay.
39+
*/
40+
@Override
41+
public void onNewItem(int id, T item) {
42+
mGraphic.setId(id);
43+
mOverlay.add(mGraphic);
44+
}
45+
46+
/**
47+
* Update the position/characteristics of the item within the overlay.
48+
*/
49+
@Override
50+
public void onUpdate(Detector.Detections<T> detectionResults, T item) {
51+
mGraphic.updateItem(item);
52+
}
53+
54+
/**
55+
* Called when the item is assumed to be gone for good. Remove the graphic annotation from
56+
* the overlay.
57+
*/
58+
@Override
59+
public void onDone() {
60+
mOverlay.remove(mGraphic);
61+
}
62+
}

0 commit comments

Comments
 (0)