Files
dora-image-view/examples/source.py
T
cristhian 00dc4c7b71 rename node to dora-image-view
The repository, the Python package, the entrypoint and the manifest name all
now agree. `plot` was carried over from the upstream opencv-plot node and no
longer described anything here, so the module, the class and the environment
variables follow the node:

  dora_plot/         -> dora_image_view/
  dora_plot/plot.py  -> dora_image_view/view.py
  Plot               -> View
  PLOT_WIDTH/HEIGHT  -> VIEW_WIDTH/HEIGHT
  --plot-width/-height -> --view-width/-height

Breaking for anyone wiring `path: dora-plot` or setting PLOT_WIDTH; nothing is
tagged yet.
2026-09-15 03:22:27 -03:00

74 lines
2.1 KiB
Python

"""Synthetic source node: this repository's stand-in for a camera and a detector.
Emits an animated frame, the box around the square moving in it, and a caption --
the three inputs dora-image-view draws -- so the example dataflow needs no camera, no
detector and no network.
"""
import os
import numpy as np
import pyarrow as pa
from dora import Node
WIDTH = int(os.getenv("SOURCE_WIDTH", "640"))
HEIGHT = int(os.getenv("SOURCE_HEIGHT", "480"))
# 0 runs until the viewer quits; a positive count is what lets CI run the
# dataflow to completion instead of killing it on a timeout.
FRAMES = int(os.getenv("SOURCE_FRAMES", "0"))
BOX = 96
SPEED = 6
CAPTION = "dora-image-view synthetic source"
def main() -> None:
"""Send one image, bbox and text per tick."""
node = Node("source")
sent = 0
for event in node:
if event["type"] != "INPUT":
continue
frame, corners = render(sent)
node.send_output(
"image",
pa.array(frame.ravel()),
{"width": WIDTH, "height": HEIGHT, "encoding": "bgr8"},
)
node.send_output(
"bbox",
pa.array([{
"bbox": corners,
"conf": np.array([0.99]),
"labels": np.array(["square"]),
}]),
{"format": "xyxy"},
)
node.send_output("text", pa.array([CAPTION]))
sent += 1
if FRAMES and sent >= FRAMES:
break
def render(index: int) -> tuple[np.ndarray, np.ndarray]:
"""Draw frame `index` and return it with the xyxy corners of the square in it."""
frame = np.zeros((HEIGHT, WIDTH, 3), dtype=np.uint8)
frame[:, :, 0] = np.linspace(40, 140, HEIGHT, dtype=np.uint8)[:, None]
travel = WIDTH - BOX
# A triangle wave over `index`: the square starts at the left edge, runs to
# the right edge, and comes back.
left = travel - abs((index * SPEED) % (2 * travel) - travel)
top = (HEIGHT - BOX) // 2
frame[top : top + BOX, left : left + BOX] = (60, 200, 255)
corners = np.array([left, top, left + BOX, top + BOX], dtype=np.float64)
return frame, corners
if __name__ == "__main__":
main()