Skip to content

Commit c3ff523

Browse files
author
Angelo DelliSanti
committed
Use GPRC/ACAP Runtime to capture video frames
Change-Id: I9d69abe9b5ff9c9edb03e77cbf96362f3153556a
1 parent d879fe9 commit c3ff523

25 files changed

Lines changed: 103 additions & 90 deletions

File tree

hello-world-python/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
ARG ARCH=armv7hf
44
ARG REPO=axisecp
5-
ARG SDK_VERSION=1.12
5+
ARG SDK_VERSION=1.13
66
ARG UBUNTU_VERSION=22.04
77

88
FROM arm32v7/ubuntu:${UBUNTU_VERSION} as runtime-image-armv7hf

hello-world-python/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ Meet the following requirements to ensure compatibility with the example:
2929

3030
* Axis device
3131
* Chip: ARTPEC-{7-8} DLPU devices (e.g., Q1615 MkIII)
32-
* Firmware: 10.9 or higher
33-
* [Docker ACAP](https://github.com/AxisCommunications/docker-acap#installing) installed and started, using TLS and SD card as storage
32+
* Firmware: 11.10 or higher
33+
* [Docker ACAP](https://github.com/AxisCommunications/docker-acap#installing) version 3.0 installed and started, using TLS with TCP and IPC socket and SD card as storage
3434
* Computer
3535
* Either [Docker Desktop](https://docs.docker.com/desktop/) version 4.11.1 or higher,
3636
* or [Docker Engine](https://docs.docker.com/engine/) version 20.10.17 or higher with BuildKit enabled using Docker Compose version 1.29.2 or higher

minimal-ml-inference/Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
ARG ARCH=armv7hf
44
ARG REPO=axisecp
5-
ARG SDK_VERSION=1.12
5+
ARG SDK_VERSION=1.13
66
ARG UBUNTU_VERSION=22.04
77

88
FROM arm32v7/ubuntu:${UBUNTU_VERSION} as runtime-image-armv7hf
@@ -17,11 +17,12 @@ FROM runtime-image-${ARCH}
1717
# Get packages from the CV SDK
1818
COPY --from=cv-sdk /axis/python /
1919
COPY --from=cv-sdk /axis/python-tfserving /
20+
COPY --from=cv-sdk /axis/python-vdoproto /
2021
COPY --from=cv-sdk /axis/python-numpy /
2122
COPY --from=cv-sdk /axis/opencv /
2223
COPY --from=cv-sdk /axis/openblas /
2324

2425
# Copy the application script to the container
2526
WORKDIR /app
2627
COPY simple_inference.py .
27-
ENTRYPOINT ["python3", "simple_inference.py"]
28+
CMD ["python3", "simple_inference.py"]

minimal-ml-inference/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This example demonstrates how to create a simple Python application that perform
88

99
This example composes three different container images into an application that performs an inference using a deep learning model.
1010

11-
The first container contains the actual program built in this example. It uses [OpenCV](https://opencv.org/) to capture pictures from the camera and modifies them to fit the input required by the model. It then uses [gRPC](https://grpc.io/)/[protobuf](https://developers.google.com/protocol-buffers) to call the second container, the *inference-server*, that performs the actual inference by implementing the [TensorFlow Serving API](https://github.com/tensorflow/serving). You can find more documentation on the [Machine Learning API documentation page](https://axiscommunications.github.io/acap-documentation/docs/api/computer-vision-sdk-apis.html#machine-learning-api). This example uses a containerized version of the [ACAP Runtime](https://github.com/AxisCommunications/acap-runtime#containerized-version) as the *inference-server*.
11+
The first container contains the actual program built in this example. It then uses [gRPC](https://grpc.io/)/[protobuf](https://developers.google.com/protocol-buffers) to call the second container, the *inference-server*, that is used to capture images from the camera and perform the actual inference by implementing the [TensorFlow Serving API](https://github.com/tensorflow/serving). You can find more documentation on the [Machine Learning API documentation page](https://axiscommunications.github.io/acap-documentation/docs/api/computer-vision-sdk-apis.html#machine-learning-api). This example uses a containerized version of the [ACAP Runtime](https://github.com/AxisCommunications/acap-runtime#containerized-version) as the *inference-server*.
1212

1313
Lastly, there is a third container that holds the deep learning model, which is put into a volume that is accessible by the other two images. The layout of the Docker image containing the model is shown below. The *MODEL_PATH* variable in the configuration file you're using specifies what model to use. By default, the armv7hf configuration file uses the edgetpu model, while the aarch64 configuration file uses the vanilla model.
1414

@@ -47,8 +47,8 @@ Meet the following requirements to ensure compatibility with the example:
4747

4848
* Axis device
4949
* Chip: ARTPEC-{7-8} DLPU devices (e.g., Q1615 MkIII)
50-
* Firmware: 10.9 or higher
51-
* [Docker ACAP](https://github.com/AxisCommunications/docker-acap#installing) installed and started, using TLS and SD card as storage
50+
* Firmware: 11.10 or higher
51+
* [Docker ACAP](https://github.com/AxisCommunications/docker-acap#installing) version 3.0 installed and started, using TLS with TCP and IPC socket and SD card as storage
5252
* Computer
5353
* Either [Docker Desktop](https://docs.docker.com/desktop/) version 4.11.1 or higher,
5454
* or [Docker Engine](https://docs.docker.com/engine/) version 20.10.17 or higher with BuildKit enabled using Docker Compose version 1.29.2 or higher
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
MODEL_PATH=/models/ssd_mobilenet_v2_coco_quant_postprocess.tflite
22
INFERENCE_SERVER_IMAGE=axisecp/acap-runtime:1.3.1-aarch64-containerized
3-
INFERENCE_CHIP=12
3+
INFERENCE_CHIP=12
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
MODEL_PATH=/models/ssd_mobilenet_v2_coco_quant_postprocess.tflite
22
INFERENCE_SERVER_IMAGE=axisecp/acap-runtime:1.3.1-aarch64-containerized
3-
INFERENCE_CHIP=2
3+
INFERENCE_CHIP=2
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
MODEL_PATH=/models/ssd_mobilenet_v2_coco_quant_postprocess.tflite
22
INFERENCE_SERVER_IMAGE=axisecp/acap-runtime:1.3.1-armv7hf-containerized
3-
INFERENCE_CHIP=2
3+
INFERENCE_CHIP=2
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
MODEL_PATH=/models/ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite
22
INFERENCE_SERVER_IMAGE=axisecp/acap-runtime:1.3.1-armv7hf-containerized
3-
INFERENCE_CHIP=4
3+
INFERENCE_CHIP=4

minimal-ml-inference/docker-compose.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@ services:
88
- INFERENCE_PORT=0
99
- MODEL_PATH=${MODEL_PATH}
1010
volumes:
11-
- /usr/lib/libvdostream.so.1:/usr/lib/libvdostream.so.1
1211
- acap_dl-models:/models:ro
1312
- /tmp:/output
14-
- /var/run/dbus:/var/run/dbus:rw
1513
- inference-server:/tmp
1614

1715
inference-server:
@@ -37,4 +35,4 @@ services:
3735

3836
volumes:
3937
acap_dl-models: {}
40-
inference-server: {}
38+
inference-server: {}

minimal-ml-inference/simple_inference.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
import os
2-
import cv2
32
import numpy as np
4-
53
from tf_proto_utils import InferenceClient
4+
from vdo_proto_utils import VideoCaptureClient
65

7-
# Create the inference client with model and socket from environment variables
8-
inf_client = InferenceClient(os.environ['INFERENCE_HOST'])
96

10-
# Create a video stream that fits the model inputs
11-
cap = cv2.VideoCapture(0)
12-
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 300)
13-
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 300)
14-
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"RGB3"))
7+
grpc_socket = os.environ['INFERENCE_HOST']
8+
stream_width, stream_height, stream_framerate = (224, 224, 10)
9+
capture_client = VideoCaptureClient(socket=grpc_socket,
10+
stream_width=stream_width,
11+
stream_height=stream_height,
12+
stream_framerate=stream_framerate)
13+
inf_client = InferenceClient(grpc_socket)
1514

1615
# The capture -> inference loop
1716
while True:
1817
# Read an image from the video stream
19-
_, image = cap.read()
18+
image = capture_client.get_frame()
2019

21-
# Give the image a batch dimension such that it has the shape (1, H, W, C)
2220
image = np.expand_dims(image, axis=0)
2321

2422
# Perform inference with a model specified as an environment variable

0 commit comments

Comments
 (0)