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.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
"""A dora display sink: overlays bounding boxes and text on an image input.
|
||||
|
||||
An `image` event decodes the frame and immediately redraws. `bbox` and `text`
|
||||
events only update stored state, which the next `image` event draws.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
|
||||
from dora import Node
|
||||
|
||||
from dora_image_view import bbox, decode
|
||||
from dora_image_view.view import View
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Connect to the dataflow and display every frame that arrives."""
|
||||
args = _parse_args()
|
||||
|
||||
view = View(
|
||||
width=_size("VIEW_WIDTH", args.view_width),
|
||||
height=_size("VIEW_HEIGHT", args.view_height),
|
||||
headless=os.getenv("CI") == "true",
|
||||
)
|
||||
|
||||
# Passing the name lets the node also run standalone as a dynamic node; when
|
||||
# dora spawns it, the id from the dataflow wins.
|
||||
node = Node(args.name)
|
||||
|
||||
for event in node:
|
||||
if event["type"] == "ERROR":
|
||||
raise RuntimeError(event["error"])
|
||||
if event["type"] != "INPUT":
|
||||
continue
|
||||
|
||||
event_id = event["id"]
|
||||
metadata = event["metadata"]
|
||||
|
||||
if event_id == "image":
|
||||
frame = decode.to_bgr(
|
||||
event["value"],
|
||||
metadata.get("encoding", "bgr8").lower(),
|
||||
metadata.get("width"),
|
||||
metadata.get("height"),
|
||||
)
|
||||
if view.show(frame):
|
||||
break
|
||||
elif event_id == "bbox":
|
||||
view.bboxes = bbox.parse(event["value"], metadata.get("format", "xyxy").lower())
|
||||
elif event_id == "text":
|
||||
view.text = event["value"][0].as_py()
|
||||
else:
|
||||
print(f"ignoring unexpected input `{event_id}`")
|
||||
|
||||
|
||||
def _parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="OpenCV plotter: draws text and bounding boxes on an image.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--name",
|
||||
default="dora-image-view",
|
||||
help="The name of the node in the dataflow, used when running as a dynamic node.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--view-width",
|
||||
type=int,
|
||||
help="Resize the displayed frame to this width. Overridden by VIEW_WIDTH.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--view-height",
|
||||
type=int,
|
||||
help="Resize the displayed frame to this height. Overridden by VIEW_HEIGHT.",
|
||||
)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def _size(name: str, fallback: int | None) -> int | None:
|
||||
value = os.getenv(name)
|
||||
return int(value) if value and value.isnumeric() else fallback
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user