Implement an Actcast application #
This tutorial is intended for ActcastOS 3 or later versions.
ActcastOS 1 and ActcastOS 2 will no longer be supported at the end of 2024.
Create an application that converts CSI camera video to grayscale and displays it. In this step, we will implement an Actcast application that converts the captured image to grayscale and displays it on the screen. For more details about each file, see also ActDK Project Structure.
The code for this tutorial is available at here.
Create a main
file under the app
directory, and paste the following code:
#!/usr/bin/python3
import numpy as np
from PIL import Image
import actfw_core
from actfw_core.task import Pipe, Consumer
from actfw_core.system import find_csi_camera_device
from actfw_core.unicam_isp_capture import UnicamIspCapture
from actfw_raspberrypi.vc4 import Display
# capture image size
(CAPTURE_WIDTH, CAPTURE_HEIGHT) = (320, 240)
# display area size
(DISPLAY_WIDTH, DISPLAY_HEIGHT) = (640, 480)
class Converter(Pipe):
"""Convert RGB camera image to grayscale image"""
def __init__(self, capture_size):
super(Converter, self).__init__()
self.capture_size = capture_size
def proc(self, frame):
rgb_image = Image.frombuffer(
"RGB", self.capture_size, frame.getvalue(), "raw", "RGB"
)
gray_image = rgb_image.convert("L")
return gray_image
class Presenter(Consumer):
"""Display grayscale image on preview window and take photo view"""
def __init__(self, preview_window, cmd):
super(Presenter, self).__init__()
self.preview_window = preview_window
self.cmd = cmd
def proc(self, gray_image):
# update `Take Photo` image
self.cmd.update_image(gray_image)
# if preview window is available, display grayscale image
if self.preview_window is not None:
# convert grayscale image to RGB image for display in preview window
gray_image = gray_image.convert("RGB")
self.preview_window.blit(np.asarray(gray_image).tobytes())
self.preview_window.update()
actfw_core.heartbeat()
def run(app, preview_window=None):
# CommandServer (for `Take Photo` command)
cmd = actfw_core.CommandServer()
app.register_task(cmd)
# register capture task
capture_size = (CAPTURE_WIDTH, CAPTURE_HEIGHT)
framerate = 30
device = find_csi_camera_device()
cap = UnicamIspCapture(unicam=device, size=capture_size, framerate=framerate)
app.register_task(cap)
# register converter task
conv = Converter(cap.capture_size())
app.register_task(conv)
# register presenter task
pres = Presenter(preview_window, cmd)
app.register_task(pres)
# Make task connection
cap.connect(conv) # from `cap` to `conv`
conv.connect(pres) # from `conv` to `pres`
# Start application
app.run()
def main():
# Actcast application
app = actfw_core.Application()
# Load act setting
settings = app.get_settings({"display": False})
if settings["display"]:
with Display() as display:
preview_area = (0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT)
capture_size = (CAPTURE_WIDTH, CAPTURE_HEIGHT)
layer = 16
with display.open_window(
preview_area, capture_size, layer
) as preview_window:
run(app, preview_window)
else:
run(app)
if __name__ == "__main__":
main()
Then, create a healthchecker
file under the app
directory, and paste the following code:
#!/bin/bash
HEARTBEAT_FILE='/root/heartbeat'
[ "$(find "${HEARTBEAT_FILE}" -mmin -1)" == "${HEARTBEAT_FILE}" ]
Then, in the apt
part of .actdk/dependencies.json
, add libv4l-0
and libv4lconvert0
used by actfw_core.unicam_isp_capture.UnicamIspCapture
, and main add
python3-numpy, which
main` depends on.
{
"apt": [
"libv4l-0",
"libv4lconvert0",
"python3",
"python3-pil",
"python3-numpy"
],
"pip": [],
"raspberrypi-bullseye": {
"apt": [
"libraspberrypi0"
],
"pip": [
"actfw-raspberrypi"
]
}
}
if you want to output the result to the display connected to the device, set setting_schema.json
as follows.
{
"$schema": "https://actcast.io/schema/v8/setting_schema_schema.json",
"type": "object",
"properties": {
"display": {
"title": "display",
"description": "display grayscale image",
"type": "boolean",
"default": false
}
},
"required": []
}
Then, run actdk generate act_settings
and set the generated act_settings.json
as follows.
{
"display": true
}
Next: Setup Actsim
Previous: Create a Project