Spaces:
Runtime error
Runtime error
Jordan Pierce
commited on
Commit
·
a1d71d0
1
Parent(s):
2fa9cbf
initial commit
Browse files- .gitattributes +1 -0
- Dockerfile +10 -0
- app.py +38 -0
- images/crab.png +3 -0
- images/eel.png +3 -0
- images/fish.png +3 -0
- images/fish_2.png +3 -0
- images/fish_3.png +3 -0
- images/fish_4.png +3 -0
- images/fish_5.png +3 -0
- images/flat_fish.png +3 -0
- images/flat_red_fish.png +3 -0
- images/jelly.png +3 -0
- images/jelly_2.png +3 -0
- images/jelly_3.png +3 -0
- images/jelly_4.png +3 -0
- images/puff.png +3 -0
- images/red_fish.png +3 -0
- images/red_fish_2.png +3 -0
- images/scene.png +3 -0
- images/scene_2.png +3 -0
- images/scene_3.png +3 -0
- images/scene_4.png +3 -0
- images/scene_5.png +3 -0
- images/scene_6.png +3 -0
- images/soft_coral.png +3 -0
- images/squid.png +3 -0
- images/starfish.png +3 -0
- images/starfish_2.png +3 -0
- inference.py +69 -0
- models/deepsea-detector.pt +3 -0
- models/results-deepsea-detector-datasetv1-trainv1/val_batch0_labels.jpg +0 -0
- models/results-deepsea-detector-datasetv1-trainv1/val_batch0_pred.jpg +0 -0
- models/results-deepsea-detector-datasetv1-trainv1/val_batch1_labels.jpg +0 -0
- models/results-deepsea-detector-datasetv1-trainv1/val_batch1_pred.jpg +0 -0
- models/results-deepsea-detector-datasetv1-trainv1/val_batch2_labels.jpg +0 -0
- models/results-deepsea-detector-datasetv1-trainv1/val_batch2_pred.jpg +0 -0
- requirements.txt +3 -0
- tator_inference.py +100 -0
.gitattributes
CHANGED
|
@@ -31,3 +31,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 31 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 32 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 33 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 31 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 32 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 33 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.png filter=lfs diff=lfs merge=lfs -text
|
Dockerfile
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM python:3.7
|
| 2 |
+
|
| 3 |
+
RUN apt-get update \
|
| 4 |
+
&& apt-get install ffmpeg libsm6 libxext6 -y
|
| 5 |
+
|
| 6 |
+
RUN pip install yolov5 tator gradio
|
| 7 |
+
|
| 8 |
+
COPY . ./
|
| 9 |
+
|
| 10 |
+
CMD [ "python", "-u", "./tator_inference.py" ]
|
app.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import glob
|
| 2 |
+
import gradio as gr
|
| 3 |
+
from inference import *
|
| 4 |
+
from PIL import Image
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
def gradio_app(image_path):
|
| 8 |
+
"""A function that send the file to the inference pipeline, and filters
|
| 9 |
+
some predictions before outputting to gradio interface."""
|
| 10 |
+
|
| 11 |
+
predictions = run_inference(image_path)
|
| 12 |
+
|
| 13 |
+
out_img = Image.fromarray(predictions.render()[0])
|
| 14 |
+
|
| 15 |
+
return out_img
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
title = "UWROV Deepsea Detector"
|
| 19 |
+
description = "Gradio demo for UWROV Deepsea Detector: Developed by Peyton " \
|
| 20 |
+
"Lee, Neha Nagvekar, and Cassandra Lam as part of the " \
|
| 21 |
+
"Underwater Remotely Operated Vehicles Team (UWROV) at the " \
|
| 22 |
+
"University of Washington. Deepsea Detector is built on " \
|
| 23 |
+
"MBARI's Monterey Bay Benthic Object Detector, which can also " \
|
| 24 |
+
"be found in FathomNet's Model Zoo. The model is trained on " \
|
| 25 |
+
"data from NOAA Ocean Exploration and FathomNet, " \
|
| 26 |
+
"with assistance from WoRMS for organism classification. All " \
|
| 27 |
+
"the images and associated annotations we used can be found in " \
|
| 28 |
+
"our Roboflow project. "
|
| 29 |
+
|
| 30 |
+
examples = glob.glob("images/*.png")
|
| 31 |
+
|
| 32 |
+
gr.Interface(gradio_app,
|
| 33 |
+
inputs=[gr.inputs.Image(type="filepath")],
|
| 34 |
+
outputs=gr.outputs.Image(type="pil"),
|
| 35 |
+
enable_queue=True,
|
| 36 |
+
title=title,
|
| 37 |
+
description=description,
|
| 38 |
+
examples=examples).launch()
|
images/crab.png
ADDED
|
Git LFS Details
|
images/eel.png
ADDED
|
Git LFS Details
|
images/fish.png
ADDED
|
Git LFS Details
|
images/fish_2.png
ADDED
|
Git LFS Details
|
images/fish_3.png
ADDED
|
Git LFS Details
|
images/fish_4.png
ADDED
|
Git LFS Details
|
images/fish_5.png
ADDED
|
Git LFS Details
|
images/flat_fish.png
ADDED
|
Git LFS Details
|
images/flat_red_fish.png
ADDED
|
Git LFS Details
|
images/jelly.png
ADDED
|
Git LFS Details
|
images/jelly_2.png
ADDED
|
Git LFS Details
|
images/jelly_3.png
ADDED
|
Git LFS Details
|
images/jelly_4.png
ADDED
|
Git LFS Details
|
images/puff.png
ADDED
|
Git LFS Details
|
images/red_fish.png
ADDED
|
Git LFS Details
|
images/red_fish_2.png
ADDED
|
Git LFS Details
|
images/scene.png
ADDED
|
Git LFS Details
|
images/scene_2.png
ADDED
|
Git LFS Details
|
images/scene_3.png
ADDED
|
Git LFS Details
|
images/scene_4.png
ADDED
|
Git LFS Details
|
images/scene_5.png
ADDED
|
Git LFS Details
|
images/scene_6.png
ADDED
|
Git LFS Details
|
images/soft_coral.png
ADDED
|
Git LFS Details
|
images/squid.png
ADDED
|
Git LFS Details
|
images/starfish.png
ADDED
|
Git LFS Details
|
images/starfish_2.png
ADDED
|
Git LFS Details
|
inference.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import cv2
|
| 2 |
+
import glob
|
| 3 |
+
import numpy as np
|
| 4 |
+
import torch
|
| 5 |
+
import yolov5
|
| 6 |
+
from typing import Dict, Tuple, Union, List, Optional
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
# -----------------------------------------------------------------------------
|
| 10 |
+
# Configs
|
| 11 |
+
# -----------------------------------------------------------------------------
|
| 12 |
+
|
| 13 |
+
model_path = "models/deepsea-detector.pt"
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
# -----------------------------------------------------------------------------
|
| 17 |
+
# YOLOv5 class
|
| 18 |
+
# -----------------------------------------------------------------------------
|
| 19 |
+
|
| 20 |
+
class YOLO:
|
| 21 |
+
"""Wrapper class for loading and running YOLO model"""
|
| 22 |
+
|
| 23 |
+
def __init__(self, model_path: str, device: Optional[str] = None):
|
| 24 |
+
|
| 25 |
+
# load model
|
| 26 |
+
self.model = yolov5.load(model_path, device=device)
|
| 27 |
+
|
| 28 |
+
def __call__(
|
| 29 |
+
self,
|
| 30 |
+
img: Union[str, np.ndarray],
|
| 31 |
+
conf_threshold: float = 0.25,
|
| 32 |
+
iou_threshold: float = 0.45,
|
| 33 |
+
image_size: int = 720,
|
| 34 |
+
classes: Optional[List[int]] = None) -> torch.Tensor:
|
| 35 |
+
self.model.conf = conf_threshold
|
| 36 |
+
self.model.iou = iou_threshold
|
| 37 |
+
|
| 38 |
+
if classes is not None:
|
| 39 |
+
self.model.classes = classes
|
| 40 |
+
|
| 41 |
+
# pylint: disable=not-callable
|
| 42 |
+
detections = self.model(img, size=image_size)
|
| 43 |
+
|
| 44 |
+
return detections
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def run_inference(image_path):
|
| 48 |
+
"""Helper function to execute the inference."""
|
| 49 |
+
|
| 50 |
+
predictions = model(image_path)
|
| 51 |
+
|
| 52 |
+
return predictions
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
# -----------------------------------------------------------------------------
|
| 56 |
+
# Model Creation
|
| 57 |
+
# -----------------------------------------------------------------------------
|
| 58 |
+
model = YOLO(model_path, device='cpu')
|
| 59 |
+
|
| 60 |
+
if __name__ == "__main__":
|
| 61 |
+
|
| 62 |
+
# For demo purposes: run through a couple of test
|
| 63 |
+
# images and then output the predictions in a folder.
|
| 64 |
+
test_images = glob.glob("images/*.png")
|
| 65 |
+
|
| 66 |
+
for test_image in test_images:
|
| 67 |
+
predictions = run_inference(test_image)
|
| 68 |
+
|
| 69 |
+
print("Done.")
|
models/deepsea-detector.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:14c5a32e23e068bec7849726065f02da91f5cb57eedd4d28186403bdfe4f66a8
|
| 3 |
+
size 175330621
|
models/results-deepsea-detector-datasetv1-trainv1/val_batch0_labels.jpg
ADDED
|
models/results-deepsea-detector-datasetv1-trainv1/val_batch0_pred.jpg
ADDED
|
models/results-deepsea-detector-datasetv1-trainv1/val_batch1_labels.jpg
ADDED
|
models/results-deepsea-detector-datasetv1-trainv1/val_batch1_pred.jpg
ADDED
|
models/results-deepsea-detector-datasetv1-trainv1/val_batch2_labels.jpg
ADDED
|
models/results-deepsea-detector-datasetv1-trainv1/val_batch2_pred.jpg
ADDED
|
requirements.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
yolov5
|
| 2 |
+
tator
|
| 3 |
+
gradio
|
tator_inference.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import logging
|
| 3 |
+
from tempfile import TemporaryFile
|
| 4 |
+
|
| 5 |
+
import cv2
|
| 6 |
+
import numpy as np
|
| 7 |
+
from PIL import Image
|
| 8 |
+
|
| 9 |
+
import tator
|
| 10 |
+
import inference
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
logger = logging.getLogger(__name__)
|
| 14 |
+
logger.setLevel(logging.INFO)
|
| 15 |
+
|
| 16 |
+
# Read environment variables that are provided from TATOR
|
| 17 |
+
host = os.getenv('HOST')
|
| 18 |
+
token = os.getenv('TOKEN')
|
| 19 |
+
project_id = int(os.getenv('PROJECT_ID'))
|
| 20 |
+
media_ids = [int(id_) for id_ in os.getenv('MEDIA_IDS').split(',')]
|
| 21 |
+
frames_per_inference = int(os.getenv('FRAMES_PER_INFERENCE', 30))
|
| 22 |
+
|
| 23 |
+
# Set up the TATOR API.
|
| 24 |
+
api = tator.get_api(host, token)
|
| 25 |
+
|
| 26 |
+
# Iterate through each video.
|
| 27 |
+
for media_id in media_ids:
|
| 28 |
+
|
| 29 |
+
# Download video.
|
| 30 |
+
media = api.get_media(media_id)
|
| 31 |
+
logger.info(f"Downloading {media.name}...")
|
| 32 |
+
out_path = f"/tmp/{media.name}"
|
| 33 |
+
for progress in tator.util.download_media(api, media, out_path):
|
| 34 |
+
logger.info(f"Download progress: {progress}%")
|
| 35 |
+
|
| 36 |
+
# Do inference on each video.
|
| 37 |
+
logger.info(f"Doing inference on {media.name}...")
|
| 38 |
+
localizations = []
|
| 39 |
+
vid = cv2.VideoCapture(out_path)
|
| 40 |
+
frame_number = 0
|
| 41 |
+
|
| 42 |
+
# Read *every* frame from the video, break when at the end.
|
| 43 |
+
while True:
|
| 44 |
+
ret, frame = vid.read()
|
| 45 |
+
if not ret:
|
| 46 |
+
break
|
| 47 |
+
|
| 48 |
+
# Create a temporary file, access the image data, save data to file.
|
| 49 |
+
framefile = TemporaryFile(suffix='.jpg')
|
| 50 |
+
im = Image.fromarray(frame)
|
| 51 |
+
im.save(framefile)
|
| 52 |
+
|
| 53 |
+
# For every N frames, make a prediction; append prediction results
|
| 54 |
+
# to a list, increase the frame count.
|
| 55 |
+
if frame_number % frames_per_inference == 0:
|
| 56 |
+
|
| 57 |
+
spec = {}
|
| 58 |
+
|
| 59 |
+
# Predictions contains all information inside pandas dataframe
|
| 60 |
+
predictions = inference.run_inference(framefile)
|
| 61 |
+
|
| 62 |
+
for i, r in predictions.pandas().xyxy[0].iterrows:
|
| 63 |
+
|
| 64 |
+
spec['media_id'] = media_id
|
| 65 |
+
spec['type'] = None # Unsure, docs not specific
|
| 66 |
+
spec['frame'] = frame_number
|
| 67 |
+
|
| 68 |
+
x, y, x2, y2 = r['xmin'], r['ymin'], r['xmax'], r['ymax']
|
| 69 |
+
w, h = x2 - x, y2 - y
|
| 70 |
+
|
| 71 |
+
spec['x'] = x
|
| 72 |
+
spec['y'] = y
|
| 73 |
+
spec['width'] = w
|
| 74 |
+
spec['height'] = h
|
| 75 |
+
spec['class_category'] = r['name']
|
| 76 |
+
spec['confidence'] = r['confidence']
|
| 77 |
+
|
| 78 |
+
localizations.append(spec)
|
| 79 |
+
|
| 80 |
+
frame_number += 1
|
| 81 |
+
|
| 82 |
+
# End interaction with video properly.
|
| 83 |
+
vid.release()
|
| 84 |
+
|
| 85 |
+
logger.info(f"Uploading object detections on {media.name}...")
|
| 86 |
+
|
| 87 |
+
# Create the localizations in the video.
|
| 88 |
+
num_created = 0
|
| 89 |
+
for response in tator.util.chunked_create(api.create_localization_list,
|
| 90 |
+
project_id,
|
| 91 |
+
localization_spec=localizations):
|
| 92 |
+
num_created += len(response.id)
|
| 93 |
+
|
| 94 |
+
# Output pretty logging information.
|
| 95 |
+
logger.info(f"Successfully created {num_created} localizations on "
|
| 96 |
+
f"{media.name}!")
|
| 97 |
+
|
| 98 |
+
logger.info("-------------------------------------------------")
|
| 99 |
+
|
| 100 |
+
logger.info(f"Completed inference on {len(media_ids)} files.")
|