Skip to content

Commit

Permalink
Merge pull request #251 from dora-rs/add-arrow-example
Browse files Browse the repository at this point in the history
Upgrading the operator example to use `dora-arrow`
  • Loading branch information
haixuanTao authored Apr 18, 2023
2 parents 86b2a53 + bf89ac7 commit 9042354
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 10 deletions.
16 changes: 14 additions & 2 deletions examples/python-operator-dataflow/no_webcam.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,28 @@
import time
import urllib.request

import cv2
import numpy as np
import pyarrow as pa

from dora import Node

print("Hello from no_webcam.py")


req = urllib.request.urlopen("https://ultralytics.com/images/zidane.jpg")
CAMERA_WIDTH = 640
CAMERA_HEIGHT = 480

# Preprocessing the image
req = urllib.request.urlopen(
"https://img0.baidu.com/it/u=2940037857,1417768899&fm=253&fmt=auto&app=138&f=PNG?w=724&h=500"
) # This image works in china better
arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
image = cv2.imdecode(arr, -1)[:, :, :3]
image = cv2.resize(image, (CAMERA_WIDTH, CAMERA_HEIGHT))

# Numpy -> Arrow
image = pa.array(image.flatten().view(np.uint8))
node = Node()

start = time.time()
Expand All @@ -24,7 +36,7 @@
match event["type"]:
case "INPUT":
print("received input", event["id"])
node.send_output("image", arr.tobytes())
node.send_output("image", image)
case "STOP":
print("received stop")
case other:
Expand Down
17 changes: 14 additions & 3 deletions examples/python-operator-dataflow/object_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@

import cv2
import numpy as np
import pyarrow as pa
import torch

from dora import DoraStatus

pa.array([])

CAMERA_WIDTH = 640
CAMERA_HEIGHT = 480


class Operator:
"""
Expand Down Expand Up @@ -38,10 +44,15 @@ def on_input(
send_output (Callable[[str, bytes]]): Function enabling sending output back to dora.
"""

frame = np.frombuffer(dora_input["data"], dtype="uint8")
frame = cv2.imdecode(frame, -1)
frame = (
dora_input["value"]
.to_numpy()
.reshape((CAMERA_HEIGHT, CAMERA_WIDTH, 3))
)
frame = frame[:, :, ::-1] # OpenCV image (BGR to RGB)
results = self.model(frame) # includes NMS
arrays = np.array(results.xyxy[0].cpu()).tobytes()
arrays = pa.array(
np.array(results.xyxy[0].cpu()).ravel().view(np.uint8)
)
send_output("bbox", arrays, dora_input["metadata"])
return DoraStatus.CONTINUE
14 changes: 11 additions & 3 deletions examples/python-operator-dataflow/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@

import cv2
import numpy as np
import pyarrow as pa
from utils import LABELS

from dora import DoraStatus

pa.array([])

CI = os.environ.get("CI")
CAMERA_WIDTH = 640
CAMERA_HEIGHT = 480

font = cv2.FONT_HERSHEY_SIMPLEX

Expand Down Expand Up @@ -49,15 +54,18 @@ def on_input(
send_output (Callable[[str, bytes]]): Function enabling sending output back to dora.
"""
if dora_input["id"] == "image":
frame = np.frombuffer(dora_input["data"], dtype="uint8")
frame = cv2.imdecode(frame, -1)
frame = (
dora_input["value"]
.to_numpy()
.reshape((CAMERA_HEIGHT, CAMERA_WIDTH, 3))
)
self.image = frame

self.image_messages += 1
print("received " + str(self.image_messages) + " images")

elif dora_input["id"] == "bbox" and len(self.image) != 0:
bboxs = np.frombuffer(dora_input["data"], dtype="float32")
bboxs = dora_input["value"].to_numpy().view(np.float32)
self.bboxs = np.reshape(bboxs, (-1, 6))

self.bounding_box_messages += 1
Expand Down
1 change: 1 addition & 0 deletions examples/python-operator-dataflow/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ thop>=0.1.1 # FLOPs computation
# roboflow

opencv-python>=4.1.1
pyarrow
11 changes: 9 additions & 2 deletions examples/python-operator-dataflow/webcam.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
from typing import Callable

import cv2
import pyarrow as pa

from dora import DoraStatus

CAMERA_WIDTH = 640
CAMERA_HEIGHT = 480


class Operator:
"""
Expand All @@ -17,19 +21,22 @@ class Operator:
def __init__(self):
self.video_capture = cv2.VideoCapture(0)
self.start_time = time.time()
self.video_capture.set(cv2.CAP_PROP_FRAME_WIDTH, CAMERA_WIDTH)
self.video_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, CAMERA_HEIGHT)

def on_event(
self,
dora_event: dict,
dora_event: str,
send_output: Callable[[str, bytes], None],
) -> DoraStatus:
match dora_event["type"]:
case "INPUT":
ret, frame = self.video_capture.read()
frame = cv2.resize(frame, (CAMERA_WIDTH, CAMERA_HEIGHT))
if ret:
send_output(
"image",
cv2.imencode(".jpg", frame)[1].tobytes(),
pa.array(frame.ravel()),
dora_event["metadata"],
)
case "STOP":
Expand Down

0 comments on commit 9042354

Please sign in to comment.