Captures frames from a V4L2 camera and publishes them as std/media/v1/Image: an Arrow struct of width, height, encoding and data, so a receiver needs nothing from the message metadata. For a compressed encoding the recorded dimensions are the image's, not the length of the payload. Based on opencv-video-capture from dora-hub, with three changes. The output is the typed image struct rather than a flat UInt8 buffer plus metadata. Camera selection by id reads /dev/v4l/by-id/ only; the upstream macOS system_profiler and Windows PowerShell enumeration is not carried. CAPTURE_FRAMES bounds a run so a test ends on its own, in place of upstream's ten-second CI cutoff -- a timeout would have made the CI step exit non-zero. CI=true keeps a failed capture from raising, publishing a labelled black frame instead, which is what lets dataflow.yml run on a machine with no camera. Two dataflows, run one at a time, as dora has no cross-dataflow wiring: dataflow.yml is the camera alone and the CI gate; dataflow_view.yml wires it into dora-image-view and is not run by CI, since it fetches that node over the network and needs a tag to exist there.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
"""Packing a frame as std/media/v1/Image.
|
||||
|
||||
The struct is respelled here rather than imported from the viewer: node
|
||||
repositories share no source package, so the manifest and this schema are the
|
||||
whole contract between them.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import pyarrow as pa
|
||||
|
||||
IMAGE_TYPE = pa.struct([
|
||||
("width", pa.uint32()),
|
||||
("height", pa.uint32()),
|
||||
("encoding", pa.utf8()),
|
||||
("data", pa.large_binary()),
|
||||
])
|
||||
|
||||
|
||||
def pack(frame: np.ndarray, encoding: str, width: int, height: int) -> pa.Array:
|
||||
"""Pack encoded frame bytes as a single-row std/media/v1/Image array.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
frame : np.ndarray
|
||||
The bytes to send. Either a raw pixel buffer or the output of an
|
||||
encoder; either way only its bytes are read.
|
||||
encoding : str
|
||||
Name of the encoding the bytes are in, e.g. ``bgr8`` or ``jpeg``.
|
||||
width, height : int
|
||||
Dimensions of the *image*, which for a compressed encoding are not the
|
||||
shape of ``frame``. They are recorded so a receiver can size a buffer
|
||||
without decoding first.
|
||||
|
||||
Returns
|
||||
-------
|
||||
pa.Array
|
||||
One-row struct array matching ``IMAGE_TYPE``.
|
||||
|
||||
"""
|
||||
return pa.array(
|
||||
[{
|
||||
"width": width,
|
||||
"height": height,
|
||||
"encoding": encoding,
|
||||
"data": frame.tobytes(),
|
||||
}],
|
||||
type=IMAGE_TYPE,
|
||||
)
|
||||
Reference in New Issue
Block a user