| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- # copytrue (c) 2020 PaddlePaddle Authors. All Rights Reserve.
- #
- # 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.
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
- import numpy as np
- import cv2
- import math
- import xml.etree.ElementTree as ET
- from PIL import Image
- def resize_img(img):
- """ 调整图片尺寸
- Args:
- img: 图片信息
- """
- h, w = img.shape[:2]
- min_size = 580
- if w >= h and w > min_size:
- new_w = min_size
- new_h = new_w * h / w
- elif h >= w and h > min_size:
- new_h = min_size
- new_w = new_h * w / h
- else:
- new_h = h
- new_w = w
- new_img = cv2.resize(
- img, (int(new_w), int(new_h)), interpolation=cv2.INTER_CUBIC)
- scale_value = new_w / w
- return new_img, scale_value
- def plot_det_label(image, anno, labels):
- """ 目标检测类型生成标注图
- Args:
- image: 图片路径
- anno: 图片标注
- labels: 图片所属数据集的类别信息
- """
- catid2color = {}
- img = cv2.imread(image)
- img, scale_value = resize_img(img)
- tree = ET.parse(anno)
- objs = tree.findall('object')
- color_map = get_color_map_list(len(labels) + 1)
- for i, obj in enumerate(objs):
- cname = obj.find('name').text
- catid = labels.index(cname)
- if cname not in labels:
- continue
- xmin = int(float(obj.find('bndbox').find('xmin').text) * scale_value)
- ymin = int(float(obj.find('bndbox').find('ymin').text) * scale_value)
- xmax = int(float(obj.find('bndbox').find('xmax').text) * scale_value)
- ymax = int(float(obj.find('bndbox').find('ymax').text) * scale_value)
- if catid not in catid2color:
- catid2color[catid] = color_map[catid + 1]
- color = tuple(catid2color[catid])
- img = draw_rectangle_and_cname(img, xmin, ymin, xmax, ymax, cname,
- color)
- return img
- def plot_seg_label(anno):
- """ 语义分割类型生成标注图
- Args:
- anno: 图片标注
- """
- label = pil_imread(anno)
- pse_label = gray2pseudo(label)
- return pse_label
- def plot_insseg_label(image, anno, labels, alpha=0.7):
- """ 实例分割类型生成标注图
- Args:
- image: 图片路径
- anno: 图片标注
- labels: 图片所属数据集的类别信息
- """
- anno = np.load(anno, allow_pickle=True).tolist()
- catid2color = dict()
- img = cv2.imread(image)
- img, scale_value = resize_img(img)
- color_map = get_color_map_list(len(labels) + 1)
- img_h = anno['h']
- img_w = anno['w']
- gt_class = anno['gt_class']
- gt_bbox = anno['gt_bbox']
- gt_poly = anno['gt_poly']
- num_bbox = gt_bbox.shape[0]
- num_mask = len(gt_poly)
- # 描绘mask信息
- img_array = np.array(img).astype('float32')
- for i in range(num_mask):
- cname = gt_class[i]
- catid = labels.index(cname)
- if cname not in labels:
- continue
- if catid not in catid2color:
- catid2color[catid] = color_map[catid + 1]
- color = np.array(catid2color[catid]).astype('float32')
- import pycocotools.mask as mask_util
- for x in range(len(gt_poly[i])):
- for y in range(len(gt_poly[i][x])):
- gt_poly[i][x][y] = int(float(gt_poly[i][x][y]) * scale_value)
- poly = gt_poly[i]
- rles = mask_util.frPyObjects(poly,
- int(float(img_h) * scale_value),
- int(float(img_w) * scale_value))
- rle = mask_util.merge(rles)
- mask = mask_util.decode(rle) * 255
- idx = np.nonzero(mask)
- img_array[idx[0], idx[1], :] *= 1.0 - alpha
- img_array[idx[0], idx[1], :] += alpha * color
- img = img_array.astype('uint8')
- for i in range(num_bbox):
- cname = gt_class[i]
- catid = labels.index(cname)
- if cname not in labels:
- continue
- if catid not in catid2color:
- catid2color[catid] = color_map[catid]
- color = tuple(catid2color[catid])
- xmin, ymin, xmax, ymax = gt_bbox[i]
- img = draw_rectangle_and_cname(img,
- int(float(xmin) * scale_value),
- int(float(ymin) * scale_value),
- int(float(xmax) * scale_value),
- int(float(ymax) * scale_value), cname,
- color)
- return img
- def draw_rectangle_and_cname(img, xmin, ymin, xmax, ymax, cname, color):
- """ 根据提供的标注信息,给图片描绘框体和类别显示
- Args:
- img: 图片路径
- xmin: 检测框最小的x坐标
- ymin: 检测框最小的y坐标
- xmax: 检测框最大的x坐标
- ymax: 检测框最大的y坐标
- cname: 类别信息
- color: 类别与颜色的对应信息
- """
- # 描绘检测框
- line_width = math.ceil(2 * max(img.shape[0:2]) / 600)
- cv2.rectangle(
- img,
- pt1=(xmin, ymin),
- pt2=(xmax, ymax),
- color=color,
- thickness=line_width)
- # 计算并描绘类别信息
- text_thickness = math.ceil(2 * max(img.shape[0:2]) / 1200)
- fontscale = math.ceil(0.5 * max(img.shape[0:2]) / 600)
- tw, th = cv2.getTextSize(
- cname, 0, fontScale=fontscale, thickness=text_thickness)[0]
- cv2.rectangle(
- img,
- pt1=(xmin + 1, ymin - th),
- pt2=(xmin + int(0.7 * tw) + 1, ymin),
- color=color,
- thickness=-1)
- cv2.putText(
- img,
- cname, (int(xmin) + 3, int(ymin) - 5),
- 0,
- 0.6 * fontscale, (255, 255, 255),
- lineType=cv2.LINE_AA,
- thickness=text_thickness)
- return img
- def pil_imread(file_path):
- """ 将图片读成np格式数据
- Args:
- file_path: 图片路径
- """
- img = Image.open(file_path)
- return np.asarray(img)
- def get_color_map_list(num_classes):
- """ 为类别信息生成对应的颜色列表
- Args:
- num_classes: 类别数量
- """
- 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[i:i + 3] for i in range(0, len(color_map), 3)]
- return color_map
- def gray2pseudo(gray_image):
- """ 将分割的结果映射到图片
- Args:
- gray_image: 灰度图
- """
- color_map = get_color_map_list(256)
- color_map = np.array(color_map).astype("uint8")
- # 用OpenCV进行色彩映射
- c1 = cv2.LUT(gray_image, color_map[:, 0])
- c2 = cv2.LUT(gray_image, color_map[:, 1])
- c3 = cv2.LUT(gray_image, color_map[:, 2])
- pseudo_img = np.dstack((c1, c2, c3))
- return pseudo_img
|