Skip to content

Commit

Permalink
Semi-working setup, still stuck on #1
Browse files Browse the repository at this point in the history
  • Loading branch information
freol35241 committed May 12, 2022
1 parent 2339ffc commit a8da84a
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 40 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM python:3.9-slim

RUN apt-get update && apt-get install -y python3-opencv
RUN apt-get update && apt-get install --no-install-recommends -y ffmpeg libsm6 libxext6 && rm -rf /var/lib/apt/lists/*

COPY requirements.txt requirements.txt

RUN pip3 install -r requirements.txt
RUN pip3 install --no-cache-dir -r requirements.txt

WORKDIR /app

Expand Down
106 changes: 68 additions & 38 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Main entrypoint for this application"""
import warnings
import logging
import time
from datetime import datetime, timezone

import yolov5
from vidgear.gears import CamGear
Expand All @@ -17,65 +19,93 @@
"YOLOV5_CONFIDENCE_THRESHOLD", default=0.5, validate=lambda x: 0.0 <= x <= 1.0
)
YOLOV5_MAX_DETECTIONS: int = env.int(
"YOLOV5_MAX_DETECTIONS", default=10, validate=lambda x: x > 0
"YOLOV5_MAX_DETECTIONS", default=100, validate=lambda x: x > 0
)
YOLOV5_DEVICE: str = env("YOLOV5_DEVICE", default="cpu")
YOLOV5_FRAMERATE: float = env.float("YOLOV5_FRAMERATE", default=1)

LOG_LEVEL = env.log_level("LOG_LEVEL", logging.WARNING)
FFMPEG_OUTPUT = env.bool("FFMPEG_OUTPUT", default=False)


verbose = LOG_LEVEL <= logging.INFO

# Setup logger
logging.basicConfig(level=LOG_LEVEL)
logging.basicConfig(level=LOG_LEVEL, force=True)
logging.captureWarnings(True)
warnings.filterwarnings("once")
warnings.filterwarnings("ignore")
LOGGER = logging.getLogger("crowsnest-processor-video-yolov5")

### Configure yolov5 model
MODEL = yolov5.load(YOLOV5_MODEL)
MODEL = yolov5.load(YOLOV5_MODEL, device=YOLOV5_DEVICE, verbose=verbose)

MODEL.conf = 0.25 # NMS confidence threshold
MODEL.conf = YOLOV5_CONFIDENCE_THRESHOLD # NMS confidence threshold
MODEL.iou = 0.45 # NMS IoU threshold
MODEL.agnostic = False # NMS class-agnostic
MODEL.multi_label = False # NMS multiple labels per box
MODEL.max_det = 10 # maximum number of detections per image
MODEL.max_det = YOLOV5_MAX_DETECTIONS # maximum number of detections per image


try:

# Open source stream, we always want the last frame since we
# cant guarantee to keep up with the source frame rate
source = CamGear(
source=SOURCE_STREAM,
colorspace="COLOR_BGR2RGB",
logging=verbose or FFMPEG_OUTPUT,
**{"THREADED_QUEUE_MODE": False, "-fflags": "nobuffer"}
).start()

sink = WriteGear(
output_filename=SINK_STREAM,
logging=verbose or FFMPEG_OUTPUT,
**{
"-f": "rtsp",
"-rtsp_transport": "tcp",
"-tune": "zerolatency",
"-preset": "ultrafast",
"-stimeout": "1000000",
"-input_framerate": YOLOV5_FRAMERATE,
"-r": source.framerate,
}
)

# Frame-wise loop
while True:

frame_t0 = time.time()

frame = source.read()
if frame is None:
break

LOGGER.debug("New frame read at: %s", datetime.now(timezone.utc))

if __name__ == "__main__":
t0 = time.time()

try:
# Do object detection
# pylint: disable=not-callable
result: yolov5.models.common.Detections = MODEL(frame, size=max(frame.shape))

# Open source stream, we always want the last frame since we
# cant guarantee to keep up with the source frame rate
source = CamGear(
source=SOURCE_STREAM,
colorspace="COLOR_BGR2RGB",
logging=verbose,
**{"THREADED_QUEUE_MODE": False}
).start()
LOGGER.debug("Inference took %s seconds", time.time() - t0)
LOGGER.debug(result.print())

sink = WriteGear(
output_filename=SINK_STREAM,
logging=verbose,
**{"-f": "rtsp", "-rtsp_transport": "tcp"}
)
annotated_frame = result.render()[0]

# Frame-wise loop
while True:
frame = source.read()
if frame is None:
break
LOGGER.debug("Annotated frame rendered with shape: %s", annotated_frame.shape)
sink.write(frame, rgb_mode=True)

# Do object detection
# pylint: disable=not-callable
result: yolov5.models.common.Detections = MODEL(
frame, size=max(frame.shape)
)
time_to_sleep = 1 / YOLOV5_FRAMERATE - (time.time() - frame_t0)

annotated_frame = result.render()[0]
sink.write(annotated_frame)
if time_to_sleep < 0:
LOGGER.warning("YOLOV5_FRAMERATE not reached!")
else:
time.sleep(time_to_sleep)

except Exception: # pylint: disable=broad-except
LOGGER.exception("Fundamental failure...")
except Exception: # pylint: disable=broad-except
LOGGER.exception("Fundamental failure...")

finally:
source.stop()
sink.close()
finally:
source.stop()
sink.close()

0 comments on commit a8da84a

Please sign in to comment.