Coverage for backpack/annotation/annotation.py: 100%

75 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-30 23:12 +0000

1''' This module makes it possible to draw annotations on different 

2backends with an unified API. Currently, you can draw rectangles and labels with 

3:mod:`~backpack.annotation` on ``panoramasdk.media`` and OpenCV images 

4(:class:`numpy arrays <numpy.ndarray>`).''' 

5 

6from typing import Optional 

7from enum import Enum 

8import datetime 

9from abc import ABC 

10from dataclasses import dataclass 

11 

12from .color import Color 

13from ..timepiece import local_now 

14from ..geometry import Point, Rectangle, Line, PolyLine 

15 

16 

17class Annotation(ABC): 

18 ''' Abstract base class for annotations. ''' 

19 

20 

21@dataclass(frozen=True) 

22class LabelAnnotation(Annotation): 

23 ''' A label annotation to be rendered in an :class:`AnnotationDriver` context. 

24 

25 The :attr:`point` refers to the position of the anchor point. 

26 

27 Args: 

28 point (Point): The origin of the label 

29 text (str): The text to be rendered 

30 color (Color): The color of the text 

31 ''' 

32 class HorizontalAnchor(Enum): 

33 ''' Horizontal anchor point location. ''' 

34 LEFT = 1, 

35 ''' Left anchor point ''' 

36 CENTER = 2, 

37 ''' Center anchor point ''' 

38 RIGHT = 3 

39 ''' Right anchor point ''' 

40 

41 class VerticalAnchor(Enum): 

42 ''' Vertical anchor point location. ''' 

43 TOP = 1 

44 ''' Top anchor point ''' 

45 CENTER = 2 

46 ''' Center anchor point ''' 

47 BASELINE = 3 

48 ''' Text baseline anchor point ''' 

49 BOTTOM = 4 

50 ''' Bottom anchor point ''' 

51 

52 point: Point 

53 ''' The origin of the label. ''' 

54 

55 text: str 

56 ''' The text to be rendered. ''' 

57 

58 color: Color = None 

59 ''' The color of the text. If `None`, the default drawing color will be used. ''' 

60 

61 horizontal_anchor: HorizontalAnchor = HorizontalAnchor.LEFT 

62 ''' Horizontal anchor point location ''' 

63 

64 vertical_anchor: VerticalAnchor = VerticalAnchor.BOTTOM 

65 ''' Vertical anchor point location ''' 

66 

67 size: float = 1.0 

68 ''' The relative size of the text ''' 

69 

70 

71@dataclass(frozen=True) 

72class RectAnnotation(Annotation): 

73 ''' A rectangle annotation to be rendered in an AnnotationDriver context. 

74 

75 Args: 

76 rect: The rectangle to be rendered in the AnnotationDriver context. 

77 color: The line color of the rectangle. 

78 ''' 

79 rect: Rectangle 

80 ''' The rectangle to be rendered in the AnnotationDriver context ''' 

81 

82 color: Color = None 

83 ''' The line color of the rectangle. If `None`, the default drawing color will be used. ''' 

84 

85 

86@dataclass(frozen=True) 

87class LineAnnotation(Annotation): 

88 ''' A line annotation to be rendered in an AnnotationDriver context. 

89 

90 Args: 

91 line: The line segment to be drawn 

92 color: The color of the line 

93 ''' 

94 line: Line 

95 ''' The line segment to be drawn ''' 

96 

97 color: Color = None 

98 ''' The color of the line. If `None`, the default drawing color will be used. ''' 

99 

100 thickness: int = 1 

101 ''' The thickness of the line. ''' 

102 

103 

104@dataclass(frozen=True) 

105class MarkerAnnotation(Annotation): 

106 ''' A marker annotation to be rendered in an AnnotationDriver context. 

107 

108 Args: 

109 point (Point): The coordinates of the maker 

110 style (MarkerAnnotation.Style): The style of the marker 

111 color (Color): The color of the maker 

112 ''' 

113 class Style(Enum): 

114 ''' Possible set of marker types. ''' 

115 CROSS = 1 

116 ''' A crosshair marker shape. ''' 

117 TILTED_CROSS = 2 

118 ''' A 45 degree tilted crosshair marker shape. ''' 

119 STAR = 3 

120 ''' A star marker shape, combination of cross and tilted cross. ''' 

121 DIAMOND = 4 

122 ''' A diamond marker shape. ''' 

123 SQUARE = 5 

124 ''' A square marker shape. ''' 

125 TRIANGLE_UP = 6 

126 ''' An upwards pointing triangle marker shape. ''' 

127 TRIANGLE_DOWN = 7 

128 ''' A downwards pointing triangle marker shape. ''' 

129 

130 point: Point 

131 ''' The coordinates of the maker. ''' 

132 style: Style = Style.CROSS 

133 ''' The style of the marker. ''' 

134 color: Color = None 

135 ''' The color of the maker. ''' 

136 

137 

138@dataclass(frozen=True) 

139class PolyLineAnnotation(Annotation): 

140 ''' A PolyLine annotation to be rendered in an AnnotationDriver context. 

141 

142 Args: 

143 polyline(PolyLine): The PolyLine instance 

144 thickness(int): Line thickness 

145 color(Color): Line color 

146 fill_color(Color): Fill color 

147 ''' 

148 

149 polyline : PolyLine 

150 ''' The PolyLine instance. ''' 

151 thickness : int = 1 

152 ''' Line thickness. ''' 

153 color : Color = None 

154 ''' Line color. ''' 

155 fill_color : Color = None 

156 ''' Fill color. ''' 

157 

158 

159@dataclass(frozen=True) 

160class TimestampAnnotation(LabelAnnotation): 

161 ''' A timestamp annotation to be rendered in an AnnotationDriver context. 

162 

163 Args: 

164 timestamp: The timestamp to be rendered. If not specified, the current local time 

165 will be used. 

166 point: The origin of the timestamp. If not specified, the timestamp will be places 

167 on the top-left corner of the image. 

168 ''' 

169 def __init__(self, timestamp: Optional[datetime.datetime]=None, point: Point=Point(0.02, 0.04)): 

170 timestamp = timestamp or local_now() 

171 time_str = timestamp.strftime('%Y-%m-%d %H:%M:%S') 

172 return super().__init__(point=point, text=time_str) 

173 

174 

175@dataclass(frozen=True) 

176class BoundingBoxAnnotation(Annotation): 

177 ''' A bounding box annotation with a rectangle, and optional upper and lower labels. 

178 

179 Args: 

180 rectangle: The rectangle of the bounding box. 

181 top_label: The optional top label. 

182 bottom_label: The optional bottom label. 

183 color: The color of the bounding box and the labels. 

184 ''' 

185 

186 rectangle: Rectangle 

187 ''' The rectangle of the bounding box. ''' 

188 

189 top_label: Optional[str] = None 

190 ''' The optional top label. ''' 

191 

192 bottom_label: Optional[str] = None 

193 ''' The optional bottom label. ''' 

194 

195 color: Optional[Color] = None 

196 ''' The color of the bounding box and the labels. '''