def colorFillImg(self, img): h, w = img.shape[:2] if h < self.min_block_size or w < self.min_block_size: mode = random.choice(self.mode_list) if mode == "origin": return img elif mode == "pure": bg_color = random.choice(self.fillcolors) r_channel = np.ones(img.shape[:2], dtype=np.uint8) * bg_color[0] g_channel = np.ones(img.shape[:2], dtype=np.uint8) * bg_color[1] b_channel = np.ones(img.shape[:2], dtype=np.uint8) * bg_color[2] pure = cv2.merge((b_channel, g_channel, r_channel)) return pure elif mode == "image": filled_img = cv2.imread(os.path.join(self.images_dir, self.images[np.random.randint(0, self.images_num)])) return cv2.resize(filled_img, (img.shape[1], img.shape[0])) else: LOG.logE("colorFillImg mode error: {} not in ['origin', 'pure', 'image']".format(mode)) max_side = max(h, w) borderline = np.random.randint(int(max_side/self.split_ratio), int(2*max_side/self.split_ratio)) if h > w: img_top = self.colorFillImg(img[0:borderline, 0:w]) img_bottom = self.colorFillImg(img[borderline:h, 0:w]) img_res = np.vstack([img_top, img_bottom]) else: img_left = self.colorFillImg(img[0:h, 0:borderline]) img_right = self.colorFillImg(img[0:h, borderline:w]) img_res = np.hstack([img_left, img_right]) return img_res
def forward(self, imgs): img, label, _, fn = imgs sample = self.composer(img).unsqueeze(0).to(self.device) with torch.no_grad(): pred_fusion, _, _ = self.net(sample) pred_resize = cv2.resize( pred_fusion.squeeze().cpu().numpy().argmax(0), (label.shape[1], label.shape[0]), interpolation=cv2.INTER_NEAREST) cls_iou = 0 for cls_idx in range(1, self.cls_num): mask_label = label == cls_idx if np.sum(mask_label) == 0: continue mask_pred = pred_resize == cls_idx tmp = np.sum(mask_label & mask_pred) / np.sum(mask_label | mask_pred) cls_iou += tmp try: mean_iou = cls_iou / (len(np.unique(label)) - 1) except Exception as e: LOG.logE( "{} has no annotation yet. Please remove it from dataset.") mean_iou = 0 if mean_iou < self.min_iou: LOG.logI("Image {} has risk on rule {} with cls_iou = {}".format( fn, self.name(), mean_iou)) self.write(img, label, fn) return imgs
def _accumulateMeanStd(self, image_path, label_path): img_file = os.path.join(self.sample_path_prefix, image_path.strip()) label_file = os.path.join(self.sample_path_prefix, label_path.strip()) label_img = self._buildLabelFromPath(label_file) unique_values = np.unique(label_img) max_val = max(unique_values) min_val = min(unique_values) self.max_val_al = max(max_val, self.max_val_al) self.min_val_al = min(min_val, self.min_val_al) hist = np.histogram(label_img, self.classes) self.global_hist += hist[0] rgb_img = self._buildSampleFromPath(img_file) self.mean[0] += np.mean(rgb_img[:, :, 0]) self.mean[1] += np.mean(rgb_img[:, :, 1]) self.mean[2] += np.mean(rgb_img[:, :, 2]) self.std[0] += np.std(rgb_img[:, :, 0]) self.std[1] += np.std(rgb_img[:, :, 1]) self.std[2] += np.std(rgb_img[:, :, 2]) if max_val > (self.classes - 1) or min_val < 0: LOG.logE( 'Some problem with labels. Please check image file: {}. Labels can take value between 0 and number of classes {}.' .format(label_file, self.classes - 1), exit=True)
def __call__(self): if os.path.isfile(self.cached_data_file): return pickle.load(open(self.cached_data_file, "rb")) data = self.processData() if data is None: LOG.logE('Error while pickling data. Please check.', exit=True) LOG.logI('Process train dataset finished.') LOG.logI('Your train dataset mean: {}'.format(data['mean'])) LOG.logI('Your train dataset std: {}'.format(data['std'])) LOG.logI('Your train dataset classWeights: {}'.format( data['classWeights'])) return data
def _getImageAndLabelPathList(self): files = os.listdir(self.config.input_image_dir) for i, f in enumerate(files): if os.path.isdir(os.path.join(self.config.input_image_dir, f)): LOG.logE('{} is a dir, {} contain a sub dir, you must get rid of it.'.format(os.path.join(self.config.input_image_dir, f), self.config.input_image_dir), exit=True) if os.path.isdir(os.path.join(self.config.input_label_dir, f.replace('jpg', 'png'))): LOG.logE('{} is a dir, {} contain a sub dir, you must get rid of it.'.format(os.path.join(self.config.input_label_dir, f.replace('jpg', 'png')), self.config.input_label_dir), exit=True) if self.is_clothes_task and os.path.isdir(os.path.join(self.config.portrait_mask_output_dir, f.replace('jpg', 'png'))): LOG.logE('{} is a dir, {} contain a sub dir, you must get rid of it.'.format(os.path.join(self.config.portrait_mask_output_dir, f.replace('jpg', 'png')), self.config.portrait_mask_output_dir), exit=True) self.image_path_list.append(os.path.join(self.config.input_image_dir, f)) self.label_path_list.append(os.path.join(self.config.input_label_dir, f.replace('jpg', 'png'))) if self.is_clothes_task: self.human_mask_path_list.append(os.path.join(self.config.portrait_mask_output_dir, f.replace('jpg', 'png'))) LOG.logI('Length of image_path_list is {} ...'.format(len(self.image_path_list)))
from deepvac import LOG from deepvac.datasets import CocoCVSegDataset if __name__ == "__main__": from config import config json_path_glob = sys.argv[1] + "/*.json" json_paths = glob.glob(json_path_glob) sample_path_prefixs = [os.path.splitext(jp)[0] for jp in json_paths] LOG.logI("All json_paths: {} \n All sample_path_prefixs: {}".format( json_paths, sample_path_prefixs)) for sample_path_prefix, json_path in zip(sample_path_prefixs, json_paths): if not os.path.exists(sample_path_prefix): LOG.logE("Path {} not exists !".format(sample_path_prefix), exit=True) config.test_dataset = CocoCVSegDataset(config, sample_path_prefix, json_path, config.cat2idx) config.test_loader = torch.utils.data.DataLoader(config.test_dataset, batch_size=1, shuffle=False, num_workers=0, pin_memory=False) for idx, (img, label, _, file_path) in tqdm(enumerate(config.test_loader), total=config.test_loader.__len__()): continue LOG.logI("Json file {} analyze done!".format(json_path))
mask_hat = cv2.imread(fp) checkMask(mask_hat) fp = os.path.join(clothes_mask_dir, fn) mask_clothes = cv2.imread(fp) checkMask(mask_clothes) mask = np.clip(mask_hat + mask_clothes, 0, 3) cv2.imwrite(os.path.join(new_mask_dir, fn), mask) if __name__ == '__main__': from config import config import sys if len(sys.argv) != 2: LOG.logE("Usage: python synthesis.py <synthesis|perspect|fusion|flip>", exit=True) op = sys.argv[1] if op not in ('synthesis', 'perspect', 'fusion', 'flip'): LOG.logE("Usage: python synthesis.py <synthesis|perspect|fusion|flip>", exit=True) if op == 'synthesis': synthesis = Synthesis2D(config) synthesis() if op == 'perspect': perspect(config.perspect_image_dir, config.perspect_mask_dir, config.perspect_num)
def auditConfig(self): super(SynthesisText, self).auditConfig() self.lex = [] self.pil_img = None self.draw = None self.txt_file = self.conf.txt_file assert os.path.isfile(self.txt_file), "txt file {} not exist.".format( self.txt_file) with open(self.txt_file, 'r') as f: for line in f: line = line.rstrip() self.lex.append(line) random.shuffle(self.lex) self.lex_len = len(self.lex) self.fonts_dir = self.conf.fonts_dir if not os.path.exists(self.fonts_dir): raise Exception("Dir {} not found!".format(self.fonts_dir)) self.font_file_list = os.listdir(self.fonts_dir) self.font_num = len(self.font_file_list) if self.font_num == 0: raise Exception("No font was found in {}!".format(self.fonts_dir)) self.current_font_size = 50 self.max_font = 60 if self.conf.max_font is None else self.conf.max_font self.min_font = 15 if self.conf.min_font is None else self.conf.min_font self.crop_scale = 8 self.scene_hw = (1080, 1920) self.gb18030_font_file_list = [] for i, font_file in enumerate(self.font_file_list): LOG.logI("found font: {}:{}".format(i, font_file)) if font_file.startswith('gb18030'): LOG.logI("And this is a gb18030 font!") self.gb18030_font_file_list.append(font_file) self.runtime_fonts = dict() self.runtime_gb18030_fonts = dict() for font_size in range(self.min_font, self.max_font + 1): self.runtime_fonts[font_size] = [] for font_file in self.font_file_list: font = ImageFont.truetype(os.path.join(self.fonts_dir, font_file), font_size, encoding='utf-8') self.runtime_fonts[font_size].append(font) for font_size in range(self.min_font, self.max_font + 1): self.runtime_gb18030_fonts[font_size] = [] for font_file in self.gb18030_font_file_list: font = ImageFont.truetype(os.path.join(self.fonts_dir, font_file), font_size, encoding='utf-8') self.runtime_gb18030_fonts[font_size].append(font) self.support_fonts4char = {} with open(self.conf.chars, 'r') as f: line = f.readlines()[0][:-1] for c in line: self.support_fonts4char[c] = [] for idx, font_file in enumerate(self.font_file_list): font_table = self.getFontTables( os.path.join(self.fonts_dir, font_file)) for c in line: if self.hasGlyph(font_table, c): self.support_fonts4char[c].append(idx) elif font_file in self.gb18030_font_file_list: LOG.logE( '{} not supported in current font! Are you sure {} is a gb18030 font?' .format(c, font_file)) self.fg_color = [(10, 10, 10), (200, 10, 10), (10, 10, 200), (200, 200, 10), (255, 255, 255)] self.fg_color_len = len(self.fg_color) self.distance = 100 # The min distance of fg_color and bg_color self.s_width = 0 self.s_height = 0
from PIL import Image, ImageDraw, ImageFont import cv2 import numpy as np import os import random from deepvac import LOG from deepvac.aug.haishoku_helper import Haishoku try: from fontTools.ttLib import TTFont except: LOG.logE('no fonttools, pip install fonttools please', exit=True) class SynthesisBase(object): def __init__(self, deepvac_config): self.conf = deepvac_config self.auditConfig() def auditConfig(self): self.total_num = self.conf.total_num self.output_dir = self.conf.output_dir if not os.path.exists(self.output_dir): os.makedirs(self.output_dir) def __call__(): pass def dumpImgToPath(self, file_name, img): output_file_name = os.path.join(self.output_dir, file_name) try: cv2.imwrite(output_file_name, img)