Jordan Pierce commited on
Commit
a1d71d0
1 Parent(s): 2fa9cbf

initial commit

Browse files
.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

  • SHA256: 3e074223d31a3eaf82d20c67a776d97eefcc32e8068f3a2426fdb8ae6d32ff1b
  • Pointer size: 131 Bytes
  • Size of remote file: 784 kB
images/eel.png ADDED

Git LFS Details

  • SHA256: ab1fc09c0fab498839350db48b2cd2568c0979fc41ab7f677b443f945a277130
  • Pointer size: 132 Bytes
  • Size of remote file: 1.98 MB
images/fish.png ADDED

Git LFS Details

  • SHA256: 8f0aa7f7cf83c4fc7a8b25282ae3bf2aaace1ebffb153d98a46073a0fc130883
  • Pointer size: 131 Bytes
  • Size of remote file: 436 kB
images/fish_2.png ADDED

Git LFS Details

  • SHA256: 7a4c79f95a5e2175d34e3740fcac83147f17b34ebed938c35b6d59bc9a184019
  • Pointer size: 132 Bytes
  • Size of remote file: 4.44 MB
images/fish_3.png ADDED

Git LFS Details

  • SHA256: f93efdec2fd36bcafac53729a7c618b824f6bfc2aa99deafb90f2a4760200b43
  • Pointer size: 131 Bytes
  • Size of remote file: 375 kB
images/fish_4.png ADDED

Git LFS Details

  • SHA256: 18769ce02f5a11cbb205c3843c74b32acc1b60bd6ee0881097462e49158ed704
  • Pointer size: 131 Bytes
  • Size of remote file: 343 kB
images/fish_5.png ADDED

Git LFS Details

  • SHA256: 48b1f7a7f1cdbb54f0bdec8d254766cab3f0cf15d4a302098b83a28a42360f66
  • Pointer size: 131 Bytes
  • Size of remote file: 927 kB
images/flat_fish.png ADDED

Git LFS Details

  • SHA256: 5d8b67d2254a7e5737f34d1698629aca80605cbb17227f67fa5032d1ea9975a9
  • Pointer size: 131 Bytes
  • Size of remote file: 483 kB
images/flat_red_fish.png ADDED

Git LFS Details

  • SHA256: 5dad1dae0327e1aa43276ccbc7c45bfee7c736f1f0e19f37ea3c6c471f1bd166
  • Pointer size: 131 Bytes
  • Size of remote file: 438 kB
images/jelly.png ADDED

Git LFS Details

  • SHA256: 5c0f5068a307d70a21f83178899ff9893e98d4a2cbc1720dfe5586658734c385
  • Pointer size: 131 Bytes
  • Size of remote file: 382 kB
images/jelly_2.png ADDED

Git LFS Details

  • SHA256: b90ce6a8a471781249b9f3c7567bd831ff64dab824dd5a714065628b2cdf41d9
  • Pointer size: 132 Bytes
  • Size of remote file: 1.91 MB
images/jelly_3.png ADDED

Git LFS Details

  • SHA256: cd065530c7d7d74ab330603c6e72dd63856c06d3fb28c370258d620a42de6ae3
  • Pointer size: 131 Bytes
  • Size of remote file: 372 kB
images/jelly_4.png ADDED

Git LFS Details

  • SHA256: f797bc2017ef22b58f2012aeccdffb12628a0047c73fe7522b7881a05c79838f
  • Pointer size: 132 Bytes
  • Size of remote file: 1.64 MB
images/puff.png ADDED

Git LFS Details

  • SHA256: f7070e76cce4cfebbd9427bcc9f556017f35db8fb3df033d53d1d972356528d6
  • Pointer size: 131 Bytes
  • Size of remote file: 810 kB
images/red_fish.png ADDED

Git LFS Details

  • SHA256: 82d2d4b63874a4436397b3866733c3e5854b55e792a98ff6ba1780e1158e736e
  • Pointer size: 131 Bytes
  • Size of remote file: 543 kB
images/red_fish_2.png ADDED

Git LFS Details

  • SHA256: d917b1fb942e49b13fd9202c3e8a50343b80dfcaa2c35258260ed3b912d72895
  • Pointer size: 131 Bytes
  • Size of remote file: 467 kB
images/scene.png ADDED

Git LFS Details

  • SHA256: 1db4c76f67b872871dfea9f98a34564fc6abdcdebbae845603d66297cd720a36
  • Pointer size: 131 Bytes
  • Size of remote file: 684 kB
images/scene_2.png ADDED

Git LFS Details

  • SHA256: 5352f28fb997d2bca33c0b64a437994b87abb409cf36f543ce2009b20e71f985
  • Pointer size: 132 Bytes
  • Size of remote file: 3.51 MB
images/scene_3.png ADDED

Git LFS Details

  • SHA256: 79ed1a48a6b0ffe28f7dbb5e59350866ae3a561e7b8ebcd2ab4b9727766d412d
  • Pointer size: 131 Bytes
  • Size of remote file: 557 kB
images/scene_4.png ADDED

Git LFS Details

  • SHA256: 4587de40785f84e626099addabe543e30d24319cb50d3377267de5c99f4c34c2
  • Pointer size: 131 Bytes
  • Size of remote file: 515 kB
images/scene_5.png ADDED

Git LFS Details

  • SHA256: 30276e3c9b6eadfaa6538e52e0a814e20642e97cb4444e785bd4e433070ae24d
  • Pointer size: 132 Bytes
  • Size of remote file: 3.1 MB
images/scene_6.png ADDED

Git LFS Details

  • SHA256: 05df1e63218a14e9fb946000aa01b29a85eb4bd760e22107cb39b58ffbe305b7
  • Pointer size: 131 Bytes
  • Size of remote file: 530 kB
images/soft_coral.png ADDED

Git LFS Details

  • SHA256: 8ff302cc355b3d646e9fcf00c8cb781996907d6df86bbfbe083aea6a4bf6ad43
  • Pointer size: 131 Bytes
  • Size of remote file: 621 kB
images/squid.png ADDED

Git LFS Details

  • SHA256: 7017d563d41b21c5ce21e1da368505c8c5705ada6aae565ca89a47dd2ff4abf5
  • Pointer size: 132 Bytes
  • Size of remote file: 2.55 MB
images/starfish.png ADDED

Git LFS Details

  • SHA256: ccb636e812751313b19511c53a71245d1ca9e48662f59341f67e056834cf1e28
  • Pointer size: 131 Bytes
  • Size of remote file: 684 kB
images/starfish_2.png ADDED

Git LFS Details

  • SHA256: 65f58b8f77c5887b3fdf410b2d739af69443b081ed8ba9299ad96c737b44fb73
  • Pointer size: 131 Bytes
  • Size of remote file: 443 kB
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.")