diff --git a/.gitignore b/.gitignore index 95615a2a008170b9320e24a7b0ec0d8f5e1e55b8..6ad15ab1ede0cbec7aa83b0963be13732409c647 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ # TF models /models +do_not_commit.py # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/common/poetry.lock b/common/poetry.lock index 696dcb36d509498476ab2f5a1b67451f12f95f40..9a42637dd95b439a257bc035a9c81a7198ac2003 100644 Binary files a/common/poetry.lock and b/common/poetry.lock differ diff --git a/common/polystar/common/frame_generators/__init__.py b/common/polystar/common/frame_generators/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/common/polystar/common/frame_generators/camera_frame_generator.py b/common/polystar/common/frame_generators/camera_frame_generator.py new file mode 100644 index 0000000000000000000000000000000000000000..e613cb6ea4796c6faf7d90a4899a19eb482e3dfe --- /dev/null +++ b/common/polystar/common/frame_generators/camera_frame_generator.py @@ -0,0 +1,25 @@ +from dataclasses import dataclass +from typing import Any, Iterable + +import cv2 + +from polystar.common.frame_generators.cv2_frame_generator_abc import CV2FrameGeneratorABC + + +@dataclass +class CameraFrameGenerator(CV2FrameGeneratorABC): + width: int + height: int + + def _capture_params(self) -> Iterable[Any]: + return ( + "nvarguscamerasrc ! " + "video/x-raw(memory:NVMM), " + f"width=(int){self.width}, height=(int){self.height}, " + "format=(string)NV12, framerate=(fraction)60/1 ! " + "nvvidconv flip-method=0 ! " + f"video/x-raw, width=(int){self.width}, height=(int){self.height}, " + "format=(string)BGRx ! " + "videoconvert ! appsink", + cv2.CAP_GSTREAMER, + ) diff --git a/common/polystar/common/frame_generators/cv2_frame_generator_abc.py b/common/polystar/common/frame_generators/cv2_frame_generator_abc.py new file mode 100644 index 0000000000000000000000000000000000000000..7cdf709cfdfe44732494be77a70bdcdb57948aca --- /dev/null +++ b/common/polystar/common/frame_generators/cv2_frame_generator_abc.py @@ -0,0 +1,32 @@ +from abc import ABC, abstractmethod +from dataclasses import dataclass, field +from typing import Any, Iterable + +import cv2 + +from polystar.common.frame_generators.frames_generator_abc import FrameGeneratorABC +from polystar.common.models.image import Image + + +@dataclass +class CV2FrameGeneratorABC(FrameGeneratorABC, ABC): + + _cap: cv2.VideoCapture = field(init=False, repr=False) + + def __enter__(self): + self._cap = cv2.VideoCapture(*self._capture_params()) + + def __exit__(self, exc_type, exc_val, exc_tb): + self._cap.release() + + def generate(self) -> Iterable[Image]: + with self: + while 1: + is_open, frame = self._cap.read() + if not is_open: + return + yield frame + + @abstractmethod + def _capture_params(self) -> Iterable[Any]: + pass diff --git a/common/polystar/common/frame_generators/fps_video_frame_generator.py b/common/polystar/common/frame_generators/fps_video_frame_generator.py new file mode 100644 index 0000000000000000000000000000000000000000..ade93a8882e9259e4fb23178eea38a01bc777df5 --- /dev/null +++ b/common/polystar/common/frame_generators/fps_video_frame_generator.py @@ -0,0 +1,26 @@ +from dataclasses import dataclass +from typing import Iterable + +import ffmpeg + +from polystar.common.frame_generators.video_frame_generator import VideoFrameGenerator +from polystar.common.models.image import Image + + +@dataclass +class FPSVideoFrameGenerator(VideoFrameGenerator): + + desired_fps: int + + def __post_init__(self): + self.frame_rate: int = self._get_video_fps() // self.desired_fps + + def _get_video_fps(self): + return max( + int(stream["r_frame_rate"].split("/")[0]) for stream in ffmpeg.probe(str(self.video_path))["streams"] + ) + + def generate(self) -> Iterable[Image]: + for i, frame in enumerate(super().generate()): + if not i % self.frame_rate: + yield frame diff --git a/common/polystar/common/frame_generators/frames_generator_abc.py b/common/polystar/common/frame_generators/frames_generator_abc.py new file mode 100644 index 0000000000000000000000000000000000000000..737446b257d3eef1971a6b1d1b1e242d8bbc2726 --- /dev/null +++ b/common/polystar/common/frame_generators/frames_generator_abc.py @@ -0,0 +1,10 @@ +from abc import ABC, abstractmethod +from typing import Iterable + +from polystar.common.models.image import Image + + +class FrameGeneratorABC(ABC): + @abstractmethod + def generate(self) -> Iterable[Image]: + pass diff --git a/common/polystar/common/frame_generators/video_frame_generator.py b/common/polystar/common/frame_generators/video_frame_generator.py new file mode 100644 index 0000000000000000000000000000000000000000..388dcc2a6999d27b14908c79c33fe9a30f345eec --- /dev/null +++ b/common/polystar/common/frame_generators/video_frame_generator.py @@ -0,0 +1,14 @@ +from dataclasses import dataclass +from pathlib import Path +from typing import Iterable, Any + +from polystar.common.frame_generators.cv2_frame_generator_abc import CV2FrameGeneratorABC + + +@dataclass +class VideoFrameGenerator(CV2FrameGeneratorABC): + + video_path: Path + + def _capture_params(self) -> Iterable[Any]: + return (str(self.video_path),) diff --git a/common/polystar/common/models/trt_model.py b/common/polystar/common/models/trt_model.py index 676e06af75a83aad7058d873874c848a73cc743f..b72fa2020009e6c03ba1fb964cdb62cdbdcd0489 100644 --- a/common/polystar/common/models/trt_model.py +++ b/common/polystar/common/models/trt_model.py @@ -46,7 +46,7 @@ class TRTModel: img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img = cv2.resize(img, self.input_size) img = img.transpose((2, 0, 1)).astype(np.float32) - img = (2.0/255.0) * img - 1.0 + img = (2.0 / 255.0) * img - 1.0 return img # Initialization diff --git a/common/polystar/common/utils/video_frame_generator.py b/common/polystar/common/utils/video_frame_generator.py deleted file mode 100644 index e28e7b7416adb0e79b5d70ea62492eb93a30d34c..0000000000000000000000000000000000000000 --- a/common/polystar/common/utils/video_frame_generator.py +++ /dev/null @@ -1,29 +0,0 @@ -from pathlib import Path - -import cv2 -import ffmpeg - - -class VideoFrameGenerator: - def __init__(self, video_path: Path, desired_fps: int): - self.video_path: Path = video_path - self.desired_fps: int = desired_fps - self.video_fps: int = self._get_video_fps() - - def _get_video_fps(self): - return max( - int(stream["r_frame_rate"].split("/")[0]) for stream in ffmpeg.probe(str(self.video_path))["streams"] - ) - - def generate(self): - video = cv2.VideoCapture(str(self.video_path)) - frame_rate = self.video_fps // self.desired_fps - count = 0 - while 1: - is_unfinished, frame = video.read() - if not is_unfinished: - video.release() - return - if not count % frame_rate: - yield frame - count += 1 diff --git a/common/polystar/common/view/bend_object_on_image.py b/common/polystar/common/view/bend_object_on_image.py deleted file mode 100644 index b91ce7206d7e4f2e6514bccf60ee66f23b9f2690..0000000000000000000000000000000000000000 --- a/common/polystar/common/view/bend_object_on_image.py +++ /dev/null @@ -1,58 +0,0 @@ -import cv2 -from typing import Tuple - -import numpy as np - -from polystar.common.models.image import Image -from polystar.common.models.object import Object - -_COLORS = [ - [31, 119, 180], - [255, 127, 14], - [44, 160, 44], - [214, 39, 40], - [148, 103, 189], - [140, 86, 75], - [227, 119, 194], - [127, 127, 127], - [188, 189, 34], - [23, 190, 207], -] # seaborn.color_palette() * 255 - -ALPHA = 0.5 -FONT = cv2.FONT_HERSHEY_PLAIN -TEXT_SCALE = 1.0 -TEXT_THICKNESS = 1 -BLACK = (0, 0, 0) -WHITE = (255, 255, 255) - - -def bend_boxed_text_on_image(img: Image, text: str, topleft: Tuple[int, int], color: Tuple[int, int, int]): - assert img.dtype == np.uint8 - img_h, img_w, _ = img.shape - if topleft[0] >= img_w or topleft[1] >= img_h: - return img - margin = 3 - size = cv2.getTextSize(text, FONT, TEXT_SCALE, TEXT_THICKNESS) - w = size[0][0] + margin * 2 - h = size[0][1] + margin * 2 - # the patch is used to draw boxed text - patch = np.zeros((h, w, 3), dtype=np.uint8) - patch[...] = color - cv2.putText(patch, text, (margin+1, h-margin-2), FONT, TEXT_SCALE, - WHITE, thickness=TEXT_THICKNESS, lineType=cv2.LINE_8) - cv2.rectangle(patch, (0, 0), (w-1, h-1), BLACK, thickness=1) - w = min(w, img_w - topleft[0]) # clip overlay at image boundary - h = min(h, img_h - topleft[1]) - # Overlay the boxed text onto region of interest (roi) in img - roi = img[topleft[1]:topleft[1]+h, topleft[0]:topleft[0]+w, :] - cv2.addWeighted(patch[0:h, 0:w, :], ALPHA, roi, 1 - ALPHA, 0, roi) - return img - - -def bend_object_on_image(image: Image, obj: Object): - color = _COLORS[obj.type.value] - cv2.rectangle(image, (obj.x, obj.y), (obj.x + obj.w, obj.y + obj.h), color, 2) - - bend_boxed_text_on_image(image, f"{obj.type.name} ({obj.confidence:.1%})", (obj.x, obj.y), _COLORS[obj.type.value]) - return image diff --git a/common/polystar/common/view/cv2_results_viewer.py b/common/polystar/common/view/cv2_results_viewer.py new file mode 100644 index 0000000000000000000000000000000000000000..3894982d9c1ee40a93830b744fdd76e99826b222 --- /dev/null +++ b/common/polystar/common/view/cv2_results_viewer.py @@ -0,0 +1,73 @@ +import cv2 +import numpy as np + +from polystar.common.models.image import Image +from polystar.common.view.results_viewer_abc import ResultViewerABC, ColorView + +ALPHA = 0.5 +FONT = cv2.FONT_HERSHEY_PLAIN +TEXT_SCALE = 1.0 +TEXT_THICKNESS = 1 +BLACK = (0, 0, 0) +WHITE = (255, 255, 255) +COLORS = [ + (31, 119, 180), + (255, 127, 14), + (44, 160, 44), + (214, 39, 40), + (148, 103, 189), + (140, 86, 75), + (227, 119, 194), + (127, 127, 127), + (188, 189, 34), + (23, 190, 207), +] # seaborn.color_palette() * 255 + + +class CV2ResultViewer(ResultViewerABC): + def __init__(self, name: str, delay: int = 1, end_keys: str = "q"): + self.end_keys = [ord(c) for c in end_keys] + self.delay = delay + self.name = name + self._current_image: Image = None + self.finished = False + super().__init__(COLORS) + + def __exit__(self, exc_type, exc_val, exc_tb): + cv2.destroyWindow(self.name) + + def new(self, image: Image): + self.height, self.width, _ = image.shape + self._current_image = image + + def add_text(self, text: str, x: int, y: int, color: ColorView): + margin = 3 + size = cv2.getTextSize(text, FONT, TEXT_SCALE, TEXT_THICKNESS) + w = size[0][0] + margin * 2 + h = size[0][1] + margin * 2 + # the patch is used to draw boxed text + patch = np.zeros((h, w, 3), dtype=np.uint8) + patch[...] = color + cv2.putText( + patch, + text, + (margin + 1, h - margin - 2), + FONT, + TEXT_SCALE, + WHITE, + thickness=TEXT_THICKNESS, + lineType=cv2.LINE_8, + ) + cv2.rectangle(patch, (0, 0), (w - 1, h - 1), BLACK, thickness=1) + w = min(w, self.width - x) # clip overlay at image boundary + h = min(h, self.height - y) + # Overlay the boxed text onto region of interest (roi) in img + roi = self._current_image[y : y + h, x : x + w, :] + cv2.addWeighted(patch[0:h, 0:w, :], ALPHA, roi, 1 - ALPHA, 0, roi) + + def add_rectangle(self, x: int, y: int, w: int, h: int, color: ColorView): + cv2.rectangle(self._current_image, (x, y), (x + w, y + h), color, 2) + + def display(self): + cv2.imshow(self.name, self._current_image) + self.finished = cv2.waitKey(self.delay) & 0xFF in self.end_keys diff --git a/common/polystar/common/view/plt_display_image_with_annotation.py b/common/polystar/common/view/plt_display_image_with_annotation.py deleted file mode 100644 index 8c28081a8bf2569ba08c2ca3b999618bfe34285f..0000000000000000000000000000000000000000 --- a/common/polystar/common/view/plt_display_image_with_annotation.py +++ /dev/null @@ -1,29 +0,0 @@ -from typing import Iterable - -import matplotlib.pyplot as plt - -from polystar.common.models.image import Image -from polystar.common.models.image_annotation import ImageAnnotation -from polystar.common.models.object import Object -import seaborn as sns - - -_COLORS = sns.color_palette() - - -def display_image_with_objects(image: Image, objects: Iterable[Object]): - plt.figure(figsize=(16, 9)) - plt.imshow(image) - for obj in objects: - if obj.confidence >= 0.5: - color = _COLORS[obj.type.value] - rect = plt.Rectangle((obj.x, obj.y), obj.w, obj.h, linewidth=2, edgecolor=color, fill=False) - plt.gca().add_patch(rect) - plt.text(obj.x, obj.y - 2, f"{obj.type.name} ({int(obj.confidence*100)}%)", color=color, weight="bold") - plt.axis("off") - plt.tight_layout() - plt.show() - - -def display_image_annotation(image_annotation: ImageAnnotation): - display_image_with_objects(image_annotation.image, image_annotation.objects) diff --git a/common/polystar/common/view/plt_display_image_with_object.py b/common/polystar/common/view/plt_display_image_with_object.py deleted file mode 100644 index 075bc85d9812b3c00be55e8a660e39869434cad6..0000000000000000000000000000000000000000 --- a/common/polystar/common/view/plt_display_image_with_object.py +++ /dev/null @@ -1,7 +0,0 @@ -from polystar.common.models.image import Image -from polystar.common.models.object import Object -from polystar.common.view.plt_display_image_with_annotation import display_image_with_objects - - -def display_object(image: Image, obj: Object): - display_image_with_objects(image, [obj]) diff --git a/common/polystar/common/view/plt_results_viewer.py b/common/polystar/common/view/plt_results_viewer.py new file mode 100644 index 0000000000000000000000000000000000000000..e46e019edb1eeccf8bc32da9901f84362c5e5aa5 --- /dev/null +++ b/common/polystar/common/view/plt_results_viewer.py @@ -0,0 +1,46 @@ +from typing import Tuple + +import matplotlib.pyplot as plt + +from polystar.common.models.image import Image +from polystar.common.view.results_viewer_abc import ResultViewerABC, ColorView + + +COLORS = [ + (0.12156862745098039, 0.4666666666666667, 0.7058823529411765), + (1.0, 0.4980392156862745, 0.054901960784313725), + (0.17254901960784313, 0.6274509803921569, 0.17254901960784313), + (0.8392156862745098, 0.15294117647058825, 0.1568627450980392), + (0.5803921568627451, 0.403921568627451, 0.7411764705882353), + (0.5490196078431373, 0.33725490196078434, 0.29411764705882354), + (0.8901960784313725, 0.4666666666666667, 0.7607843137254902), + (0.4980392156862745, 0.4980392156862745, 0.4980392156862745), + (0.7372549019607844, 0.7411764705882353, 0.13333333333333333), + (0.09019607843137255, 0.7450980392156863, 0.8117647058823529), +] + + +class PltResultViewer(ResultViewerABC): + def __init__(self, name: str, fig_size: Tuple[int, int] = (16, 9)): + self.name = name + self.fig_size = fig_size + self._current_fig = None + super().__init__(COLORS) + + def new(self, image: Image): + self._current_fig = plt.figure(figsize=self.fig_size) + plt.imshow(image) + plt.title(self.name) + plt.axis("off") + + def add_text(self, text: str, x: int, y: int, color: ColorView): + plt.text(x, y - 2, text, color=color, weight="bold") + + def add_rectangle(self, x: int, y: int, w: int, h: int, color: ColorView): + rect = plt.Rectangle((x, y), w, h, linewidth=2, edgecolor=color, fill=False) + plt.gca().add_patch(rect) + + def display(self): + plt.tight_layout() + plt.show() + plt.close(self._current_fig) diff --git a/common/polystar/common/view/results_viewer_abc.py b/common/polystar/common/view/results_viewer_abc.py new file mode 100644 index 0000000000000000000000000000000000000000..486bf0d29bb288453b158acde5ef0d95e084f974 --- /dev/null +++ b/common/polystar/common/view/results_viewer_abc.py @@ -0,0 +1,52 @@ +from abc import ABC, abstractmethod +from typing import Iterable, Tuple, NewType, Sequence + +from polystar.common.models.image import Image +from polystar.common.models.image_annotation import ImageAnnotation +from polystar.common.models.object import Object + +ColorView = NewType("ColorView", Tuple[float, float, float]) + + +class ResultViewerABC(ABC): + def __init__(self, colors: Sequence[ColorView]): + self.colors = colors + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + pass + + @abstractmethod + def new(self, image: Image): + pass + + @abstractmethod + def add_text(self, text: str, x: int, y: int, color: ColorView): + pass + + @abstractmethod + def add_rectangle(self, x: int, y: int, w: int, h: int, color: ColorView): + pass + + @abstractmethod + def display(self): + pass + + def add_object(self, obj: Object): + color = self.colors[obj.type.value] + self.add_rectangle(obj.x, obj.y, obj.w, obj.h, color) + self.add_text(f"{obj.type.name} ({obj.confidence:.1%})", obj.x, obj.y, color) + + def add_objects(self, objects: Iterable[Object]): + for obj in objects: + self.add_object(obj) + + def display_image_with_objects(self, image: Image, objects: Iterable[Object]): + self.new(image) + self.add_objects(objects) + self.display() + + def display_image_annotation(self, annotation: ImageAnnotation): + self.display_image_with_objects(annotation.image, annotation.objects) diff --git a/common/pyproject.toml b/common/pyproject.toml index d499fd72844b1516a60a602a1c12277f167151e7..9590454498d87945cedddbc85223986fa9531c8b 100644 --- a/common/pyproject.toml +++ b/common/pyproject.toml @@ -8,7 +8,7 @@ packages = [{ include = "polystar" }] [tool.poetry.dependencies] python = "^3.7" dynaconf = "^2.2.2" -opencv-python = "^4.2.0" +opencv-python = "4.1.x" injector = "^0.18.3" numpy = "1.18.x" matplotlib = "^3.1.3" diff --git a/common/research_common/dataset/twitch/robots_views_extractor.py b/common/research_common/dataset/twitch/robots_views_extractor.py index 878295d89be72f7eab47cf099b829c5d48a90294..c14759bc74ab4250992d3d5f5a6e204c1dedeacc 100644 --- a/common/research_common/dataset/twitch/robots_views_extractor.py +++ b/common/research_common/dataset/twitch/robots_views_extractor.py @@ -3,7 +3,7 @@ import ffmpeg import numpy as np from tqdm import tqdm -from polystar.common.utils.video_frame_generator import VideoFrameGenerator +from polystar.common.frame_generators.fps_video_frame_generator import FPSVideoFrameGenerator from research_common.constants import TWITCH_DSET_DIR, TWITCH_ROBOTS_VIEWS_DIR from research_common.dataset.twitch.mask_detector import is_image_from_robot_view @@ -15,7 +15,7 @@ class RobotsViewExtractor: def __init__(self, video_name: str): self.video_name: str = video_name self.video_path = TWITCH_DSET_DIR / "videos" / f"{video_name}.mp4" - self.frame_generator: VideoFrameGenerator = VideoFrameGenerator(self.video_path, self.FPS) + self.frame_generator: FPSVideoFrameGenerator = FPSVideoFrameGenerator(self.video_path, self.FPS) self.count = 0 (TWITCH_ROBOTS_VIEWS_DIR / self.video_name).mkdir(exist_ok=True) diff --git a/dataset/twitch/runes/.gitignore b/dataset/twitch/runes/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c96a04f008ee21e260b28f7701595ed59e2839e3 --- /dev/null +++ b/dataset/twitch/runes/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/drone-at-base/poetry.lock b/drone-at-base/poetry.lock index a71cb44e19bfb263ef690b2f061b8284fbf17e53..5d5ab9b3fe409ee080089ae7f272c78a9f47c25b 100644 Binary files a/drone-at-base/poetry.lock and b/drone-at-base/poetry.lock differ diff --git a/models-training/install_tensorflow_models.sh b/models-training/install_tensorflow_models.sh deleted file mode 100755 index 80e4d45aad2647a54ca637c58b2aa13c93f0b59b..0000000000000000000000000000000000000000 --- a/models-training/install_tensorflow_models.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash - -ROOT_DIR=`pwd` -MODELS_DIR=$ROOT_DIR/../models -PYTHON='poetry run python' -PIP='poetry run pip' - -# make sure tensorflow has been installed -$PIP list | grep tensorflow -if [ $? -ne 0 ]; then - echo "TensorFlow doesn't seem to be installed!" - exit -fi - -# Download tensorflow models, with the working commit -cd .. -git clone https://github.com/tensorflow/models -cd $MODELS_DIR || exit -git checkout 6518c1c - -# Fix the code for python3 -cd research || exit -sed -i "" -e "157s/print '--annotation_type expected value is 1 or 2.'/print('--annotation_type expected value is 1 or 2.')/" \ - object_detection/dataset_tools/oid_hierarchical_labels_expansion.py -sed -i "" -e "516s/print num_classes, num_anchors/print(num_classes, num_anchors)/" \ - object_detection/meta_architectures/ssd_meta_arch_test.py -sed -i "" -e "282s/losses_dict.itervalues()/losses_dict.values()/" \ - object_detection/model_lib.py -sed -i "" -e "381s/category_index.values(),/list(category_index.values()),/" \ - object_detection/model_lib.py -sed -i "" -e "391s/eval_metric_ops.iteritems()/eval_metric_ops.items()/" \ - object_detection/model_lib.py -sed -i "" -e "225s/reversed(zip(output_feature_map_keys, output_feature_maps_list)))/reversed(list(zip(output_feature_map_keys, output_feature_maps_list))))/" \ - object_detection/models/feature_map_generators.py -sed -i "" -e "842s/print 'Scores and tpfp per class label: {}'.format(class_index)/print('Scores and tpfp per class label: {}'.format(class_index))/" \ - object_detection/utils/object_detection_evaluation.py -sed -i "" -e "843s/print tp_fp_labels/print(tp_fp_labels)/" \ - object_detection/utils/object_detection_evaluation.py -sed -i "" -e "844s/print scores/print(scores)/" \ - object_detection/utils/object_detection_evaluation.py -sed -n '31p' object_detection/eval_util.py | grep -q vis_utils && - ex -s -c 31m23 -c w -c q object_detection/eval_util.py - -protoc object_detection/protos/*.proto --python_out=. - -# run a basic test to make sure tensorflow object detection is working -echo Running model_builder_test.py -CUDA_VISIBLE_DEVICES=0 \ -PYTHONPATH=$MODELS_DIR/research:$MODELS_DIR/research/slim \ - $PYTHON $MODELS_DIR/research/object_detection/builders/model_builder_test.py - -echo add tf models, research and slim to your PYTHONPATH diff --git a/models-training/poetry.lock b/models-training/poetry.lock deleted file mode 100644 index 76d867b2fb54391a730e78314f4dcf473344f33b..0000000000000000000000000000000000000000 Binary files a/models-training/poetry.lock and /dev/null differ diff --git a/models-training/pyproject.toml b/models-training/pyproject.toml deleted file mode 100644 index eea43767a4de8e3691c58cde5764b686abbcae48..0000000000000000000000000000000000000000 --- a/models-training/pyproject.toml +++ /dev/null @@ -1,29 +0,0 @@ -[tool.poetry] -name = "polystar.models-training" -version = "0.1.0" -description = "" -authors = ["Polystar"] -packages = [{ include = "polystar" }] - -[tool.poetry.dependencies] -python = "3.6" -#tensorflow-gpu = { version = "1.12.x", platform = "linux/win32" } -matplotlib = "^3.1.3" -PILLOW = "^7.0.0" -Cython = "^0.29.15" -pycocotools = "^2.0.0" -six = "^1.14.0" -numpy = "^1.18.1" -wheel = "^0.34.2" -setuptools = "^45.2.0" -mock = "^4.0.1" -future = "^0.18.2" -keras_applications = "^1.0.8" -keras_preprocessing = "^1.1.0" - -[tool.poetry.dev-dependencies] -pytest = "^4.5" - -[tool.black] -line-length = 120 -target_version = ['py36'] diff --git a/robots-at-robots/poetry.lock b/robots-at-robots/poetry.lock index a71cb44e19bfb263ef690b2f061b8284fbf17e53..5d5ab9b3fe409ee080089ae7f272c78a9f47c25b 100644 Binary files a/robots-at-robots/poetry.lock and b/robots-at-robots/poetry.lock differ diff --git a/robots-at-robots/research/demos/demo_infer.py b/robots-at-robots/research/demos/demo_infer.py index 4e0a7f237d67847d916a9318e520897fdea3fe2c..9769460c3cf395f0d1729138d17683c3695bbc46 100644 --- a/robots-at-robots/research/demos/demo_infer.py +++ b/robots-at-robots/research/demos/demo_infer.py @@ -2,7 +2,7 @@ from polystar.common.models.label_map import LabelMap from polystar.common.pipeline.objects_detectors.tf_model_objects_detector import TFModelObjectsDetector from polystar.common.pipeline.objects_validators.confidence_object_validator import ConfidenceObjectValidator from polystar.common.utils.tensorflow import patch_tf_v2 -from polystar.common.view.plt_display_image_with_annotation import display_image_with_objects +from polystar.common.view.plt_results_viewer import PltResultViewer from polystar.robots_at_robots.dependency_injection import make_injector from research.demos.utils import load_tf_model from research_common.dataset.dji.dji_roco_datasets import DJIROCODataset @@ -16,11 +16,13 @@ if __name__ == "__main__": objects_detector = TFModelObjectsDetector(load_tf_model(), injector.get(LabelMap)) filters = [ConfidenceObjectValidator(confidence_threshold=0.5)] - for i, image in enumerate(SplitDataset(DJIROCODataset.CentralChina, Split.Test).images): - objects = objects_detector.detect(image) - for f in filters: - objects = f.filter(objects, image) + with PltResultViewer("Demo of tf model") as viewer: + for i, image in enumerate(SplitDataset(DJIROCODataset.CentralChina, Split.Test).images): + objects = objects_detector.detect(image) + for f in filters: + objects = f.filter(objects, image) - display_image_with_objects(image, objects) - if i == 0: - break + viewer.display_image_with_objects(image, objects) + + if i == 5: + break diff --git a/robots-at-robots/research/demos/demo_pipeline.py b/robots-at-robots/research/demos/demo_pipeline.py index 047aaf2a7d0c120fb5f6dd9e81ffb3636e43a918..ca58ed5fbc583e81a082ff747036caa7ea3a4a00 100644 --- a/robots-at-robots/research/demos/demo_pipeline.py +++ b/robots-at-robots/research/demos/demo_pipeline.py @@ -10,7 +10,7 @@ from polystar.common.pipeline.objects_validators.type_object_validator import Ty from polystar.common.pipeline.pipeline import Pipeline from polystar.common.pipeline.target_factories.ratio_simple_target_factory import RatioSimpleTargetFactory from polystar.common.utils.tensorflow import patch_tf_v2 -from polystar.common.view.plt_display_image_with_object import display_object +from polystar.common.view.plt_results_viewer import PltResultViewer from polystar.robots_at_robots.dependency_injection import make_injector from research.demos.utils import load_tf_model from research_common.dataset.dji.dji_roco_datasets import DJIROCODataset @@ -28,11 +28,12 @@ if __name__ == "__main__": target_factory=RatioSimpleTargetFactory(injector.get(Camera), 300, 100), ) - for i, image_path in enumerate(SplitDataset(DJIROCODataset.CentralChina, Split.Test).image_paths): - image = cv2.cvtColor(cv2.imread(str(image_path)), cv2.COLOR_BGR2RGB) - obj = pipeline.predict_best_object(image) + with PltResultViewer("Demo of tf model") as viewer: + for i, image_path in enumerate(SplitDataset(DJIROCODataset.CentralChina, Split.Test).image_paths): + image = cv2.cvtColor(cv2.imread(str(image_path)), cv2.COLOR_BGR2RGB) + obj = pipeline.predict_best_object(image) - display_object(image, obj) + viewer.display_image_with_objects(image, [obj]) - if i == 0: - break + if i == 5: + break diff --git a/robots-at-robots/research/demos/demo_pipeline_camera.py b/robots-at-robots/research/demos/demo_pipeline_camera.py index 94b8bc8417664e606080264e1ab2928241c9df76..33f15701452d229d2e76b445bf0ed79d507964db 100644 --- a/robots-at-robots/research/demos/demo_pipeline_camera.py +++ b/robots-at-robots/research/demos/demo_pipeline_camera.py @@ -1,59 +1,21 @@ -import subprocess -import sys - -import cv2 from time import time import pycuda.autoinit # This is needed for initializing CUDA driver from polystar.common.constants import MODELS_DIR +from polystar.common.frame_generators.camera_frame_generator import CameraFrameGenerator from polystar.common.models.label_map import LabelMap from polystar.common.models.trt_model import TRTModel from polystar.common.pipeline.objects_detectors.trt_model_object_detector import TRTModelObjectsDetector from polystar.common.pipeline.objects_validators.confidence_object_validator import ConfidenceObjectValidator from polystar.common.utils.tensorflow import patch_tf_v2 -from polystar.common.view.bend_object_on_image import bend_object_on_image, bend_boxed_text_on_image +from polystar.common.view.cv2_results_viewer import CV2ResultViewer from polystar.robots_at_robots.dependency_injection import make_injector from polystar.robots_at_robots.globals import settings -WINDOWS_NAME = "TensorRT demo" - - [pycuda.autoinit] # So pycharm won't remove the import -def open_cam_onboard(width, height): - """Open the Jetson onboard camera.""" - gst_elements = str(subprocess.check_output("gst-inspect-1.0")) - if "nvcamerasrc" in gst_elements: - # On versions of L4T prior to 28.1, you might need to add - # 'flip-method=2' into gst_str below. - gst_str = ( - "nvcamerasrc ! " - "video/x-raw(memory:NVMM), " - "width=(int)2592, height=(int)1458, " - "format=(string)I420, framerate=(fraction)30/1 ! " - "nvvidconv ! " - "video/x-raw, width=(int){}, height=(int){}, " - "format=(string)BGRx ! " - "videoconvert ! appsink" - ).format(width, height) - elif "nvarguscamerasrc" in gst_elements: - gst_str = ( - "nvarguscamerasrc ! " - "video/x-raw(memory:NVMM), " - f"width=(int){width}, height=(int){height}, " - "format=(string)NV12, framerate=(fraction)60/1 ! " - "nvvidconv flip-method=0 ! " - f"video/x-raw, width=(int){width}, height=(int){height}, " - "format=(string)BGRx ! " - "videoconvert ! appsink" - ) - else: - raise RuntimeError("onboard camera source not found!") - return cv2.VideoCapture(gst_str, cv2.CAP_GSTREAMER) - - if __name__ == "__main__": patch_tf_v2() injector = make_injector() @@ -63,31 +25,22 @@ if __name__ == "__main__": ) filters = [ConfidenceObjectValidator(confidence_threshold=0.5)] - cap = open_cam_onboard(1_280, 720) - - if not cap.isOpened(): - sys.exit("Failed to open camera!") - fps = 0 - try: - while True: + with CV2ResultViewer("TensorRT demo") as viewer: + for image in CameraFrameGenerator(1_280, 720).generate(): + previous_time = time() - ret, image = cap.read() + + # inference objects = objects_detector.detect(image) for f in filters: objects = f.filter(objects, image) - fps = .9 * fps + .1 / (time() - previous_time) - bend_boxed_text_on_image(image, f'FPS: {fps:.1f}', (10, 10), (0, 0, 0)) - - for obj in objects: - bend_object_on_image(image, obj) - - # Display the resulting frame - cv2.imshow("frame", image) - if cv2.waitKey(1) & 0xFF == ord("q"): + # display + fps = 0.9 * fps + 0.1 / (time() - previous_time) + viewer.new(image) + viewer.add_objects(objects) + viewer.add_text(f"FPS: {fps:.1f}", 10, 10, (0, 0, 0)) + viewer.display() + if viewer.finished: break - finally: - # When everything done, release the capture - cap.release() - cv2.destroyAllWindows() diff --git a/robots-at-robots/research/demos/utils.py b/robots-at-robots/research/demos/utils.py index 93969a53989b036dd763f68b07222bb4522c37a0..6bcbcdba5703dfcfe3dea7e808258dc760555d7f 100644 --- a/robots-at-robots/research/demos/utils.py +++ b/robots-at-robots/research/demos/utils.py @@ -1,9 +1,8 @@ import tensorflow as tf from polystar.common.constants import MODELS_DIR -from polystar.robots_at_robots.globals import settings def load_tf_model(): - model = tf.saved_model.load(export_dir=str(MODELS_DIR / settings.MODEL_NAME / "saved_model")) + model = tf.saved_model.load(export_dir=str(MODELS_DIR / "robots/ssd_mobilenet_v2_coco_2018_03_29" / "saved_model")) return model.signatures["serving_default"] diff --git a/robots-at-runes/poetry.lock b/robots-at-runes/poetry.lock index a71cb44e19bfb263ef690b2f061b8284fbf17e53..5d5ab9b3fe409ee080089ae7f272c78a9f47c25b 100644 Binary files a/robots-at-runes/poetry.lock and b/robots-at-runes/poetry.lock differ