def imread(img_or_path, flag='color', channel_order='bgr'): """Read an image. Args: img_or_path (ndarray or str): Either a numpy array or image path. If it is a numpy array (loaded image), then it will be returned as is. flag (str): Flags specifying the color type of a loaded image, candidates are `color`, `grayscale` and `unchanged`. Note that the `turbojpeg` backened does not support `unchanged`. channel_order (str): Order of channel, candidates are `bgr` and `rgb`. Returns: ndarray: Loaded image array. """ if isinstance(img_or_path, np.ndarray): return img_or_path elif is_str(img_or_path): check_file_exist(img_or_path, 'img file does not exist: {}'.format(img_or_path)) if imread_backend == 'turbojpeg': with open(img_or_path, 'rb') as in_file: img = jpeg.decode(in_file.read(), _jpegflag(flag, channel_order)) if img.shape[-1] == 1: img = img[:, :, 0] return img else: flag = imread_flags[flag] if is_str(flag) else flag img = cv2.imread(img_or_path, flag) if flag == IMREAD_COLOR and channel_order == 'rgb': cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) return img else: raise TypeError('"img" must be a numpy array or a filename')
def philly_imread(self, img_or_path, flag='color'): if isinstance(img_or_path, np.ndarray): return img_or_path elif is_str(img_or_path): flag = imread_flags[flag] if is_str(flag) else flag # check_file_exist(img_or_path, 'img file does not exist: {}'.format(img_or_path)) return phillyzip_imread(img_or_path, flag) else: raise TypeError('"img" must be a numpy array or a filename')
def imread(img_or_path, flag='color', channel_order='bgr', backend=None): """Read an image. Args: img_or_path (ndarray or str or Path): Either a numpy array or str or pathlib.Path. If it is a numpy array (loaded image), then it will be returned as is. flag (str): Flags specifying the color type of a loaded image, candidates are `color`, `grayscale` and `unchanged`. Note that the `turbojpeg` backened does not support `unchanged`. channel_order (str): Order of channel, candidates are `bgr` and `rgb`. backend (str | None): The image decoding backend type. Options are `cv2`, `pillow`, `turbojpeg`, `tifffile`, `None`. If backend is None, the global imread_backend specified by ``mmcv.use_backend()`` will be used. Default: None. Returns: ndarray: Loaded image array. """ if backend is None: backend = imread_backend if backend not in supported_backends: raise ValueError(f'backend: {backend} is not supported. Supported ' "backends are 'cv2', 'turbojpeg', 'pillow'") if isinstance(img_or_path, Path): img_or_path = str(img_or_path) if isinstance(img_or_path, np.ndarray): return img_or_path elif is_str(img_or_path): check_file_exist(img_or_path, f'img file does not exist: {img_or_path}') if backend == 'turbojpeg': with open(img_or_path, 'rb') as in_file: img = jpeg.decode(in_file.read(), _jpegflag(flag, channel_order)) if img.shape[-1] == 1: img = img[:, :, 0] return img elif backend == 'pillow': img = Image.open(img_or_path) img = _pillow2array(img, flag, channel_order) return img elif backend == 'tifffile': img = tifffile.imread(img_or_path) return img else: flag = imread_flags[flag] if is_str(flag) else flag img = cv2.imread(img_or_path, flag) if flag == IMREAD_COLOR and channel_order == 'rgb': cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) return img else: raise TypeError('"img" must be a numpy array or a str or ' 'a pathlib.Path object')
def imread(path, flag='color'): zip_path, path_img = ZipReader.split_zip_style_path(path) zfile = ZipReader.get_zipfile(zip_path) data = zfile.read(path_img) flag = imread_flags[flag] if is_str(flag) else flag im = cv2.imdecode(np.frombuffer(data, np.uint8), flag) return im
def color_val(color): """Convert various input to color tuples. Args: color (:obj:`Color`/str/tuple/int/ndarray): Color inputs Returns: tuple[int]: A tuple of 3 integers indicating BGR channels. """ if is_str(color): return Color[color].value elif isinstance(color, Color): return color.value elif isinstance(color, tuple): assert len(color) == 3 for channel in color: assert channel >= 0 and channel <= 255 return color elif isinstance(color, int): assert color >= 0 and color <= 255 return color, color, color elif isinstance(color, np.ndarray): assert color.ndim == 1 and color.size == 3 assert np.all((color >= 0) & (color <= 255)) color = color.astype(np.uint8) return tuple(color) else: raise TypeError('Invalid type for color: {}'.format(type(color)))
def color_val(color=None): if is_str(color): color = color[0].upper() + color[1:].lower() return list(COLORS[color])[::-1] elif color == None: color_name = random.choice(list(COLORS.keys())) return list(COLORS[color_name])[::-1] elif type(color) == int: return list(COLORS[list(COLORS.keys())[color]])[::-1] else: return list(COLORS['Red'])[::-1]
def color_val(color = None): # COLORS = {k: v for k, v in sorted(COLORS.items(), key=lambda item: item[0])} if is_str(color): color = color[0].upper() + color[1:].lower() return list(COLORS[color])[::-1] elif color == None: color_name = random.choice(list(COLORS.keys())) return list(COLORS[color_name])[::-1] elif type(color) == int: return list(COLORS[list(COLORS.keys())[color]])[::-1] else: return list(COLORS['Red'])[::-1]
def imfrombytes(content, flag='color', channel_order='bgr', backend=None): """Read an image from bytes. Args: content (bytes): Image bytes got from files or other streams. flag (str): Same as :func:`imread`. channel_order (str): The channel order of the output, candidates are 'bgr' and 'rgb'. Default to 'bgr'. backend (str | None): The image decoding backend type. Options are `cv2`, `pillow`, `turbojpeg`, `tifffile`, `None`. If backend is None, the global imread_backend specified by ``mmcv.use_backend()`` will be used. Default: None. Returns: ndarray: Loaded image array. Examples: >>> img_path = '/path/to/img.jpg' >>> with open(img_path, 'rb') as f: >>> img_buff = f.read() >>> img = mmcv.imfrombytes(img_buff) >>> img = mmcv.imfrombytes(img_buff, flag='color', channel_order='rgb') >>> img = mmcv.imfrombytes(img_buff, backend='pillow') >>> img = mmcv.imfrombytes(img_buff, backend='cv2') """ if backend is None: backend = imread_backend if backend not in supported_backends: raise ValueError( f'backend: {backend} is not supported. Supported ' "backends are 'cv2', 'turbojpeg', 'pillow', 'tifffile'") if backend == 'turbojpeg': img = jpeg.decode(content, _jpegflag(flag, channel_order)) if img.shape[-1] == 1: img = img[:, :, 0] return img elif backend == 'pillow': with io.BytesIO(content) as buff: img = Image.open(buff) img = _pillow2array(img, flag, channel_order) return img elif backend == 'tifffile': with io.BytesIO(content) as buff: img = tifffile.imread(buff) return img else: img_np = np.frombuffer(content, np.uint8) flag = imread_flags[flag] if is_str(flag) else flag img = cv2.imdecode(img_np, flag) if flag == IMREAD_COLOR and channel_order == 'rgb': cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) return img
def imread(img_or_path, flag='color'): """Read an image. Args: img_or_path (ndarray or str): Either a numpy array or image path. If it is a numpy array (loaded image), then it will be returned as is. flag (str): Flags specifying the color type of a loaded image, candidates are `color`, `grayscale` and `unchanged`. Returns: ndarray: Loaded image array. """ if isinstance(img_or_path, np.ndarray): return img_or_path elif is_str(img_or_path): flag = imread_flags[flag] if is_str(flag) else flag check_file_exist(img_or_path, 'img file does not exist: {}'.format(img_or_path)) return cv2.imread(img_or_path, flag) else: raise TypeError('"img" must be a numpy array or a filename')
def flowread(flow_or_path, quantize=False, concat_axis=0, *args, **kwargs): """Read an optical flow map. Args: flow_or_path (ndarray or str): A flow map or filepath. quantize (bool): whether to read quantized pair, if set to True, remaining args will be passed to :func:`dequantize_flow`. concat_axis (int): The axis that dx and dy are concatenated, can be either 0 or 1. Ignored if quantize is False. Returns: ndarray: Optical flow represented as a (h, w, 2) numpy array """ if isinstance(flow_or_path, np.ndarray): if (flow_or_path.ndim != 3) or (flow_or_path.shape[-1] != 2): raise ValueError('Invalid flow with shape {}'.format( flow_or_path.shape)) return flow_or_path elif not is_str(flow_or_path): raise TypeError( '"flow_or_path" must be a filename or numpy array, not {}'.format( type(flow_or_path))) if not quantize: with open(flow_or_path, 'rb') as f: try: header = f.read(4).decode('utf-8') except Exception: raise IOError('Invalid flow file: {}'.format(flow_or_path)) else: if header != 'PIEH': raise IOError( 'Invalid flow file: {}, header does not contain PIEH'. format(flow_or_path)) w = np.fromfile(f, np.int32, 1).squeeze() h = np.fromfile(f, np.int32, 1).squeeze() flow = np.fromfile(f, np.float32, w * h * 2).reshape((h, w, 2)) else: assert concat_axis in [0, 1] cat_flow = imread(flow_or_path, flag='unchanged') if cat_flow.ndim != 2: raise IOError( '{} is not a valid quantized flow file, its dimension is {}.'. format(flow_or_path, cat_flow.ndim)) assert cat_flow.shape[concat_axis] % 2 == 0 dx, dy = np.split(cat_flow, 2, axis=concat_axis) flow = dequantize_flow(dx, dy, *args, **kwargs) return flow.astype(np.float32)
def imfrombytes(content, flag='color'): """Read an image from bytes. Args: content (bytes): Image bytes got from files or other streams. flag (str): Same as :func:`imread`. Returns: ndarray: Loaded image array. """ img_np = np.frombuffer(content, np.uint8) flag = imread_flags[flag] if is_str(flag) else flag img = cv2.imdecode(img_np, flag) return img
def flowread(flow_or_path, quantize=False, concat_axis=0, *args, **kwargs): 'Read an optical flow map.\n\n Args:\n flow_or_path (ndarray or str): A flow map or filepath.\n quantize (bool): whether to read quantized pair, if set to True,\n remaining args will be passed to :func:`dequantize_flow`.\n concat_axis (int): The axis that dx and dy are concatenated,\n can be either 0 or 1. Ignored if quantize is False.\n\n Returns:\n ndarray: Optical flow represented as a (h, w, 2) numpy array\n ' if isinstance(flow_or_path, np.ndarray): if ((flow_or_path.ndim != 3) or (flow_or_path.shape[(-1)] != 2)): raise ValueError(''.join( ['Invalid flow with shape ', '{}'.format(flow_or_path.shape)])) return flow_or_path elif (not is_str(flow_or_path)): raise TypeError(''.join([ '"flow_or_path" must be a filename or numpy array, not ', '{}'.format(type(flow_or_path)) ])) if (not quantize): with open(flow_or_path, 'rb') as f: try: header = f.read(4).decode('utf-8') except Exception: raise IOError(''.join( ['Invalid flow file: ', '{}'.format(flow_or_path)])) else: if (header != 'PIEH'): raise IOError(''.join([ 'Invalid flow file: ', '{}'.format(flow_or_path), ', header does not contain PIEH' ])) w = np.fromfile(f, np.int32, 1).squeeze() h = np.fromfile(f, np.int32, 1).squeeze() flow = np.fromfile(f, np.float32, ((w * h) * 2)).reshape((h, w, 2)) else: assert (concat_axis in [0, 1]) cat_flow = imread(flow_or_path, flag='unchanged') if (cat_flow.ndim != 2): raise IOError(''.join([ '{}'.format(flow_or_path), ' is not a valid quantized flow file, its dimension is ', '{}'.format(cat_flow.ndim), '.' ])) assert ((cat_flow.shape[concat_axis] % 2) == 0) (dx, dy) = np.split(cat_flow, 2, axis=concat_axis) flow = dequantize_flow(dx, dy, *args, **kwargs) return flow.astype(np.float32)
def imfrombytes(content, flag='color', channel_order='bgr'): """Read an image from bytes. Args: content (bytes): Image bytes got from files or other streams. flag (str): Same as :func:`imread`. Returns: ndarray: Loaded image array. """ if imread_backend == 'turbojpeg': img = jpeg.decode(content, _jpegflag(flag, channel_order)) if img.shape[-1] == 1: img = img[:, :, 0] return img else: img_np = np.frombuffer(content, np.uint8) flag = imread_flags[flag] if is_str(flag) else flag img = cv2.imdecode(img_np, flag) if flag == IMREAD_COLOR and channel_order == 'rgb': cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) return img
def imfrombytes(content, flag='color', channel_order='bgr', backend=None): """Read an image from bytes. Args: content (bytes): Image bytes got from files or other streams. flag (str): Same as :func:`imread`. backend (str | None): The image decoding backend type. Options are `cv2`, `pillow`, `turbojpeg`, `None`. If backend is None, the global imread_backend specified by ``mmcv.use_backend()`` will be used. Default: None. Returns: ndarray: Loaded image array. """ if backend is None: backend = imread_backend if backend not in supported_backends: raise ValueError("backend: %s is not supported. Supported backends are 'cv2', 'turbojpeg', 'pillow'"%backend) if backend == 'turbojpeg': img = jpeg.decode(content, _jpegflag(flag, channel_order)) if img.shape[-1] == 1: img = img[:, :, 0] return img elif backend == 'pillow': buff = io.BytesIO(content) img = Image.open(buff) img = _pillow2array(img, flag, channel_order) return img else: img_np = np.frombuffer(content, np.uint8) flag = imread_flags[flag] if is_str(flag) else flag img = cv2.imdecode(img_np, flag) if flag == IMREAD_COLOR and channel_order == 'rgb': cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img) return img
def imread(img_or_path, flag='color', channel_order='bgr', backend=None, file_client_args=None): """Read an image. Note: In v1.4.1 and later, add `file_client_args` parameters. Args: img_or_path (ndarray or str or Path): Either a numpy array or str or pathlib.Path. If it is a numpy array (loaded image), then it will be returned as is. flag (str): Flags specifying the color type of a loaded image, candidates are `color`, `grayscale`, `unchanged`, `color_ignore_orientation` and `grayscale_ignore_orientation`. By default, `cv2` and `pillow` backend would rotate the image according to its EXIF info unless called with `unchanged` or `*_ignore_orientation` flags. `turbojpeg` and `tifffile` backend always ignore image's EXIF info regardless of the flag. The `turbojpeg` backend only supports `color` and `grayscale`. channel_order (str): Order of channel, candidates are `bgr` and `rgb`. backend (str | None): The image decoding backend type. Options are `cv2`, `pillow`, `turbojpeg`, `tifffile`, `None`. If backend is None, the global imread_backend specified by ``mmcv.use_backend()`` will be used. Default: None. file_client_args (dict | None): Arguments to instantiate a FileClient. See :class:`mmcv.fileio.FileClient` for details. Default: None. Returns: ndarray: Loaded image array. Examples: >>> import mmcv >>> img_path = '/path/to/img.jpg' >>> img = mmcv.imread(img_path) >>> img = mmcv.imread(img_path, flag='color', channel_order='rgb', ... backend='cv2') >>> img = mmcv.imread(img_path, flag='color', channel_order='bgr', ... backend='pillow') >>> s3_img_path = 's3://bucket/img.jpg' >>> # infer the file backend by the prefix s3 >>> img = mmcv.imread(s3_img_path) >>> # manually set the file backend petrel >>> img = mmcv.imread(s3_img_path, file_client_args={ ... 'backend': 'petrel'}) >>> http_img_path = 'http://path/to/img.jpg' >>> img = mmcv.imread(http_img_path) >>> img = mmcv.imread(http_img_path, file_client_args={ ... 'backend': 'http'}) """ if isinstance(img_or_path, Path): img_or_path = str(img_or_path) if isinstance(img_or_path, np.ndarray): return img_or_path elif is_str(img_or_path): file_client = FileClient.infer_client(file_client_args, img_or_path) img_bytes = file_client.get(img_or_path) return imfrombytes(img_bytes, flag, channel_order, backend) else: raise TypeError('"img" must be a numpy array or a str or ' 'a pathlib.Path object')
def imshow_rbboxes(img_or_path, rbboxes, labels=None, scores=None, score_threshold=0.0, colors='red', show_label=False, show_score=False, thickness=3, show=True, win_name='', wait_time=0, out_file=None, return_img=False): """ Draw oriented bounding boxes on image Args: img (str or ndarray): The image to be displayed. rbboxes (list or ndarray): A ndarray of shape (N, 8) labels (list or ndarray): A ndarray of shape (N, 1) scores (list or ndarray): A ndarray of shape (N, 1) """ if is_str(img_or_path): img = cv2.imread(img_or_path) else: img = img_or_path if rbboxes == []: return if isinstance(rbboxes, list): rbboxes = np.array(rbboxes) if rbboxes.shape[1] == 5: rbboxes_ = [] for rbbox in rbboxes: rbboxes_.append(thetaobb2pointobb(rbbox)) rbboxes = np.array(rbboxes_) if rbboxes.ndim == 1: rbboxes = np.array([rbboxes]) if labels is None: labels_vis = np.array(['ins'] * rbboxes.shape[0]) else: labels_vis = np.array(labels) if labels_vis.ndim == 0: labels_vis = np.array([labels_vis]) if scores is None: scores_vis = np.array([1.0] * rbboxes.shape[0]) else: scores_vis = np.array(scores) if scores_vis.ndim == 0: scores_vis = np.array([scores_vis]) if labels is None: colors = dict() colors[colors] = color_val(colors) else: max_label = max(labels) colors = [color_val(_) for _ in range(max_label + 1)] for rbbox, label, score in zip(rbboxes, labels_vis, scores_vis): if score < score_threshold: continue if len(rbbox) == 5: rbbox = np.array(thetaobb2pointobb(rbbox)) rbbox = rbbox.astype(np.int32) cx = np.mean(rbbox[::2]) cy = np.mean(rbbox[1::2]) current_color = colors[label] for idx in range(-1, 3, 1): cv2.line( img, (int(rbbox[idx * 2]), int(rbbox[idx * 2 + 1])), (int(rbbox[(idx + 1) * 2]), int(rbbox[(idx + 1) * 2 + 1])), current_color, thickness=thickness) if show_label: cv2.putText(img, label, (cx, cy), cv2.FONT_HERSHEY_COMPLEX_SMALL, fontScale=1.0, color=current_color, thickness=2, lineType=8) if show_score: cv2.putText(img, "{:.2f}".format(score), (cx, cy), cv2.FONT_HERSHEY_COMPLEX_SMALL, fontScale=1.0, color=current_color, thickness=2, lineType=8) if show: cv2.namedWindow(win_name, cv2.WINDOW_NORMAL) cv2.imshow(win_name, img) cv2.waitKey(wait_time) if out_file is not None: dir_name = osp.abspath(osp.dirname(out_file)) mkdir_or_exist(dir_name) cv2.imwrite(out_file, img) if return_img: return img
def imshow_bboxes(img_or_path, bboxes, labels=None, scores=None, score_threshold=0.0, colors='red', show_label=False, show_score=False, thickness=3, show=True, win_name='', wait_time=0, out_file=None, origin_file=None, return_img=False): """ Draw horizontal bounding boxes on image Args: img (str or ndarray): The image to be displayed. bboxes (list or ndarray): A ndarray of shape (N, 4) labels (list or ndarray): A ndarray of shape (N, 1) scores (list or ndarray): A ndarray of shape (N, 1) """ if is_str(img_or_path): img = cv2.imread(img_or_path) img_origin = img.copy() else: img = img_or_path img_origin = img.copy() if len(bboxes) == []: return if isinstance(bboxes, list): bboxes = np.array(bboxes) if bboxes.ndim == 1: bboxes = np.array([bboxes]) if labels is None: labels_vis = np.array(['ins'] * bboxes.shape[0]) else: labels_vis = np.array(labels) if labels_vis.ndim == 0: labels_vis = np.array([labels_vis]) if scores is None: scores_vis = np.array([1.0] * bboxes.shape[0]) else: scores_vis = np.array(scores) if scores_vis.ndim == 0: scores_vis = np.array([scores_vis]) if labels is None: colors = dict() colors[colors] = color_val(colors) else: max_label = max(labels) if max_label > 20: max_label = max_label % 20 colors = [color_val(_) for _ in range(max_label + 1)] for bbox, label, score in zip(bboxes, labels_vis, scores_vis): if score < score_threshold: continue bbox = bbox.astype(np.int32) xmin, ymin, xmax, ymax = bbox current_color = colors[label % 20] cv2.rectangle(img, (xmin, ymin), (xmax, ymax), color=current_color, thickness=thickness) if show_label: cv2.putText(img, label, (xmin, ymin - 5), cv2.FONT_HERSHEY_COMPLEX_SMALL, fontScale=1.0, color=current_color, thickness=2, lineType=8) if show_score: cv2.putText(img, "{:.2f}".format(score), (xmin, ymin - 5), cv2.FONT_HERSHEY_COMPLEX_SMALL, fontScale=1.0, color=current_color, thickness=2, lineType=8) if show: cv2.imshow(win_name, img) cv2.waitKey(wait_time) if out_file is not None: dir_name = osp.abspath(osp.dirname(out_file)) mkdir_or_exist(dir_name) cv2.imwrite(out_file, img) if origin_file is not None: dir_name = osp.abspath(osp.dirname(origin_file)) mkdir_or_exist(dir_name) cv2.imwrite(origin_file, img_origin) if return_img: return img
def imshow_bboxes(img_or_path, bboxes, labels=None, scores=None, score_threshold=0.0, show_label=False, show_score=False, thickness=2, show=False, win_name='', wait_time=0, out_file=None, origin_file=None, return_img=False): """ Draw horizontal bounding boxes on image Args: img (str or ndarray): The image to be displayed. bboxes (list or ndarray): A ndarray of shape (N, 4) labels (dict): {"category": idx} scores (list or ndarray): A ndarray of shape (N, 1) """ if is_str(img_or_path): img = cv2.imread(img_or_path) img_origin = img.copy() else: img = img_or_path img_origin = img.copy() if len(bboxes) == 0: return if isinstance(bboxes, list): bboxes = np.array(bboxes) if bboxes.ndim == 1: bboxes = np.array([bboxes]) if labels is None: labels_vis = np.array(['ins'] * bboxes.shape[0]) else: labels_vis = [list(label.keys())[0] for label in labels] class_idxs = [list(label.values())[0] for label in labels] max_label_idx = max(class_idxs) if max_label_idx > 20: max_label_idx = max_label_idx % 20 color_dict = { list(label.keys())[0]: color_val(list(label.values())[0]) for label in labels } if scores is None: scores_vis = np.array([1.0] * bboxes.shape[0]) else: scores_vis = np.array(scores) if scores_vis.ndim == 0: scores_vis = np.array([scores_vis]) for bbox, label, score in zip(bboxes, labels_vis, scores_vis): if score < score_threshold: continue bbox = bbox.astype(np.int32) xmin, ymin, xmax, ymax = bbox if labels is None: current_color = color_val() else: current_color = color_dict[label] cv2.rectangle(img, (xmin, ymin), (xmax, ymax), color=current_color, thickness=thickness) if show_label: cv2.putText(img, label, (xmin, ymin - 5), cv2.FONT_HERSHEY_COMPLEX_SMALL, fontScale=1.0, color=current_color, thickness=2, lineType=8) if show_score: cv2.putText(img, "{:.2f}".format(score), (xmin, ymin - 5), cv2.FONT_HERSHEY_COMPLEX_SMALL, fontScale=1.0, color=current_color, thickness=2, lineType=8) if show: # cv2.namedWindow(win_name, cv2.WINDOW_NORMAL) # cv2.resizeWindow(win_name, 360, 360) cv2.imshow(win_name, img) cv2.waitKey(wait_time) if out_file is not None: dir_name = osp.abspath(osp.dirname(out_file)) mkdir_or_exist(dir_name) cv2.imwrite(out_file, img) if origin_file is not None: dir_name = osp.abspath(osp.dirname(origin_file)) mkdir_or_exist(dir_name) cv2.imwrite(origin_file, img_origin) if return_img: return img