QED Camera is an Android application conceived by Quantitative Engineering Design (QED.ai) that is designed to work with ODK Collect as an external application for data collection. It offers three modes (the first 2 are only accessible from the ODK Collect app, so their buttons on the front page of the app are disabled):
Multiple Photo Capture (only as integration with ODK Collect)
- Automatic Mode (Default): Captures photos at configurable intervals (e.g., every 5 seconds).
- Manual Mode: Allows users to manually take photos.
- Mode Switching: Users can switch between automatic and manual modes during an active session.
- Interval Adjustment: Users can change the interval between photos during an active session.
- Zoom: Allows users to zoom in and out while taking photos.
- Switching between cameras: Allows users to toggle between the default and wide-angle cameras for greater flexibility.
- Automatic Session Termination: Sessions automatically end when storage limits are reached (e.g., 2.4GB for a group of 10 placeholders, see below what a group is).
- Timed/Photo Count Limits: Sessions automatically terminate after reaching a specified time limit or photo count.
- Additional EXIF Data: Apart from the standard EXIF data, photos include also yaw, pitch, and roll stored in EXIF tag
UserComment. - Photo Compression: Photos can be compressed and converted to WebP format.
- Metadata about session: Can store in ODK form the number of taken photos and the duration of photo session.
- Supports packaging photos into bundles up to 240MB for seamless uploading to a server.
- Configurable parameters for flexible use cases.
QED Camera is initiated from ODK Collect via an intent-based configuration in the ODK form. The form must include a group of questions and use the intent column with the following structure:
ai.qed.camera(questionNamePrefix='part',maxNumberOfPackages='5',mode='automatic',captureInterval='3')
The integration relies on defining a group of questions rather than a single question that could be populated by an external app. This approach prevents the creation of a single, excessively large file by dividing the photos into smaller, manageable packages (up to 240MB each), as required by server limitations. It is the responsibility of the form designer to define a group with the appropriate number of questions (placeholders). For example, if a form contains 10 questions, it allows collecting up to 2.4GB of photos (10 x 240MB).
| type | name | label | intent | appearance |
|---|---|---|---|---|
| begin group | photos | ai.qed.camera(questionNamePrefix=’part’, maxNumberOfPackages=’5’, mode=’automatic’, captureInterval=’3’) | field-list | |
| integer | photoQuantity | Number of taken photos | ||
| integer | photoSessionDuration | Session duration | ||
| file | part1 | Part 1 | ||
| file | part2 | Part 2 | ||
| file | part3 | Part 3 | ||
| file | part4 | Part 4 | ||
| file | part5 | Part 5 | ||
| end group |
-
questionNamePrefix(Mandatory)- Specifies the prefix for question placeholders in the ODK form.
- Example: For questions named
part1,part2,part3, the prefix ispart. - Together with maxNumberOfPackages, this allows the camera application to determine the corresponding question in the ODK form to which the photo bundle should be assigned.
-
maxNumberOfPackages(Mandatory)- Specifies the number of placeholders defined in the group.
- Together with maxNumberOfPackages, this allows the camera application to determine the corresponding question in the ODK form to which the photo bundle should be assigned.
-
mode(Optional)- Specifies the mode of operation:
automaticormanual. - Default:
automatic.
- Specifies the mode of operation:
-
captureInterval(Optional)- Interval between photos in seconds (only applicable in
automaticmode). - Default: 5 seconds.
- Interval between photos in seconds (only applicable in
-
maxPhotoCount(Optional)- Limits the number of photos taken in a single session.
- Default: No limit.
-
maxSessionDuration(Optional)- Sets the maximum session duration in seconds.
- Default: No limit.
-
compressionLevel(Optional)- Sets the photo compression level. The three options are:
none(no compression),medium(compressed), andhigh(compressed and converted to WebP format). - Default:
medium.
- Sets the photo compression level. The three options are:
-
photoQuantityQuestionName(Optional)- Specifies the question name in the ODK form that should receive the number of taken photos.
- Default:
photoQuantity.
-
photoSessionDurationQuestionName(Optional)- Specifies the question name in the ODK form that should receive the session duration in seconds.
- Default:
photoSessionDuration.
-
Install ODK Collect and Camera Application
- Install ODK Collect and the camera application (QED Camera) on the device.
-
Create an ODK Form
- Define a group of questions with placeholders where you would like to store the result. In the intent column, specify the package name of the camera application along with the other parameters. This is necessary for launching the external camera application with the correct settings.
-
Run the ODK Form in Collect
- Start filling out your form.
- When the relevant section is reached, QED Camera will launch with the configured settings.
-
Capture Photos
- Depending on the mode (
automaticormanual), photos will be captured and packaged.
- Depending on the mode (
-
Return Data to ODK Collect
- Packages are sent back to their corresponding placeholders in the form.
The process of data collection involves one app (ODK Collect) launching another (QED Camera) to perform long-running sessions, which may last over an hour. Under certain conditions, the Android system may terminate the background app due to limited resources.
To reduce the risk of interruptions during long-running sessions, follow these steps:
-
Close Other Apps: Before starting the session, close any unnecessary apps running in the background to free up system resources.
-
Avoid Multitasking: During the session, avoid switching between applications or performing other memory-intensive tasks.
-
Avoid Frequent Screen Rotation: Try to avoid rotating the screen frequently during the session. Constant changes in screen orientation can affect performance and may result in resource reallocation, increasing the risk of session disruption.
After each photo is taken, it is compressed to save space (unless compression is disabled). The compression process can be quite demanding when the high option is selected, and depending on your device, it may take longer than the interval between photos. This means that photos will be taken faster than they can be compressed, and by the end of the session, you'll need to wait for the remaining photos to be compressed.
Depending on the length of the session, the device performance, and the interval between photos, the compression process may add anywhere from 1 to 5, 10, or even over 20 minutes (especially if thousands of photos were taken) to the finalization of the session.
Please be patient during the finalization process. A progress dialog will be displayed, so do not close the app or perform any unnecessary actions, just wait for the process to complete.
Code Scanner (only as integration with ODK Collect)
- Scanning Codes: Supports scanning all types of barcodes and QR codes.
- Code Preview Highlighting: Highlights the detected barcode in the preview during the scanning process, offering a clear visual cue when a barcode is successfully recognized.
- Zoom: Enables users to zoom in and out while scanning for better accuracy. The zoom ratio is remembered across scans, ensuring a consistent experience without resetting to the default.
- Tap to Focus: Enables users to tap on the camera preview to adjust focus, auto exposure (AE), and auto white balance (AWB) for improved scanning performance.
QED Camera is initiated from ODK Collect via an intent-based configuration in the ODK form. The form must include a text question and use the appearance column with the following structure:
ex:ai.qed.camera(codescanner=’true’)
The integration relies on Launching external apps to populate single fields.
| type | name | label | appearance |
|---|---|---|---|
| text | codeScanner | Code scanner | ex:ai.qed.camera(codescanner=’true’) |
codescanner(Mandatory)- Indicates that the scanner mode should be used.
-
Install ODK Collect and Camera Application
- Install ODK Collect and the camera application (QED Camera) on the device.
-
Create an ODK Form
- Define a text question where you would like store the scanned code. In the appearance column, specify the package name of the camera application along with the mode parameter.
-
Run the ODK Form in Collect
- Start filling out your form.
- When the relevant section is reached, QED Camera will launch the code scanner.
-
Scan Codes
- Once the code is scanned, the data is automatically sent back to ODK Collect.
GoPro Controller (accessible directly from the QED camera app)
- Pairing & Unpairing: Allows users to pair and unpair GoPro cameras, enabling seamless connection management for multi-camera setups.
- Preview Mode: Allows users to take test photos to verify camera positioning and alignment before starting the actual data capture process.
- Capture Mode: Enables automatic synchronized photo capture across multiple cameras at user-defined intervals (e.g., every few seconds).
- Connection Monitoring & Auto-Reconnect: Continuously monitors camera connection status and attempts automatic reconnection if a camera gets disconnected.
- Camera Status Display: Shows key camera information, including connection status, battery level, SD card capacity, and remaining storage space.
- Time synchronization between GoPro(s) and phone: The time is set in the GoPro over BLE, at two points: before preview photo and before starting capture session. It verifies itself by checking that time difference between camera and phone is under 1 second.
QED Camera is initiated from ODK Collect via an intent-based configuration in the ODK form. The form must include a text question and use the appearance column with the following structure:
ex:ai.qed.camera(app-mode=’gopro-capture’,captureInterval=’3’,lens=’wide’)
The integration relies on Launching external apps to populate single fields.
| type | name | label | appearance |
|---|---|---|---|
| text | preview | Preview | ex:ai.qed.camera(app-mode=’gopro-preview’,label1=’top’,label2=’bottom’,previewHint=’Please perform a detailed check of all cameras and gather necessary information’) |
| file | capture | Capture | ex:ai.qed.camera(app-mode=’gopro-capture’,captureInterval=’3’,lens=’wide’) |
app-mode(Mandatory)- Specifies the mode of operation:
gopro-previeworgopro-capture.
- Specifies the mode of operation:
previewHint(Optional)- A hint displayed to the user in Preview Mode to help them understand their task.
labelX(Mandatory)- Label names to be assigned to cameras in Preview Mode.
captureInterval(Optional)- Interval between photos in seconds. If not specified, the user will be prompted to choose from the available options after opening Capture Mode.
lens(Optional)- Specifies the lens used for taking photos in Capture Mode:
linearorwide. - Default:
linear.
- Specifies the lens used for taking photos in Capture Mode:
-
Install ODK Collect and Camera Application
- Install ODK Collect and the camera application (QED Camera) on the device.
-
Pair GoPro(s) with you phone
- Open the camera application and click
GoPro pairingbutton. - Scan for devices. Make sure that phone has Bluetooth enabled and GoPro is in pairing mode.
- To enter pairing mode on GoPro, just swipe from the top of the display down and one time to the right.
- You should find an option to pair with other devices, click it.
- Pair the phone with GoPro(s) using the camera app, not GoPro(s) clicking a button next to found GoPro name.
- Open the camera application and click
-
Create an ODK Form
- Define a text question or a file question where you would like to store the result. In the appearance column, specify the camera application's package name along with the required parameters. See examples above.
-
Run the ODK Form in Collect
- Start filling out your form.
- When the relevant section is reached, QED Camera will launch the appropriate mode (
gopro-previeworgopro-capture).
-
Collect data
- Depending on the mode, either a timestamp (for Preview Mode) or a file with collected metadata (for Capture Mode) is automatically sent back to ODK Collect. For Capture Mode the images are kept on GoPro and are not sent over to the phone.
Finishing the capture mode results in saving a ZIP file to the phone.
This file contains a ZIP file with the photos taken during the preview, as well as .properties files with session data for each camera in the following format:
# Camera session data
camera_with_label=GoPro 0932-top
camera_name=GoPro 0932
camera_ssid=MyCam1
serial_number=C3531324650932
camera_label=top
start_session_timestamp=1747272683517
end_session_timestamp=1747272722127
photo_groups=GPES, GPET
photo_interval=3.0
lens=wide
estimated_photos_number=6
app_version=2.1
version_code=5
- Minimum Android version: Android 10 (API level 29) is required due to new Bluetooth and Wi-Fi APIs introduced in Android 10. Supporting older versions is possible but:
- Would require separate code paths.
- Would rely on less stable and secure APIs.
- Supported GoPro camera: HERO13 Black
-
Problem: GoPro camera was previously paired but won’t reconnect automatically
Cause: After being powered off or after some time, the camera may not automatically reconnect, even if it was already paired.
Solution: To reconnect, you may need to manually activate pairing mode on the GoPro camera again. This reinitiates the Bluetooth connection process with your device.
Quantitative Engineering Design (QED.ai) develops AI-driven data collection and analysis tools to strengthen public health and agricultural systems. Our work focuses on sustainable technology deployment in resource-constrained environments to improve decision-making and outcomes at national scale.
This repository is licenced under Apache License, Version 2.0. See LICENCE for details.