3 This module contains an image viewer and drawing routines based on OpenCV. 11 """Check if ROI is fully contained in the image. 16 An ndarray of ndim>=2. 17 roi : (int, int, int, int) 18 Region of interest (x, y, width, height) where (x, y) is the top-left 24 Returns true if the ROI is contain in mat. 27 if roi[0] < 0
or roi[0] + roi[2] >= mat.shape[1]:
29 if roi[1] < 0
or roi[1] + roi[3] >= mat.shape[0]:
37 The ROI must be valid, i.e., fully contained in the image. 42 An ndarray of ndim=2 or ndim=3. 43 roi : (int, int, int, int) 44 Region of interest (x, y, width, height) where (x, y) is the top-left 53 sx, ex = roi[0], roi[0] + roi[2]
54 sy, ey = roi[1], roi[1] + roi[3]
56 return mat[sy:ey, sx:ex]
58 return mat[sy:ey, sx:ex, :]
62 """An image viewer with drawing routines and video capture capabilities. 72 Number of milliseconds between frames (1000 / frames per second). 73 window_shape : (int, int) 74 Shape of the window (width, height). 75 caption : Optional[str] 81 Color image of shape (height, width, 3). You may directly manipulate 82 this image to change the view. Otherwise, you may call any of the 83 drawing routines of this class. Internally, the image is treated as 84 beeing in BGR color space. 86 Note that the image is resized to the the image viewers window_shape 87 just prior to visualization. Therefore, you may pass differently sized 88 images and call drawing routines with the appropriate, original point 90 color : (int, int, int) 91 Current BGR color code that applies to all drawing routines. 92 Values are in range [0-255]. 93 text_color : (int, int, int) 94 Current BGR text color code that applies to all text rendering 95 routines. Values are in range [0-255]. 97 Stroke width in pixels that applies to all drawing routines. 101 def __init__(self, update_ms, window_shape=(640, 480), caption=
"Figure 1"):
121 raise ValueError(
"color must be tuple of 3")
122 self.
_color = tuple(
int(c)
for c
in value)
130 Top left corner of the rectangle (x-axis). 132 Top let corner of the rectangle (y-axis). 134 Width of the rectangle. 136 Height of the rectangle. 137 label : Optional[str] 138 A text label that is placed at the top left corner of the 143 pt2 =
int(x + w),
int(y + h)
145 if label
is not None:
146 text_size = cv2.getTextSize(
147 label, cv2.FONT_HERSHEY_PLAIN, 1, self.
thickness)
149 center = pt1[0] + 5, pt1[1] + 5 + text_size[0][1]
150 pt2 = pt1[0] + 10 + text_size[0][0], pt1[1] + 10 + \
152 cv2.rectangle(self.
image, pt1, pt2, self.
_color, -1)
153 cv2.putText(self.
image, label, center, cv2.FONT_HERSHEY_PLAIN,
156 def circle(self, x, y, radius, label=None):
162 Center of the circle (x-axis). 164 Center of the circle (y-axis). 166 Radius of the circle in pixels. 167 label : Optional[str] 168 A text label that is placed at the center of the circle. 172 roi =
int(x - image_size),
int(y - image_size), \
173 int(2 * image_size),
int(2 * image_size)
178 center = image.shape[1] // 2, image.shape[0] // 2
181 if label
is not None:
183 self.
image, label, center, cv2.FONT_HERSHEY_PLAIN,
187 """Draw 95% confidence ellipse of a 2-D Gaussian distribution. 192 The mean vector of the Gaussian distribution (ndim=1). 193 covariance : array_like 194 The 2x2 covariance matrix of the Gaussian distribution. 195 label : Optional[str] 196 A text label that is placed at the center of the ellipse. 200 vals, vecs = np.linalg.eigh(5.9915 * covariance)
201 indices = vals.argsort()[::-1]
202 vals, vecs = np.sqrt(vals[indices]), vecs[:, indices]
204 center =
int(mean[0] + .5),
int(mean[1] + .5)
205 axes =
int(vals[0] + .5),
int(vals[1] + .5)
206 angle =
int(180. * np.arctan2(vecs[1, 0], vecs[0, 0]) / np.pi)
208 self.
image, center, axes, angle, 0, 360, self.
_color, 2)
209 if label
is not None:
210 cv2.putText(self.
image, label, center, cv2.FONT_HERSHEY_PLAIN,
214 """Draws a text string at a given location. 219 Bottom-left corner of the text in the image (x-axis). 221 Bottom-left corner of the text in the image (y-axis). 223 The text to be drawn. 226 cv2.putText(self.
image, text, (
int(x),
int(y)), cv2.FONT_HERSHEY_PLAIN,
230 """Draw a collection of points. 232 The point size is fixed to 1. 237 The Nx2 array of image locations, where the first dimension is 238 the x-coordinate and the second dimension is the y-coordinate. 239 colors : Optional[ndarray] 240 The Nx3 array of colors (dtype=np.uint8). If None, the current 241 color attribute is used. 242 skip_index_check : Optional[bool] 243 If True, index range checks are skipped. This is faster, but 244 requires all points to lie within the image dimensions. 247 if not skip_index_check:
248 cond1, cond2 = points[:, 0] >= 0, points[:, 0] < 480
249 cond3, cond4 = points[:, 1] >= 0, points[:, 1] < 640
250 indices = np.logical_and.reduce((cond1, cond2, cond3, cond4))
251 points = points[indices, :]
254 self.
_color, len(points)).reshape(3, len(points)).T
255 indices = (points + .5).astype(np.int)
256 self.
image[indices[:, 1], indices[:, 0], :] = colors
260 """ Write images to video file. 264 output_filename : str 267 The OpenCV FOURCC code that defines the video codec (check OpenCV 268 documentation for more information). 269 fps : Optional[float] 270 Frames per second. If None, configured according to current 274 fourcc = cv2.VideoWriter_fourcc(*fourcc_string)
281 """ Disable writing videos. 285 def run(self, update_fun=None):
286 """Start the image viewer. 288 This method blocks until the user requests to close the window. 292 update_fun : Optional[Callable[] -> None] 293 An optional callable that is invoked at each frame. May be used 294 to play an animation/a video sequence. 297 if update_fun
is not None:
307 self._video_writer.write(
313 key = cv2.waitKey(remaining_time)
317 elif key & 255 == 32:
318 print(
"toggeling pause: " + str(
not is_paused))
319 is_paused =
not is_paused
320 elif key & 255 == 115:
336 """Stop the control loop. 338 After calling this method, the viewer will stop execution before the 339 next frame and hand over control flow to the user.
def colored_points(self, points, colors=None, skip_index_check=False)
def is_in_bounds(mat, roi)
def enable_videowriter(self, output_filename, fourcc_string="MJPG", fps=None)
def disable_videowriter(self)
def run(self, update_fun=None)
def circle(self, x, y, radius, label=None)
def __init__(self, update_ms, window_shape=(640, 480), caption="Figure 1")
def gaussian(self, mean, covariance, label=None)
def annotate(self, x, y, text)
def rectangle(self, x, y, w, h, label=None)