-
Notifications
You must be signed in to change notification settings - Fork 0
/
VuforiaCapture.java
111 lines (87 loc) · 3.76 KB
/
VuforiaCapture.java
1
2
3
4
5
6
7
8
9
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package org.firstinspires.ftc.teamcode;
import android.graphics.Bitmap;
import com.qualcomm.robotcore.util.RobotLog;
import org.firstinspires.ftc.robotcore.external.navigation.VuforiaLocalizer;
import java.util.concurrent.BlockingQueue;
/**
* This class provides a way to capture video images from the camera
* when using Vuforia. This allows you use the images for other purposes
* like streaming to a browser or processing with OpenCV.
*
* Vuforia must own the camera so if we want to do image
* processing alongside Vuforia, we have to get the images from Vuforia. Once
* Vuforia is configured create an instance of this class with the localizer
* object and then you can get images posted by Vuforia for external use.
* Note that this means the images change on Vuforia's schedule and that can
* be fairly slow. Even if you call for images rapidly, the image may not
* change for 10s of milliseconds. However testing shows adequate an refresh
* rate for useful video processing. This class uses a separate thread to
* monitor Vuforia for new images so the calling thread is not blocked
* waiting for a new image. This class works with web cams and phones.
*/
class VuforiaCapture
{
private static final String TAG = "VuforiaCapture";
private VuforiaLocalizer vuforia;
private BlockingQueue<VuforiaLocalizer.CloseableFrame> frameQueue;
private Bitmap currentImage;
private Object lock = new Object();
private MonitorVuforia monitorThread;
/**
* Constructor.
* @param vuforia Localizer object created by calling program.
*/
public VuforiaCapture(VuforiaLocalizer vuforia)
{
this.vuforia = vuforia;
}
/**
* Start capturing images from Vuforia. Call after your call
* to activate on the localizer object.
*/
public void startCapture()
{
vuforia.enableConvertFrameToBitmap();
vuforia.setFrameQueueCapacity(1);
frameQueue = vuforia.getFrameQueue();
monitorThread = new MonitorVuforia();
monitorThread.start();
RobotLog.v(TAG, "capture started");
}
/**
* Get the current (last posted) image from Vuforia. This image is
* updated by vuforia on its own schedule typically in the 10s of
* milliseconds.
* @return Camera image. Null if no image available.
*/
public Bitmap getImage()
{
synchronized (lock) { return currentImage; }
}
// Thread to monitor Vuforia for camera images passed through the blocking queue.
private class MonitorVuforia extends Thread
{
Bitmap newImage;
public void run()
{
try
{
while (true)
{
// Note that take() waits until there is something in the queue to take.
// This means this loop will iterate at the speed at which Vuforia updates
// the queue. The queue length of 1 assumes this loop will empty the queue
// as rapidly as Vuforia updates it. Vuforia returns frames which contain
// more than one image format so we extract the bitmap image from the frame.
// We copy the retrieved image so that is can be available to callers during
// the time this thread waits for a new image.
newImage = vuforia.convertFrameToBitmap(frameQueue.take());
synchronized (lock)
{
currentImage = newImage.copy(newImage.getConfig(), false);
}
}
} catch (Exception e) { e.printStackTrace(); }
}
}
}