From 6efc2b7835141db21718365a6ba396493e7be8b2 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Mon, 11 Apr 2022 15:45:44 +0200 Subject: Using DictObject to define ROI 2D and 3D --- src/argaze/RegionOfInterest/ROI2DScene.py | 44 ++++++++++++++++++++----------- src/argaze/RegionOfInterest/ROI3DScene.py | 40 +++++++++++++++++++--------- 2 files changed, 57 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/argaze/RegionOfInterest/ROI2DScene.py b/src/argaze/RegionOfInterest/ROI2DScene.py index d025cb2..acf8e0a 100644 --- a/src/argaze/RegionOfInterest/ROI2DScene.py +++ b/src/argaze/RegionOfInterest/ROI2DScene.py @@ -1,19 +1,28 @@ #!/usr/bin/env python +from argaze import DataStructures + import cv2 as cv import matplotlib.path as mpath -class ROI2DScene(list): - """List of ROI3D dictionary. - ``` - { - 'NAME': str, - 'VERTICES': array of (x, y) tuples, - 'POINTER_INSIDE': bool - } +class ROI2D(DataStructures.DictObject): + """Define Region Of Interest 2D + ``` + { + 'name': str, + 'vertices': array of (x, y) tuples + 'pointer': (x, y) tuple or None + } ``` """ + def __init__(self, name, vertices, pointer = None): + + super().__init__(type(self).__name__, **{'name': name, 'vertices': vertices, 'pointer': pointer}) + +class ROI2DScene(list): + """List of ROI2D.""" + def __new__(cls): return super(ROI2DScene, cls).__new__(cls) @@ -24,25 +33,30 @@ class ROI2DScene(list): pass def inside(self, pointer): - """Check if a (x, y) pointer is inside ROIs.""" + """Store pointer position if it is inside ROIs.""" for roi in self: - roi['POINTER_INSIDE'] = mpath.Path(roi['VERTICES']).contains_points([pointer])[0] + if mpath.Path(roi.vertices).contains_points([pointer])[0]: + + roi.pointer = pointer + + else: + + roi.pointer = None def draw(self, frame): """Draw ROI polygons on frame.""" for roi in self: - vertices = roi['VERTICES'] - inside = roi['POINTER_INSIDE'] + inside = roi.pointer != None color = (0, 255, 0) if inside else (0, 0, 255) if inside: - cv.putText(frame, roi['NAME'], (vertices[3][0], vertices[3][1]), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1, cv.LINE_AA) + cv.putText(frame, roi.name, (roi.vertices[3][0], roi.vertices[3][1]), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1, cv.LINE_AA) - cv.line(frame, vertices[-1], vertices[0], color, 1) - for A, B in zip(vertices, vertices[1:]): + cv.line(frame, roi.vertices[-1], roi.vertices[0], color, 1) + for A, B in zip(roi.vertices, roi.vertices[1:]): cv.line(frame, A, B, color, 1) diff --git a/src/argaze/RegionOfInterest/ROI3DScene.py b/src/argaze/RegionOfInterest/ROI3DScene.py index cf55e63..683110c 100644 --- a/src/argaze/RegionOfInterest/ROI3DScene.py +++ b/src/argaze/RegionOfInterest/ROI3DScene.py @@ -3,11 +3,25 @@ import math import re +from argaze import DataStructures from argaze.RegionOfInterest import ROI2DScene import numpy import cv2 as cv -import matplotlib.path as mpath + +class ROI3D(DataStructures.DictObject): + """Define Region Of Interest 3D + ``` + { + 'name': str, + 'vertices': array of (x, y, z) tuples + } + ``` + """ + + def __init__(self, name, vertices): + + super().__init__(type(self).__name__, **{'name': name, 'vertices': vertices}) class ROI3DScene(list): """List of ROI3D dictionary. @@ -56,6 +70,7 @@ class ROI3DScene(list): # start parsing try: + roi3D_list = [] roi3D = {} vertices = [] faces = [] @@ -77,7 +92,7 @@ class ROI3DScene(list): # extract roi3D name elif key == 'name': - roi3D['NAME'] = str(match.group(1)) + roi3D['name'] = str(match.group(1)) # fill vertices array elif key == 'vertice': @@ -87,10 +102,10 @@ class ROI3DScene(list): # extract roi3D vertice id elif key == 'face': - roi3D['FACE'] = [int(i) for i in match.group(1).split()] + roi3D['face'] = [int(i) for i in match.group(1).split()] # store roi3D dict into scene array - self.append(roi3D) + roi3D_list.append(roi3D) # clear roi3D dict roi3D = {} @@ -101,9 +116,10 @@ class ROI3DScene(list): file.close() # retreive all roi3D vertices - for roi3D in self: - roi3D['VERTICES'] = [ vertices[i-1] for i in roi3D['FACE'] ] - roi3D.pop('FACE', None) + for roi3D in roi3D_list: + roi3D['vertices'] = [ vertices[i-1] for i in roi3D['face'] ] + roi3D.pop('face', None) + self.append(ROI3D(**roi3D)) except IOError: raise IOError(f'File not found: {obj_filepath}') @@ -124,17 +140,17 @@ class ROI3DScene(list): for roi3D in self: - vertices_3D = numpy.array(roi3D['VERTICES']).astype('float32') + vertices_3D = numpy.array(roi3D.vertices).astype('float32') vertices_2D, J = cv.projectPoints(vertices_3D, self.__rotation, self.__translation, K, D) vertices_2D = vertices_2D.astype('int').reshape((len(vertices_2D), 2)) roi2D = { - 'NAME': roi3D['NAME'], - 'VERTICES': vertices_2D, - 'POINTER_INSIDE': False + 'name': roi3D.name, + 'vertices': vertices_2D, + 'pointer': None } - roi2D_scene.append(roi2D) + roi2D_scene.append(ROI2DScene.ROI2D(**roi2D)) return roi2D_scene -- cgit v1.1