# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import cv2 import numpy as np from PIL import Image as PILImage def visualize(image, result, color_map, save_dir=None, weight=0.6): """ Convert predict result to color image, and save added image. Args: image (str): The path of origin image. result (np.ndarray): The predict result of image. color_map (list): The color used to save the prediction results. save_dir (str): The directory for saving visual image. Default: None. weight (float): The image weight of visual image, and the result weight is (1 - weight). Default: 0.6 Returns: vis_result (np.ndarray): If `save_dir` is None, return the visualized result. """ color_map = [color_map[i:i + 3] for i in range(0, len(color_map), 3)] color_map = np.array(color_map).astype("uint8") # Use OpenCV LUT for color mapping c1 = cv2.LUT(result, color_map[:, 0]) c2 = cv2.LUT(result, color_map[:, 1]) c3 = cv2.LUT(result, color_map[:, 2]) pseudo_img = np.dstack((c3, c2, c1)) im = cv2.imread(image) vis_result = cv2.addWeighted(im, weight, pseudo_img, 1 - weight, 0) if save_dir is not None: if not os.path.exists(save_dir): os.makedirs(save_dir) image_name = os.path.split(image)[-1] out_path = os.path.join(save_dir, image_name) cv2.imwrite(out_path, vis_result) else: return vis_result def get_pseudo_color_map(pred, color_map=None): """ Get the pseudo color image. Args: pred (numpy.ndarray): the origin predicted image. color_map (list, optional): the palette color map. Default: None, use paddleseg's default color map. Returns: (numpy.ndarray): the pseduo image. """ pred_mask = PILImage.fromarray(pred.astype(np.uint8), mode='P') if color_map is None: color_map = get_color_map_list(256) pred_mask.putpalette(color_map) return pred_mask def get_color_map_list(num_classes, custom_color=None): """ Returns the color map for visualizing the segmentation mask, which can support arbitrary number of classes. Args: num_classes (int): Number of classes. custom_color (list, optional): Save images with a custom color map. Default: None, use paddleseg's default color map. Returns: (list). The color map. """ num_classes += 1 color_map = num_classes * [0, 0, 0] for i in range(0, num_classes): j = 0 lab = i while lab: color_map[i * 3] |= (((lab >> 0) & 1) << (7 - j)) color_map[i * 3 + 1] |= (((lab >> 1) & 1) << (7 - j)) color_map[i * 3 + 2] |= (((lab >> 2) & 1) << (7 - j)) j += 1 lab >>= 3 color_map = color_map[3:] if custom_color: color_map[:len(custom_color)] = custom_color return color_map def paste_images(image_list): """ Paste all image to a image. Args: image_list (List or Tuple): The images to be pasted and their size are the same. Returns: result_img (PIL.Image): The pasted image. """ assert isinstance(image_list, (list, tuple)), "image_list should be a list or tuple" assert len( image_list) > 1, "The length of image_list should be greater than 1" pil_img_list = [] for img in image_list: if isinstance(img, str): assert os.path.exists(img), "The image is not existed: {}".format( img) img = PILImage.open(img) img = np.array(img) elif isinstance(img, np.ndarray): img = PILImage.fromarray(img) pil_img_list.append(img) sample_img = pil_img_list[0] size = sample_img.size for img in pil_img_list: assert size == img.size, "The image size in image_list should be the same" width, height = sample_img.size result_img = PILImage.new(sample_img.mode, (width * len(pil_img_list), height)) for i, img in enumerate(pil_img_list): result_img.paste(img, box=(width * i, 0)) return result_img