Skip to content

Commit

Permalink
Initial stream, interpreter and config code
Browse files Browse the repository at this point in the history
  • Loading branch information
GearBoxFox committed Feb 1, 2024
1 parent f2135c9 commit 64d3990
Show file tree
Hide file tree
Showing 5,004 changed files with 1,387,882 additions and 16 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
16 changes: 0 additions & 16 deletions py/main.py

This file was deleted.

7 changes: 7 additions & 0 deletions py/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
numpy = 1.26.3
pillow = 10.2.0
pycoral = 2.0.0
setuptools = 69.0.3
tflite-runtime = 2.5.0.post1
robotpy
opencv-python
29 changes: 29 additions & 0 deletions py/src/config/Config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from dataclasses import dataclass
from typing import Tuple


@dataclass
class LocalConfig:
device_id: str = ""
server_ip: str = ""
stream_port: int = 8000
model_path: str = ""
label_path: str = ""
inference_size: Tuple[int, int] = 0, 0


@dataclass
class RemoteConfig:
camera_id: int = 0
camera_resolution_width: int = 0
camera_resolution_height: int = 0
camera_auto_exposure: int = 0
camera_exposure: int = 0
detection_threshold: float = 0.1
max_targets: int = 5


@dataclass
class ConfigStore:
local_config: LocalConfig
remote_config: RemoteConfig
2 changes: 2 additions & 0 deletions py/src/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
if __name__ == '__main__':
print("Hello, world!")
52 changes: 52 additions & 0 deletions py/src/pipeline/Capture.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import dataclasses
from typing import Tuple

import cv2 as cv

from src.config.Config import ConfigStore


class Capture:
"""Base interface for reading from a camera"""

def __init__(self) -> None:
raise NotImplementedError

def get_frame(self) -> Tuple[bool, cv.Mat]:
"""Returns the current camera frame"""
raise NotImplementedError

@classmethod
def _config_changed(cls, config_a: ConfigStore, config_b: ConfigStore) -> bool:
if config_a is None and config_b is None:
return False
if config_a is None or config_b is None:
return True

remote_a = config_a.remote_config
remote_b = config_b.remote_config

return (remote_a.camera_id != remote_b.camera_id
or remote_a.camera_resolution_width != remote_b.camera_resolution_width
or remote_a.camera_resolution_height != remote_b.camera_resolution_height
or remote_a.camera_auto_exposure != remote_b.camera_auto_exposure
or remote_a.camera_exposure != remote_b.camera_exposure)


class CVCapture(Capture):
"""Uses the default opencv capture stream"""

def __init__(self) -> None:
pass

m_video = None

def get_frame(self) -> Tuple[bool, cv.Mat]:
if self.m_video is None:
print("Creating camera with device id {}.".format(0))
self.m_video = cv.VideoCapture(0)

retval, image = self.m_video.read()

image_rgb = cv.cvtColor(image, cv.COLOR_BGR2RGB)
return retval, image_rgb
36 changes: 36 additions & 0 deletions py/src/pipeline/Detector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import sys

from src.config.Config import ConfigStore
from typing import Dict

from pycoral.adapters.detect import get_objects, Object
from pycoral.utils.edgetpu import run_inference
from pycoral.utils.edgetpu import make_interpreter
from pycoral.utils.dataset import read_label_file
import cv2 as cv


class Detector:
"""Runs a tflite model on the coral to detect objects"""
_labels: Dict[int, str]
_config: ConfigStore

def __init__(self, config: ConfigStore):
self._config = config

print("Loading {} with {} labels.".format(config.local_config.model_path, config.local_config.label_path))

self._interpreter = make_interpreter(config.local_config.model_path)
self._interpreter.allocate_tensors()
self._labels = read_label_file(config.local_config.label_path)

if self._interpreter is None:
print("Failed to create interpreter. Exiting.")
sys.exit(1)

print("Created interpreter successfully.")

def run_inference(self, image: cv.Mat) -> list[Object]:
run_inference(self._interpreter, image)
objs = get_objects(self._interpreter, self._config.remote_config.detection_threshold)[:self._config.remote_config.max_targets]
return objs
133 changes: 133 additions & 0 deletions py/venv/Lib/site-packages/PIL/BdfFontFile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#
# The Python Imaging Library
# $Id$
#
# bitmap distribution font (bdf) file parser
#
# history:
# 1996-05-16 fl created (as bdf2pil)
# 1997-08-25 fl converted to FontFile driver
# 2001-05-25 fl removed bogus __init__ call
# 2002-11-20 fl robustification (from Kevin Cazabon, Dmitry Vasiliev)
# 2003-04-22 fl more robustification (from Graham Dumpleton)
#
# Copyright (c) 1997-2003 by Secret Labs AB.
# Copyright (c) 1997-2003 by Fredrik Lundh.
#
# See the README file for information on usage and redistribution.
#

"""
Parse X Bitmap Distribution Format (BDF)
"""
from __future__ import annotations

from typing import BinaryIO

from . import FontFile, Image

bdf_slant = {
"R": "Roman",
"I": "Italic",
"O": "Oblique",
"RI": "Reverse Italic",
"RO": "Reverse Oblique",
"OT": "Other",
}

bdf_spacing = {"P": "Proportional", "M": "Monospaced", "C": "Cell"}


def bdf_char(
f: BinaryIO,
) -> (
tuple[
str,
int,
tuple[tuple[int, int], tuple[int, int, int, int], tuple[int, int, int, int]],
Image.Image,
]
| None
):
# skip to STARTCHAR
while True:
s = f.readline()
if not s:
return None
if s[:9] == b"STARTCHAR":
break
id = s[9:].strip().decode("ascii")

# load symbol properties
props = {}
while True:
s = f.readline()
if not s or s[:6] == b"BITMAP":
break
i = s.find(b" ")
props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii")

# load bitmap
bitmap = bytearray()
while True:
s = f.readline()
if not s or s[:7] == b"ENDCHAR":
break
bitmap += s[:-1]

# The word BBX
# followed by the width in x (BBw), height in y (BBh),
# and x and y displacement (BBxoff0, BByoff0)
# of the lower left corner from the origin of the character.
width, height, x_disp, y_disp = (int(p) for p in props["BBX"].split())

# The word DWIDTH
# followed by the width in x and y of the character in device pixels.
dwx, dwy = (int(p) for p in props["DWIDTH"].split())

bbox = (
(dwx, dwy),
(x_disp, -y_disp - height, width + x_disp, -y_disp),
(0, 0, width, height),
)

try:
im = Image.frombytes("1", (width, height), bitmap, "hex", "1")
except ValueError:
# deal with zero-width characters
im = Image.new("1", (width, height))

return id, int(props["ENCODING"]), bbox, im


class BdfFontFile(FontFile.FontFile):
"""Font file plugin for the X11 BDF format."""

def __init__(self, fp: BinaryIO):
super().__init__()

s = fp.readline()
if s[:13] != b"STARTFONT 2.1":
msg = "not a valid BDF file"
raise SyntaxError(msg)

props = {}
comments = []

while True:
s = fp.readline()
if not s or s[:13] == b"ENDPROPERTIES":
break
i = s.find(b" ")
props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii")
if s[:i] in [b"COMMENT", b"COPYRIGHT"]:
if s.find(b"LogicalFontDescription") < 0:
comments.append(s[i + 1 : -1].decode("ascii"))

while True:
c = bdf_char(fp)
if not c:
break
id, ch, (xy, dst, src), im = c
if 0 <= ch < len(self.glyph):
self.glyph[ch] = xy, dst, src, im
Loading

0 comments on commit 64d3990

Please sign in to comment.