Camera Client
Before diving into this code, here's a quick heads-up on what you'll need to be familiar with:
- Python Programming: It's important to have a good grasp of Python, especially with concepts
like
functions
,loops
, andclasses
, since the example utilizes these fundamentals. - Asynchronous Programming with asyncio: Familiarity with Python's asyncio for writing concurrent
code using the
async/await
syntax. - Image Processing with OpenCV: Basic knowledge of the OpenCV library for handling and manipulating
image data, including functions like
imdecode
,applyColorMap
, andimshow
. - farm-ng Oak Service Overview: This overview provides a base understanding of the gRPC service the client you create will connect to.
The Camera Client
example operates as a standalone Python script,
in which an EventClient
to an Oak camera service running on an Amiga brain is created.
The selected stream is displayed in a popup window.
To successfully run this example, you must use your local PC, as the example won't work if executed directly from a brain (because of the popup window). Ensure that a farm-ng brain running Oak cameras is active. Your local PC should be either connected to the same local network as the brain or linked to it through tailscale.
1. Install the farm-ng Brain ADK package
2. Install the example's dependencies
It is recommended to also install these dependencies and run the example in the brain ADK virtual environment.
# assuming you're already in the amiga-dev-kit/ directory
cd farm-ng-amiga/py/examples/camera_client
pip3 install -r requirements.txt
3. Execute the Python script
python3 main.py --service-config service_config.json
4. Customize the run
Since this example must be run from your local PC, you will need update the service_config.json
by modifying the host
field with your Amiga brain name.
Please check out Amiga Development 101 for more details.
python3 main.py --help
# usage: amiga-camera-stream [-h] --service-config SERVICE_CONFIG
#
# optional arguments:
# -h, --help show this help message and exit
# --service-config SERVICE_CONFIG
# The camera config.
Moreover, you can also stream the stereo left or right images or the camera's
disparity by changing the path
field (e.g., /left) in the service_config.json
file.
5. Code overview
In this example we use the EventClient
with the subscribe
method to receive the camera stream.
async def main(service_config_path: Path) -> None:
"""Run the camera service client.
Args:
service_config_path (Path): The path to the camera service config.
"""
# create a client to the camera service
config: EventServiceConfig = proto_from_json_file(service_config_path, EventServiceConfig())
# instantiate the image decoder
image_decoder = ImageDecoder()
async for event, message in EventClient(config).subscribe(config.subscriptions[0], decode=True):
print(f"Timestamps: {event.timestamps[-2]}")
print(f"Meta: {message.meta}")
print("###################\n")
# cast image data bytes to numpy and decode
image = np.from_dlpack(image_decoder.decode(message.image_data))
# visualize the image
cv2.namedWindow("image", cv2.WINDOW_NORMAL)
cv2.imshow("image", image)
cv2.waitKey(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(prog="amiga-camera-stream")
parser.add_argument("--service-config", type=Path, required=True, help="The camera config.")
args = parser.parse_args()
asyncio.run(main(args.service_config))
We highly recommend to have some basic knowledge about
asyncio
.