from typing import Optional, Iterable import cv2 import numpy as np import util as abu from data.xhdfs import MIN_PIXEL_VALUE, MAX_PIXEL_VALUE _WHITE = 255 def to_8_bit_image(src_image: np.ndarray, display_min: Optional[int] = None, display_max: Optional[int] = None) -> np.ndarray: """Copies the image and normalizes pixel values to [0; 255]. See https://stackoverflow.com/questions/14464449/using-numpy-to-efficiently-convert-16-bit-image-data-to-8-bit-for-display-with""" if src_image.dtype == np.uint8: # Do nothing with images that are already 8-bit return src_image copy = np.array(src_image, copy=True) # Clip pixel values if necessary need_to_clip = display_min is not None or display_max is not None if display_min is None: display_min = MIN_PIXEL_VALUE if display_max is None: display_max = MAX_PIXEL_VALUE if need_to_clip: copy.clip(display_min, display_max, out=copy) copy -= display_min np.floor_divide(copy, (display_max - display_min + 1) / 256, out=copy, casting='unsafe') return copy.astype(np.uint8) def imshow_xhdfs_frame(frame: np.ndarray, window_name: Optional[str] = None, color_map: Optional[int] = None, display_min: Optional[int] = None, display_max: Optional[int] = None) -> None: frame_as_8_bit = to_8_bit_image(frame, display_min=display_min, display_max=display_max) if color_map: frame_as_8_bit = cv2.applyColorMap(frame_as_8_bit, color_map) if not window_name: window_name = __name__ cv2.imshow(window_name, frame_as_8_bit) del frame_as_8_bit def box_mask(box_points: Iterable[abu.FloatPoint], image_width: Optional[int] = None, image_height: Optional[int] = None) -> np.ndarray: image_width = image_width or abu.FRAME_WIDTH # FIXME: hard-coded dimensions image_height = image_height or abu.FRAME_HEIGHT mask = np.zeros(shape=(image_height, image_width), dtype=np.uint8) box_corners = np.asarray(box_points, dtype=np.int32) cv2.fillConvexPoly(mask, box_corners, _WHITE) return mask