Build an ACAP application that consume scene metadata
This guide provides steps on how to build a simple ACAP application that consumes Fusion Tracker output and/or Track Summary output scene metadata using the Message Broker API.
Prerequisites
- An Axis device that supports AXIS Scene Metadata.
- Docker
- For Windows and macOS, use the automatically upgradable Docker desktop stable.
- For Linux, use Docker Engine version 23.0.0 or later.
- Git
Overview
The guide contains the following steps:
- Cloning the ACAP Native SDK Examples repository containing the application source code
- Build the application
- Install and start the application
Lets get started!
Step 1: Cloning the repository
Execute the following command from a Git terminal to clone the repository containing the ACAP Native SDK Examples.
git clone https://github.com/AxisCommunications/acap-native-sdk-examples.git
Navigate to the message-broker > consume-scene-metadata folder where you should be able to find a directory called app. That directory contains the consume_scene_metadata.c application source code which can be compiled and run on the target device.
Step 2: Build the application
Standing in your working directory run the following commands:
Depending on the network your local build machine is connected to, you may need to add proxy settings for Docker. See Proxy in build time.
docker build --tag <APP_IMAGE> .
APP_IMAGE is the name to tag the image with, e.g., consume_scene_metadata:1.0
Default architecture is armv7hf. To build for aarch64 it's possible to update the ARCH variable in the Dockerfile or to set it in the docker build command via build argument:
docker build --build-arg ARCH=aarch64 --tag <APP_IMAGE> .
Copy the result from the container image to a local directory build:
docker cp $(docker create <APP_IMAGE>):/opt/app ./build
The working directory now contains a build folder with the following files:
consume-scene-metadata
├── app
│ ├── LICENSE
│ ├── Makefile
│ ├── manifest.json
│ └── consume_scene_metadata.c
├── build
│ ├── LICENSE
│ ├── Makefile
│ ├── manifest.json
│ ├── package.conf
│ ├── param.conf
│ ├── consume_scene_metadata*
│ ├── consume_scene_metadata_1_0_0_armv7hf.eap
│ ├── consume_scene_metadata_1_0_0_LICENSE.txt
│ └── consume_scene_metadata.c
├── Dockerfile
└── README.md
- build/manifest.json - Defines the application and its configuration.
- build/package.conf - Defines the application and its configuration.
- build/param.conf - File containing application parameters.
- build/consume_scene_metadata* - Application executable binary file.
- build/consume_scene_metadata_1_0_0_armv7hf.eap - Application package .eap file.
- build/consume_scene_metadata_1_0_0_LICENSE.txt - Copy of LICENSE file.
Step 3: Install and start the application
Browse to the application page of the Axis device:
http://<AXIS_DEVICE_IP>/index.html#apps
- Click on the tab Apps in the device GUI
- Enable Allow unsigned apps toggle
- Click (+ Add app) button to upload the application file
- Browse to the newly built ACAP application, depending on architecture:
consume_scene_metadata_1_0_0_aarch64.eap
consume_scene_metadata_1_0_0_armv7hf.eap
- Click Install
- Run the application by enabling the Start switch
Inspect the generated output
The application log can be found at
http://<AXIS_DEVICE_IP>/axis-cgi/admin/systemlog.cgi?appname=consume_scene_metadata
----- Contents of SYSTEM_LOG for 'consume_scene_metadata' -----
consume_scene_metadata[3844]: Subscribed to com.axis.analytics_scene_description.v0.beta (1)...
consume_scene_metadata[3844]: Subscriber started...
consume_scene_metadata[3844]: message received from topic: com.axis.analytics_scene_description.v0.beta on source: 1: Monotonic time - 483.054847000. Data - {"frame":{"observations":[{"bounding_box":{"bottom":0.7384,"left":0.4254,"right":0.7552,"top":0.4216},"class":{"score":0.74,"type":"Car"},"timestamp":"2024-02-14T15:37:20.940582Z","track_id":"25"},{"bounding_box":{"bottom":0.9431,"left":0.9656,"right":0.9989,"top":0.8384},"timestamp":"2024-02-14T15:37:20.940582Z","track_id":"26"},{"bounding_box":{"bottom":0.8378,"left":0.8102,"right":0.9693,"top":0.1988},"class":{"score":0.75,"type":"Human"},"timestamp":"2024-02-14T15:37:20.940582Z","track_id":"37"},{"bounding_box":{"bottom":0.0553,"left":0.727,"right":0.7499,"top":0.0443},"timestamp":"2024-02-14T15:37:20.940582Z","track_id":"44"},{"bounding_box":{"bottom":0.7997,"left":0.9833,"right":0.9989,"top":0.7262},"timestamp":"2024-02-14T15:37:20.940582Z","track_id":"45"},{"bounding_box":{"bottom":0.9689,"left":0.0208,"right":0.6354,"top":0.002},"timestamp":"2024-02-14T15:37:20.940582Z","track_id":"46"},{"bounding_box":{"bottom":0.3236,"left":0.7083,"right":0.8041,"top":0.0994},"timestamp":"2024-02-14T15:37:20.940582Z","track_id":"48"}],"operations":[],"timestamp":"2024-02-14T15:37:20.940582Z"}}
consume_scene_metadata[3844]: message received from topic: com.axis.analytics_scene_description.v0.beta on source: 1: Monotonic time - 483.154843000. Data - {"frame":{"observations":[{"bounding_box":{"bottom":0.7413,"left":0.4396,"right":0.7661,"top":0.4234},"class":{"score":0.74,"type":"Car"},"timestamp":"2024-02-14T15:37:21.040577Z","track_id":"25"},{"bounding_box":{"bottom":0.9431,"left":0.9656,"right":0.9989,"top":0.8365},"timestamp":"2024-02-14T15:37:21.040577Z","track_id":"26"},{"bounding_box":{"bottom":0.839,"left":0.8295,"right":0.9782,"top":0.2037},"class":{"score":0.75,"type":"Human"},"timestamp":"2024-02-14T15:37:21.040577Z","track_id":"37"},{"bounding_box":{"bottom":0.9395,"left":0.0219,"right":0.6531,"top":0.002},"timestamp":"2024-02-14T15:37:21.040577Z","track_id":"46"},{"bounding_box":{"bottom":0.3181,"left":0.7094,"right":0.8114,"top":0.1012},"timestamp":"2024-02-14T15:37:21.040577Z","track_id":"48"}],"operations":[{"id":"35","type":"DeleteOperation"},{"id":"47","type":"DeleteOperation"}],"timestamp":"2024-02-14T15:37:21.040577Z"}}
The format of a detection is shown in a more readable way.
{
"frame" : {
"observations" : [
{
"bounding_box" : {
"bottom" : 0.7413,
"left" : 0.4396,
"right" : 0.7661,
"top" : 0.4234
},
"class" : {
"score" : 0.74,
"type" : "Car"
},
"timestamp" : "2024-02-14T15:37:21.040577Z",
"track_id" : "25"
},
{
"bounding_box" : {
"bottom" : 0.9431,
"left" : 0.9656,
"right" : 0.9989,
"top" : 0.8365
},
"timestamp" : "2024-02-14T15:37:21.040577Z",
"track_id" : "26"
},
{
"bounding_box" : {
"bottom" : 0.839,
"left" : 0.8295,
"right" : 0.9782,
"top" : 0.2037
},
"class" : {
"score" : 0.75,
"type" : "Human"
},
"timestamp" : "2024-02-14T15:37:21.040577Z",
"track_id" : "37"
},
{
"bounding_box" : {
"bottom" : 0.9395,
"left" : 0.0219,
"right" : 0.6531,
"top" : 0.002
},
"timestamp" : "2024-02-14T15:37:21.040577Z",
"track_id" : "46"
},
{
"bounding_box" : {
"bottom" : 0.3181,
"left" : 0.7094,
"right" : 0.8114,
"top" : 0.1012
},
"timestamp" : "2024-02-14T15:37:21.040577Z",
"track_id" : "48"
}
],
"operations" : [
{
"id" : "35",
"type" : "DeleteOperation"
},
{
"id" : "47",
"type" : "DeleteOperation"
}
],
"timestamp" : "2024-02-14T15:37:21.040577Z"
}
}
The application outputs the result of Fusion Tracker module for source 1
.
The source represents the origin of the data.
In this case a module instance of the Fusion tracker module corresponding to the video source that the instance uses as input.
If you want the output from another instance of the Fusion Tracker module you will need to change the source parameter accordingly.
If working with a multidirectional camera, 2
, 3
and 4
might also be available.
If you would like to consume Track Summary output instead, you would need to modify the topic specified in the application source code file to com.axis.consolidated_track.v1.beta
and specify the source parameter accordingly.