idcard_det_rec_generate_back.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. import argparse
  2. import os.path
  3. import random
  4. import cv2
  5. from PIL import Image, ImageDraw, ImageFont
  6. from tqdm import tqdm
  7. def add_space(str):
  8. temp_str = ''
  9. if len(str) <= 6:
  10. num_of_space = (3 * (6 - len(str))) / (len(str) - 1)
  11. for i in range(0, len(str) - 1):
  12. temp_str += str[i]
  13. for j in range(0, int(num_of_space)):
  14. temp_str += ' '
  15. temp_str += str[len(str) - 1]
  16. return temp_str
  17. def generate_idcard(name_dir, bingyi_dir, addr_dir, id_dir, save_dir, generate_num, bg_dir, font_dir):
  18. if not os.path.exists(save_dir):
  19. os.makedirs(save_dir)
  20. fp_name = open(name_dir, 'r', encoding='utf-8')
  21. fp_bingyi = open(bingyi_dir, 'r', encoding='utf-8')
  22. fp_addr= open(addr_dir, 'r', encoding='utf-8')
  23. fp_id = open(id_dir, 'r', encoding='utf-8')
  24. # 姓名列表
  25. name_list = []
  26. for name in fp_name.readlines():
  27. name_list.append(name.rstrip('\n').replace(" ", ''))
  28. # print(name_list)
  29. # 兵役選項
  30. bingyi_list = []
  31. for bingyi in fp_bingyi.readlines():
  32. bingyi_list.append(bingyi[2:].rstrip('\n'))
  33. # 出生地及住址
  34. addr_list = []
  35. for addr in fp_addr.readlines():
  36. addr = addr.rstrip('\n')
  37. ll = addr.split(',')
  38. addr_temp = ll[1] + ll[0]
  39. addr_list.append(addr_temp)
  40. # 編號
  41. id_list = []
  42. for id in fp_id.readlines():
  43. id_list.append(id.rstrip('\n'))
  44. cnt = 2401
  45. for i in tqdm(range(0, generate_num)):
  46. name_father_id = random.randint(0, len(name_list) - 1)
  47. name_mother_id = random.randint(0, len(name_list) - 1)
  48. name_couple_id = random.randint(0, len(name_list) - 1)
  49. bingyi_id = random.randint(0, len(bingyi_list) - 1)
  50. addr_id = random.randint(0, len(addr_list) - 1)
  51. id_id = random.randint(0, len(id_list) - 1)
  52. # 父母親及配偶姓名
  53. name_father = name_list[name_father_id]
  54. name_mother = name_list[name_mother_id]
  55. name_couple = name_list[name_couple_id]
  56. # 兵役
  57. bingyi = bingyi_list[bingyi_id]
  58. # 住址
  59. addr = addr_list[addr_id]
  60. n = random.randint(0, 1)
  61. if n == 0:
  62. # 出生地
  63. birth_place = '臺灣省' + addr[0:3]
  64. # 县或市为出生地
  65. else:
  66. birth_place = addr[0:3]
  67. # 編號
  68. id = id_list[id_id]
  69. # 获取背景图列表
  70. bg_img_name_list = os.listdir(bg_dir)
  71. bg_path_list = []
  72. for bg_img_name in bg_img_name_list:
  73. bg_path_list.append(bg_dir + '/' + bg_img_name)
  74. # 每次随机取背景图
  75. bg_path = bg_path_list[random.randint(0, len(bg_path_list) - 1)]
  76. pil_image = Image.open(bg_path)
  77. # pil_image 接收住这个图片对象
  78. # width 为图片的宽, height为图片的高
  79. width, height = pil_image.size
  80. # 生成一张尺寸为 width * height 背景色为白色的图片
  81. bg = Image.new('RGB', (width, height), color=(0, 0, 0))
  82. bg.paste(pil_image, (0, 0)) # 写入底图
  83. name_font_size = 35
  84. # 姓名中加入间隔
  85. name_father = add_space(name_father)
  86. name_mother = add_space(name_mother)
  87. name_couple = add_space(name_couple)
  88. temp_str = ''
  89. for i in range(0, len(addr) - 1):
  90. temp_str += addr[i]
  91. temp_str += ' '
  92. temp_str += addr[len(addr) - 1]
  93. addr = temp_str
  94. font_name_list = os.listdir(font_dir)
  95. font_path_list = []
  96. for font_name in font_name_list:
  97. font_path_list.append(font_dir + '/' + font_name)
  98. # 每次随机字体
  99. font_path = font_path_list[random.randint(0, len(font_path_list) - 1)]
  100. name_font = ImageFont.truetype(font_path, name_font_size) # 设置名字字体和大小
  101. addr_font = ImageFont.truetype(font_path, 23)
  102. id_font = ImageFont.truetype('OpticalBBold.otf', 28)
  103. # # 计算出要写入的文字占用的像素
  104. # # 创建一个可以在给定图像上绘图的对象
  105. draw = ImageDraw.Draw(bg)
  106. # 设置配偶及役别数据项为空
  107. rand_bingyi = random.randint(0, 1)
  108. rang_spouse = random.randint(0, 1)
  109. if rand_bingyi == 0:
  110. bingyi=''
  111. if rang_spouse == 0:
  112. name_couple = ''
  113. draw.text((110, 17), name_father, fill="#444444", font=name_font)
  114. draw.text((415, 17), name_mother, fill="#444444", font=name_font)
  115. draw.text((115, 82), name_couple, fill="#444444", font=name_font)
  116. draw.text((415, 82), bingyi, fill="#444444", font=name_font)
  117. draw.text((115, 147), birth_place, fill="#444444", font=name_font)
  118. draw.text((115, 210), addr[0:24], fill="#444444", font=addr_font)
  119. draw.text((115, 240), addr[24:], fill="#444444", font=addr_font)
  120. draw.text((455, 377), id, fill="#42A329", font=id_font)
  121. path_list = []
  122. # 保存画布
  123. img_path = save_dir + '/idcard_back' + str(cnt) + '.png'
  124. cnt += 1
  125. # img_path = save_dir + '/idcard_' + str(cnt) + '_mask.png'
  126. bg.save(img_path, "PNG")
  127. path_list.append(img_path)
  128. boxes = []
  129. box_name_father = [105, 17, 305, 62]
  130. box0 = []
  131. box0.append(box_name_father)
  132. box0.append(name_father.replace(' ', ''))
  133. box0.append('father_name')
  134. boxes.append(box0)
  135. box_name_mother = [410, 17, 610, 62]
  136. box1 = []
  137. box1.append(box_name_mother)
  138. box1.append(name_mother.replace(' ', ''))
  139. box1.append('mother_name')
  140. boxes.append(box1)
  141. box_name_spouse = [110, 82, 310, 127]
  142. box2 = []
  143. box2.append(box_name_spouse)
  144. box2.append(name_couple.replace(' ', ''))
  145. box2.append('spouse_name')
  146. boxes.append(box2)
  147. box_birth_place = [110, 147, 335, 190]
  148. box3 = []
  149. box3.append(box_birth_place)
  150. box3.append(birth_place.replace(' ', ''))
  151. box3.append('birth_place')
  152. boxes.append(box3)
  153. box_bingyi = [410, 82, 610, 125]
  154. box4 = []
  155. box4.append(box_bingyi)
  156. box4.append(bingyi.replace(' ', ''))
  157. box4.append('level')
  158. boxes.append(box4)
  159. box_id = [450, 377, 655, 410]
  160. box5 = []
  161. box5.append(box_id)
  162. box5.append(id.replace(' ', ''))
  163. box5.append('number')
  164. boxes.append(box5)
  165. num = 1
  166. # fp = open(save_dir + '/rec_gt.txt', 'a', encoding='utf-8')
  167. fp1 = open(save_dir + '/Label.txt', 'a', encoding='utf-8')
  168. for path in path_list:
  169. # print(path)
  170. jishu = 1
  171. anno = str(path).split('/')[-1] + '\t['
  172. for box in boxes:
  173. if jishu <= 6:
  174. if jishu == 6:
  175. s = '{"transcription": "' + box[1] + '", "points": [[' + str(box[0][0]) + ', ' + str(box[0][1]) + '], [' + str(box[0][2]) + ', ' + str(box[0][1]) + '], [' + str(box[0][2]) + ', ' + str(box[0][3]) + '], [' + str(box[0][0]) + ', ' + str(box[0][3]) + ']], "difficult": false, "key_cls": "' + box[2] + '"}'
  176. else:
  177. s = '{"transcription": "' + box[1] + '", "points": [[' + str(box[0][0]) + ', ' + str(
  178. box[0][1]) + '], [' + str(box[0][2]) + ', ' + str(box[0][1]) + '], [' + str(
  179. box[0][2]) + ', ' + str(box[0][3]) + '], [' + str(box[0][0]) + ', ' + str(
  180. box[0][3]) + ']], "difficult": false, "key_cls": "' + box[2] + '"}, '
  181. anno += s
  182. # image_cut_save(path, box[0][0], box[0][1], box[0][2], box[0][3], save_dir + '/crop_imgs/' + str(path).split('/')[-1].split('.')[0] + '_' + str(num) + '.png')
  183. # line = 'crop_imgs/' + str(path).split('/')[-1].split('.')[0] + '_' + str(num) + '.png' + '\t' + box[1] + '\n'
  184. # fp.write(line)
  185. num += 1
  186. jishu += 1
  187. anno += ']\n'
  188. fp1.write(anno)
  189. # print(anno)
  190. fp1.close()
  191. # fp.close()
  192. fp_name.close()
  193. fp_bingyi.close()
  194. fp_addr.close()
  195. fp_id.close()
  196. return
  197. def image_cut_save(path, left, upper, right, lower, save_path):
  198. """
  199. 所截区域图片保存
  200. :param path: 图片路径
  201. :param left: 区块左上角位置的像素点离图片左边界的距离
  202. :param upper:区块左上角位置的像素点离图片上边界的距离
  203. :param right:区块右下角位置的像素点离图片左边界的距离
  204. :param lower:区块右下角位置的像素点离图片上边界的距离
  205. 故需满足:lower > upper、right > left
  206. :param save_path: 所截图片保存位置
  207. """
  208. img = cv2.imread(path) # 打开图像
  209. cropped = img[upper:lower, left:right]
  210. cv2.imwrite(save_path, cropped)
  211. if __name__ == '__main__':
  212. parser = argparse.ArgumentParser()
  213. parser.add_argument('--name_dir', type=str, default='./materials/name_cht.txt')
  214. parser.add_argument('--bingyi_dir', type=str, default='./materials/bingyi.txt')
  215. parser.add_argument('--addr_dir', type=str, default='./materials/addr.txt')
  216. parser.add_argument('--id_dir', type=str, default='./materials/id_back.txt')
  217. parser.add_argument('--save_dir', type=str, default=r'C:\Users\KDAN\Desktop\workspace\文字检测数据集(台湾身份证)\tw_idcard_back_det_0215\imgs')
  218. parser.add_argument('--bg_dir', type=str, default='./test_bgs')
  219. parser.add_argument('--generate_num', type=int, default=700)
  220. parser.add_argument('--font_dir', type=str, default='./fonts')
  221. args = parser.parse_args()
  222. generate_idcard(args.name_dir, args.bingyi_dir, args.addr_dir, args.id_dir, args.save_dir, args.generate_num, args.bg_dir, args.font_dir)
  223. # image_cut_save('./idcard_0_02.png', 445, 340, 540, 370, 'result.png')