text_rendering.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. from copy import copy
  2. from http.client import IM_USED
  3. import pathlib
  4. import shutil
  5. import PIL
  6. import cv2
  7. import numpy as np
  8. import os.path as osp
  9. import os
  10. from PIL import Image, ImageColor, ImageFont, ImageDraw, ImageFilter, ImageOps
  11. import random
  12. from numpy.random import rand
  13. from trdg.utils import load_dict, load_fonts
  14. from tqdm import tqdm
  15. import pandas as pd
  16. import sys
  17. sys.path.append(os.getcwd())
  18. from utils.io_utils import find_all_imgs, imread, imwrite
  19. from utils.imgproc_utils import *
  20. import copy
  21. ALIGN_LEFT = 0
  22. ALIGN_CENTER = 1
  23. ALIGN_RIGHT = 2
  24. ORIENTATION_HOR = 0
  25. ORIENTATION_VER = 1
  26. def get_textlines_from_langdict(lang_dict, num_line, line_len, sampler=None):
  27. textlines = []
  28. dict_len = len(lang_dict)
  29. for ii in range(num_line):
  30. line = ''
  31. for jj in range(line_len):
  32. line += lang_dict[random.randrange(dict_len)] + ' '
  33. textlines.append(line[:line_len])
  34. if sampler is None:
  35. return textlines
  36. return textlines
  37. def draw_text_polygons(img, text_polygons, color=None):
  38. if isinstance(img, PIL.Image.Image):
  39. img = np.array(img)
  40. img = np.copy(img)
  41. for poly in text_polygons:
  42. if color is None:
  43. randcolor = (random.randint(0,255), random.randint(0,255), random.randint(0,255))
  44. else:
  45. randcolor = color
  46. cv2.polylines(img,[poly.reshape((-1, 1, 2))],True,randcolor, thickness=2)
  47. return img
  48. def draw_textblk(textlines, font,
  49. fill='black',
  50. stroke_width=0,
  51. stroke_fill='grey',
  52. spacing=0,
  53. rotation=0,
  54. orientation=ORIENTATION_HOR,
  55. alignment=ALIGN_LEFT):
  56. text_size = np.array([font.getsize(line) for line in textlines])
  57. if orientation == ORIENTATION_HOR:
  58. line_widths, line_heights = text_size[:, 0], text_size[:, 1]
  59. textblk_w = max(text_size[:, 0]) + 3*stroke_width
  60. textblk_h = (len(textlines) - 1) * spacing + text_size[:, 1].sum() + 3*stroke_width
  61. else:
  62. line_widths, line_heights = text_size[:, 1], text_size[:, 0]
  63. textblk_w = line_widths.sum() + 3*stroke_width
  64. textblk_h = max(line_heights) + 3*stroke_width
  65. if orientation == ORIENTATION_VER:
  66. textblk_h += font.size * 3 # some fonts are not correctly aligned
  67. txtblk_img = Image.new("RGBA", (textblk_w, textblk_h), (255, 255, 255, 255))
  68. txtblk_draw = ImageDraw.Draw(txtblk_img)
  69. txtblk_draw.fontmode = '1' # disable anti-aliasing
  70. txtblk_mask = Image.new("L", (textblk_w, textblk_h), (0))
  71. tmp_msk = txtblk_mask.copy()
  72. tmp_msk_draw = ImageDraw.Draw(tmp_msk)
  73. tmp_msk_draw.fontmode = '1'
  74. textpolygons = []
  75. if orientation == ORIENTATION_VER:
  76. for ii, line in enumerate(textlines):
  77. x_offset = sum(line_widths[:ii]) + stroke_width
  78. for jj, char in enumerate(line):
  79. txtblk_draw.text((x_offset, jj*font.size), char, font=font, fill=fill, stroke_width=stroke_width, stroke_fill=stroke_fill)
  80. tmp_msk_draw.text((x_offset, jj*font.size), char, font=font, fill='white', stroke_width=stroke_width, stroke_fill='white')
  81. valid_bbox = tmp_msk.getbbox()
  82. if valid_bbox is None:
  83. continue
  84. txtblk_mask.paste(tmp_msk, mask=tmp_msk)
  85. tmp_msk.paste('black', [0, 0, tmp_msk.size[0],tmp_msk.size[1]])
  86. textpolygons.append([valid_bbox[0], valid_bbox[1], valid_bbox[2]-valid_bbox[0], valid_bbox[3]-valid_bbox[1]])
  87. else:
  88. for ii, line in enumerate(textlines):
  89. x_offset = stroke_width
  90. y_offset = sum(line_heights[0:ii]) + stroke_width
  91. if alignment == ALIGN_CENTER:
  92. x_offset += (textblk_w - line_widths[ii]) / 2
  93. txtblk_draw.text((x_offset, y_offset), line, font=font, fill=fill, stroke_width=stroke_width, stroke_fill=stroke_fill)
  94. tmp_msk_draw.text((x_offset, y_offset), line, font=font, fill='white', stroke_width=stroke_width, stroke_fill='white')
  95. valid_bbox = tmp_msk.getbbox()
  96. if valid_bbox is None:
  97. continue
  98. txtblk_mask.paste(tmp_msk, mask=tmp_msk)
  99. tmp_msk.paste('black', [0, 0, tmp_msk.size[0],tmp_msk.size[1]])
  100. textpolygons.append([valid_bbox[0], valid_bbox[1], valid_bbox[2]-valid_bbox[0], valid_bbox[3]-valid_bbox[1]])
  101. bbox = txtblk_mask.getbbox()
  102. if bbox is None:
  103. return None, None, None
  104. textpolygons = np.array(textpolygons)
  105. textpolygons = xywh2xyxypoly(textpolygons)
  106. txtblk_img, txtblk_mask = txtblk_img.crop(bbox), txtblk_mask.crop(bbox)
  107. textpolygons[:, ::2] = np.clip(textpolygons[:, ::2] - bbox[0], 0, txtblk_mask.width-1)
  108. textpolygons[:, 1::2] = np.clip(textpolygons[:, 1::2] - bbox[1], 0, txtblk_mask.height-1)
  109. if rotation != 0:
  110. center = (txtblk_img.width/2, txtblk_img.height/2)
  111. txtblk_img = txtblk_img.rotate(rotation, Image.BICUBIC, expand=1)
  112. txtblk_mask = txtblk_mask.rotate(rotation, Image.BICUBIC, expand=1)
  113. new_center = (txtblk_img.width / 2, txtblk_img.height / 2)
  114. textpolygons = rotate_polygons(center, textpolygons, rotation, new_center)
  115. # txtblk_img, txtblk_mask = txtblk_img.crop(bbox), txtblk_mask.crop(bbox)
  116. # textpolygons[:, ::2] = np.clip(textpolygons[:, ::2] - bbox[0], 0, txtblk_mask.width-1)
  117. # textpolygons[:, 1::2] = np.clip(textpolygons[:, 1::2] - bbox[1], 0, txtblk_mask.height-1)
  118. return txtblk_img, txtblk_mask, textpolygons
  119. def create_random_sampler(value, prob):
  120. if isinstance(prob, list):
  121. prob = np.array(prob).astype(np.float32)
  122. prob /= prob.sum()
  123. sampler = lambda : np.random.choice(value, replace=False, p=prob)
  124. return sampler
  125. class ScaledSampler:
  126. def __init__(self, func_args, func='default'):
  127. if func == 'default':
  128. self.sampler_func = create_random_sampler(**func_args)
  129. else:
  130. raise NotImplementedError()
  131. pass
  132. def __call__(self, scaler=None, to_int=True):
  133. value = self.sampler_func()
  134. if scaler is not None:
  135. value = scaler * value
  136. if to_int:
  137. value = int(round(value))
  138. return value
  139. pass
  140. class RandColorSampler:
  141. def __init__(self, func_args, func='default'):
  142. if func == 'default':
  143. self.sampler_func = create_random_sampler(**func_args)
  144. else:
  145. raise NotImplementedError()
  146. pass
  147. def __call__(self, scaler=None):
  148. value = self.sampler_func()
  149. if value == 'random':
  150. return (random.randint(0,255), random.randint(0,255), random.randint(0,255), 255)
  151. return value
  152. class TextLinesSampler:
  153. def __init__(self, page_size, sampler_dict):
  154. self.page_w, self.page_h = page_size
  155. self.lang = sampler_dict['lang']
  156. self.lang_dict = load_dict(lang=self.lang)
  157. self.orientation_sampler = ScaledSampler(sampler_dict['orientation'])
  158. self.numlines_sampler = ScaledSampler(sampler_dict['num_lines'])
  159. self.length_sampler = ScaledSampler(sampler_dict['length'])
  160. self.min_num_lines = sampler_dict['min_num_lines']
  161. self.min_length = sampler_dict['min_length']
  162. self.alignment_sampler = create_random_sampler(**sampler_dict['alignment'])
  163. self.rotation_sampler = create_random_sampler(**sampler_dict['rotation'])
  164. def __call__(self, page_w=None, page_h=None, font_size=1):
  165. if page_w == None:
  166. page_w = self.page_w
  167. if page_h == None:
  168. page_h = self.page_h
  169. orientation = self.orientation_sampler()
  170. rotation = self.rotation_sampler()
  171. if rotation != 0:
  172. rotation = random.randint(-rotation, rotation)
  173. num_lines = max(self.numlines_sampler(page_h/font_size), self.min_num_lines)
  174. num_lines = random.randint(self.min_num_lines, num_lines)
  175. max_length = max(self.length_sampler(page_h/font_size), self.min_length)
  176. textlines = []
  177. dict_len = len(self.lang_dict)
  178. for ii in range(num_lines):
  179. line = ''
  180. length = random.randint(self.min_length, max_length)
  181. for jj in range(length):
  182. line += self.lang_dict[random.randrange(dict_len)] + ' '
  183. textlines.append(line[:length])
  184. return textlines, orientation, self.alignment_sampler(), rotation
  185. class FontSampler:
  186. def __init__(self, font_dict, page_size) -> None:
  187. font_statics = font_dict['font_statics']
  188. font_dir = font_dict['font_dir']
  189. self.page_size = page_size
  190. self.size_sampler = ScaledSampler(font_dict['size'])
  191. self.color_sampler = RandColorSampler(font_dict['color'])
  192. self.sw_sampler = ScaledSampler(font_dict['stroke_width'])
  193. self.font_dir = font_dir
  194. self.sampler_range = font_dict['num']
  195. self.font_idx = 0
  196. font_statics = pd.read_csv(font_statics)
  197. self.font_list = list()
  198. for fontname in font_statics['font']:
  199. if osp.exists(osp.join(self.font_dir, fontname)):
  200. self.font_list.append(fontname)
  201. if len(self.font_list) >= self.sampler_range:
  202. break
  203. assert len(self.font_list) > 0
  204. def __call__(self, page_size = None):
  205. if page_size is None:
  206. page_size = self.page_size
  207. page_w, page_h = page_size
  208. fontsize = self.size_sampler(page_h)
  209. stroke_width = self.sw_sampler(fontsize)
  210. color = self.color_sampler()
  211. if color == 'black':
  212. sw_color = (255, 255, 255, 255)
  213. elif color == 'white':
  214. sw_color = (0, 0, 0, 255)
  215. else:
  216. sw_color = self.color_sampler()
  217. # while (True):
  218. # self.font_idx = random.randrange(0, self.sampler_range)
  219. # fontname = self.font_statics.iloc[self.font_idx]['font']
  220. # font_path = osp.join(self.font_dir, fontname)
  221. # if osp.exists(font_path):
  222. # break
  223. self.font_idx = random.randrange(0, self.sampler_range) % len(self.font_list)
  224. font_path = osp.join(self.font_dir, self.font_list[self.font_idx])
  225. font = ImageFont.truetype(font_path, fontsize)
  226. return font, color, stroke_width, sw_color
  227. class TextBlkSampler:
  228. def __init__(self, page_size, max_tries, bboxlist=[]):
  229. self.page_w, self.page_h = page_size
  230. self.bboxlist = bboxlist
  231. self.max_tries = max_tries
  232. self.max_padding = int(round(0.05 * self.page_h))
  233. def __call__(self, bbox_w, bbox_h, padding=0, page_size=None):
  234. padding = int(round(padding))
  235. if page_size is not None:
  236. page_w, page_h = page_size
  237. else:
  238. page_w, page_h = self.page_w, self.page_h
  239. padding = min(self.max_padding, padding)
  240. bbox_w += 2*padding
  241. bbox_h += 2*padding
  242. x_range = page_w-bbox_w-1
  243. y_range = page_h-bbox_h-1
  244. if x_range < 0 or y_range < 0:
  245. return None
  246. for ii in range(self.max_tries):
  247. x, y = random.randint(0, x_range), random.randint(0, y_range)
  248. bbox_padded = [x, y, x + bbox_w, y + bbox_h]
  249. collide = False
  250. for bbox_exist in self.bboxlist:
  251. if union_area(bbox_exist, bbox_padded) > 0:
  252. collide = True
  253. break
  254. if not collide:
  255. break
  256. if not collide:
  257. bbox = [bbox_padded[0]+padding, bbox_padded[1]+padding, bbox_padded[2]-padding, bbox_padded[3]-padding]
  258. # bbox = [int(bb) for bb in bbox]
  259. self.bboxlist.append(bbox)
  260. return bbox
  261. return None
  262. def initialize(self, page_w, page_h, bboxlist=None, to_xywh=False):
  263. if bboxlist is None:
  264. self.bboxlist = []
  265. else:
  266. if to_xywh:
  267. self.bboxlist = yolo_xywh2xyxy(bboxlist, page_w, page_h)
  268. if self.bboxlist is not None:
  269. self.bboxlist = self.bboxlist.tolist()
  270. else:
  271. self.bboxlist = []
  272. LANG_DICT = {'en': 0, 'ja': 1}
  273. def lang2cls(lang: str) -> int:
  274. return LANG_DICT[lang]
  275. def cls2lang(cls: int) -> str:
  276. return list(LANG_DICT.keys())[cls]
  277. def get_max_var_color(mean_bgcolor):
  278. color_candidate = np.clip(np.array([mean_bgcolor-127, mean_bgcolor+127]), 0, 255).astype(np.int64)
  279. max_var_color = [c[0] if abs(c[0]-mean_bgcolor[ii]) > abs(c[1]-mean_bgcolor[ii]) else c[1] for ii, c in enumerate(zip(color_candidate[0], color_candidate[1]))]
  280. max_var_color = (max_var_color[0], max_var_color[1], max_var_color[2])
  281. return max_var_color
  282. class ComicTextSampler:
  283. def __init__(self, page_size, sampler_dict, seed=None):
  284. if seed is not None:
  285. random.seed(seed)
  286. np.random.seed(seed)
  287. self.page_size = page_size
  288. self.num_txtblk = sampler_dict['num_txtblk']
  289. self.font_dict = sampler_dict['font']
  290. self.text_dict = sampler_dict['text']
  291. self.textlines_sampler = TextLinesSampler(page_size, sampler_dict['text'])
  292. self.font_sampler = FontSampler(self.font_dict, self.page_size)
  293. self.textblk_sampler = TextBlkSampler(page_size, max_tries=20)
  294. self.lang = sampler_dict['text']['lang']
  295. def drawtext_one_page(self, page_size=None, bboxlist=None, im_in=None, adaptive_color=False):
  296. if page_size is not None:
  297. page_w, page_h = page_size
  298. else:
  299. page_w, page_h = self.page_size
  300. if im_in is None:
  301. canvas = Image.new("RGBA", (page_w, page_h), 'white')
  302. else:
  303. canvas = Image.fromarray(cv2.cvtColor(im_in, cv2.COLOR_BGR2RGB))
  304. page_w, page_h = canvas.width, canvas.height
  305. canvas_msk = Image.new("L", (page_w, page_h), 'black')
  306. canvas_draw = ImageDraw.Draw(canvas)
  307. block_dicts = {}
  308. yolo_labels = []
  309. textpolylines = []
  310. self.textblk_sampler.initialize(page_w, page_h, bboxlist, True)
  311. for ii in range(self.num_txtblk):
  312. font, color, stroke_width, sw_color = self.font_sampler(page_size=self.page_size)
  313. textlines, orientation, alignment, rotation = self.textlines_sampler(font_size=font.size)
  314. txtblk_img, txtblk_mask, textpolygons = draw_textblk(textlines, font, fill=color, stroke_width=stroke_width, stroke_fill=sw_color, orientation=orientation, alignment=alignment, rotation=rotation)
  315. if txtblk_mask is None:
  316. continue
  317. bbox = self.textblk_sampler(txtblk_img.width, txtblk_img.height, font.size*1.2, page_size=(page_w, page_h))
  318. if bbox is not None:
  319. x1, y1, x2, y2 = bbox[0], bbox[1], bbox[0] + txtblk_mask.width, bbox[1] + txtblk_mask.height
  320. re_draw = False
  321. if im_in is not None:
  322. mean_bgcolor = np.mean(im_in[y1: y2, x1: x2], axis=(0, 1))
  323. max_var_color = get_max_var_color(mean_bgcolor)
  324. # color_candidate = np.clip(np.array([mean_bgcolor-127, mean_bgcolor+127]), 0, 255).astype(np.int64)
  325. # max_var_color = [c[0] if abs(c[0]-mean_bgcolor[ii]) > abs(c[1]-mean_bgcolor[ii]) else c[1] for ii, c in enumerate(zip(color_candidate[0], color_candidate[1]))]
  326. # max_var_color = (max_var_color[0], max_var_color[1], max_var_color[2])
  327. if color == 'black':
  328. color_rep = np.array([0, 0, 0])
  329. elif color == 'white':
  330. color_rep = np.array([255, 255, 255])
  331. else:
  332. color_rep = np.array(color[:3])
  333. color_var = np.sum(np.abs(mean_bgcolor - color_rep))
  334. if not adaptive_color:
  335. if color_var < 127:
  336. color = max_var_color
  337. sw_color = get_max_var_color(np.array(color))
  338. re_draw = True
  339. else:
  340. color = max_var_color
  341. sw_color = get_max_var_color(np.array(color))
  342. re_draw = True
  343. if stroke_width != 0 and im_in is not None:
  344. # sw_color = get_max_var_color(color)
  345. re_draw = True
  346. if re_draw:
  347. txtblk_img, txtblk_mask, textpolygons = draw_textblk(textlines, font, fill=color, stroke_width=stroke_width, stroke_fill=sw_color, orientation=orientation, alignment=alignment, rotation=rotation)
  348. blk_dict = {
  349. 'lang': self.lang,
  350. 'lang_cls': lang2cls(self.lang),
  351. 'xyxy': [x1, y1, x2, y2],
  352. 'polylines': textpolygons
  353. }
  354. block_dicts[str(ii)+'-'+self.lang] = blk_dict
  355. textpolygons[:, ::2] += x1
  356. textpolygons[:, 1::2] += y1
  357. textpolylines += textpolygons.astype(np.int64).tolist()
  358. yolo_labels += [[x1, y1, x2, y2]]
  359. canvas.paste(txtblk_img, (bbox[0], bbox[1]), mask=txtblk_mask)
  360. canvas_msk.paste(txtblk_mask, (bbox[0], bbox[1]), mask=txtblk_mask)
  361. rst = cv2.cvtColor(np.array(canvas), cv2.COLOR_RGB2BGR)
  362. rst_msk = np.array(canvas_msk)
  363. yolo_labels = xyxy2yolo(np.array(yolo_labels), page_w, page_h)
  364. if yolo_labels is not None:
  365. cls = np.ones((yolo_labels.shape[0], 1)) * lang2cls(self.lang)
  366. yolo_labels = np.concatenate((cls, yolo_labels), axis=1)
  367. return rst, rst_msk, block_dicts, yolo_labels, np.array(textpolylines)
  368. def render_comictext(comic_sampler_list, img_dir, label_dir=None, render_num=700, save_dir=None, save_prefix=None, show=False):
  369. if osp.exists(osp.join(img_dir, 'statistics.csv')):
  370. statistics = pd.read_csv(osp.join(img_dir, 'statistics.csv'))
  371. else:
  372. statistics = None
  373. imglist = find_all_imgs(img_dir)
  374. # render_num = min(render_num, len(imglist))
  375. num_im = len(imglist)
  376. for ii in tqdm(range(render_num)):
  377. im_idx = ii % num_im
  378. if statistics is not None:
  379. imgname = statistics.loc[im_idx]['name']
  380. else:
  381. imgname = imglist[im_idx]
  382. img = imread(osp.join(img_dir, imgname))
  383. cs_idx = ii % len(comic_sampler_list)
  384. bboxlist = []
  385. labels = None
  386. if label_dir is not None:
  387. labelname = imgname.replace(pathlib.Path(imgname).suffix, '.txt')
  388. label_path = osp.join(label_dir, labelname)
  389. labels = np.loadtxt(label_path)
  390. if len(labels) != 0:
  391. if len(labels.shape) == 1:
  392. labels = np.array([labels])
  393. clslist, bboxlist = labels[:, 0], np.copy(labels[:, 1:])
  394. else:
  395. labels = None
  396. bboxlist = []
  397. rst, rst_msk, block_dicts, yolo_labels, textpolylines = comic_sampler_list[cs_idx].drawtext_one_page(im_in=img, bboxlist=bboxlist, adaptive_color=True)
  398. if save_dir is not None:
  399. if save_prefix is not None:
  400. save_name = save_prefix + '{0:09d}'.format(ii) + '.jpg'
  401. else:
  402. save_name = 'syn-' + imgname
  403. yolo_save_path = osp.join(save_dir, save_name.replace(pathlib.Path(save_name).suffix, '.txt'))
  404. content = ''
  405. if yolo_labels is not None:
  406. if labels is None:
  407. content = get_yololabel_strings(yolo_labels[:, 0], yolo_labels[:, 1:])
  408. else:
  409. yolo_labels = np.concatenate((labels, yolo_labels))
  410. content = get_yololabel_strings(yolo_labels[:, 0], yolo_labels[:, 1:])
  411. if content == '' and label_dir is not None:
  412. shutil.copy(label_path, yolo_save_path)
  413. else:
  414. with open(yolo_save_path, 'w', encoding='utf8') as f:
  415. f.write(content)
  416. linepoly_save_path = osp.join(save_dir, 'line-'+osp.basename(yolo_save_path))
  417. np.savetxt(linepoly_save_path, textpolylines, fmt='%d')
  418. imwrite(osp.join(save_dir, save_name), rst, ext='.jpg')
  419. imwrite(osp.join(save_dir, 'mask-'+save_name), rst_msk)
  420. if show:
  421. for pts in textpolylines:
  422. rst = cv2.polylines(rst, [np.array(pts).reshape((-1, 1, 2))], color=(255, 0, 0), isClosed=True, thickness=2)
  423. cv2.imshow('rst', rst)
  424. cv2.waitKey(0)
  425. if __name__ == '__main__':
  426. eng_sampler_dict = {
  427. 'num_txtblk': 20,
  428. 'font': {
  429. 'font_dir': 'data/fonts',
  430. 'font_statics': 'data/font_statics_en.csv',
  431. 'num': 500,
  432. 'size': {'value': [0.02, 0.03, 0.15],
  433. 'prob': [1, 0.4, 0.15]},
  434. 'stroke_width': {'value': [0, 0.1, 0.15],
  435. 'prob': [1, 0.2, 0.2]},
  436. 'color': {'value': ['black', 'random'],
  437. 'prob': [1, 0.4]},
  438. },
  439. 'text': {
  440. 'lang': 'en',
  441. 'orientation': {'value': [1, 0],
  442. 'prob': [0, 1]},
  443. 'rotation': {'value': [0, 30, 60],
  444. 'prob': [1, 0.3, 0.1]},
  445. 'num_lines': {'value': [0.15],
  446. 'prob': [1]},
  447. 'length': {'value': [1],
  448. 'prob': [1]},
  449. 'min_num_lines': 1,
  450. 'min_length': 3,
  451. 'alignment': {'value': [ALIGN_LEFT, ALIGN_CENTER],
  452. 'prob': [0.3, 1]}
  453. }
  454. }
  455. ja_sampler_dict = {
  456. 'num_txtblk': 20,
  457. 'font': {
  458. 'font_dir': 'data/fonts', # font file directory
  459. 'font_statics': 'data/font_statics_jp.csv', # Just a font list to use, please create your own list and ignore the last two cols.
  460. 'num': 500, # first 500 of the fontlist will be used
  461. # params to
  462. 'size': {'value': [0.02, 0.03, 0.15],
  463. 'prob': [1, 0.4, 0.15]},
  464. 'stroke_width': {'value': [0, 0.1, 0.15],
  465. 'prob': [1, 0.5, 0.2]},
  466. 'color': {'value': ['black', 'white', 'random'],
  467. 'prob': [1, 1, 0.4]},
  468. },
  469. 'text': {
  470. 'lang': 'ja', # render japanese, 'en' for english
  471. 'orientation': {'value': [1, 0], # 1 is vertical text.
  472. 'prob': [1, 0.3]},
  473. 'rotation': {'value': [0, 30, 60],
  474. 'prob': [1, 0.3, 0.1]},
  475. 'num_lines': {'value': [0.15],
  476. 'prob': [1]},
  477. 'length': {'value': [0.3],
  478. 'prob': [1]},
  479. 'min_num_lines': 1,
  480. 'min_length': 3,
  481. 'alignment': {'value': [ALIGN_LEFT, ALIGN_CENTER],
  482. 'prob': [0.3, 1]}
  483. }
  484. }
  485. # random.seed(0)
  486. # cts = ComicTextSampler((845, 1280), sampler_dict, seed=0)
  487. # jp_cts = ComicTextSampler((845, 1280), ja_sampler_dict, seed=0)
  488. # img_dir = r'../../datasets/pixanimegirls'
  489. # save_dir = r'../../datasets/pixanimegirls/processed'
  490. # os.makedirs(save_dir, exist_ok=True)
  491. # img_dir = r'../../datasets/ComicErased'
  492. # label_dir = img_dir
  493. # save_dir = r'../../datasets/ComicErased/processed'
  494. # os.makedirs(save_dir, exist_ok=True)
  495. # render_comictext([jp_cts, cts], img_dir, save_dir=save_dir, save_prefix=None, render_num=4000, label_dir=None)