pre_process.py 104 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034
  1. import copy
  2. import gc
  3. import io
  4. import json
  5. import math
  6. import os
  7. import random
  8. import re
  9. import sys
  10. import threading
  11. import time
  12. import traceback
  13. from glob import glob
  14. from itertools import combinations, product
  15. import matplotlib
  16. # 不显示图
  17. # matplotlib.use('agg')
  18. # print(matplotlib.get_backend())
  19. import matplotlib.pyplot as plt
  20. import matplotlib.patheffects as path_effects
  21. import chardet
  22. import cv2
  23. import jieba
  24. import numpy as np
  25. from PIL import ImageFont, ImageDraw, Image, ImageEnhance, ImageFilter
  26. from captcha.image import ImageCaptcha
  27. from keras_preprocessing.sequence import pad_sequences
  28. from matplotlib import _pylab_helpers
  29. from matplotlib.colors import rgb_to_hsv, hsv_to_rgb
  30. from click_captcha.model import u_net_denoise
  31. sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../")
  32. sys.path.append(os.path.dirname(os.path.abspath(__file__)))
  33. from click_captcha.utils import np2pil, pil2np, pil_resize, pil_rotate, pil2np_a, np2pil_a, pil_resize_a, pil_rotate_a
  34. fig = plt.figure(figsize=(1, 1), facecolor='none')
  35. def gen_siamese(paths, batch_size=32, shape=(40, 40), cls_num=1):
  36. num = len(paths)
  37. data_path = os.path.dirname(os.path.abspath(__file__)) + "/../data/click/"
  38. i = 0
  39. while True:
  40. if i >= num:
  41. i = 0
  42. random.shuffle(paths)
  43. height, width = shape[:2]
  44. X1 = np.zeros((batch_size, height, width, 1))
  45. X2 = np.zeros((batch_size, height, width, 1))
  46. Y = np.zeros((batch_size, 2))
  47. for j in range(batch_size):
  48. # 生成标注数据
  49. img1, img2, label = paths[i][:-1].split("\t")
  50. # print(img1, img2, label)
  51. img1 = cv2.imread(data_path + img1)
  52. img1 = pil_resize(img1, shape[0], shape[1])
  53. img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
  54. img1 = np.expand_dims(img1, axis=-1)
  55. img2 = cv2.imread(data_path + img2)
  56. img2 = pil_resize(img2, shape[0], shape[1])
  57. img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
  58. img2 = np.expand_dims(img2, axis=-1)
  59. if label == "1":
  60. label = np.array([0, 1])
  61. else:
  62. label = np.array([1, 0])
  63. X1[j] = img1
  64. X2[j] = img2
  65. Y[j] = label
  66. yield {"input_1": X1, "input_2": X2}, {"output": Y}
  67. def gen_char(paths, batch_size=32, shape=(40, 40), cls_num=6270, data_path="click"):
  68. num = len(paths)
  69. data_path = os.path.dirname(os.path.abspath(__file__)) + "/../data/" + data_path + "/"
  70. i = 0
  71. random.shuffle(paths)
  72. while True:
  73. if i >= num:
  74. i = 0
  75. random.shuffle(paths)
  76. height, width = shape[:2]
  77. if len(shape) > 2 and shape[2] == 3:
  78. channel = 3
  79. else:
  80. channel = 1
  81. X = np.zeros((batch_size, height, width, channel))
  82. Y = np.zeros((batch_size, cls_num))
  83. j = 0
  84. random.shuffle(paths)
  85. while j < batch_size:
  86. if i >= num:
  87. random.shuffle(paths)
  88. i = 0
  89. path = paths[i].split(os.sep)[-1]
  90. char_index = int(path.split("_")[0])
  91. label = np.zeros(cls_num)
  92. # print("char_index", char_index)
  93. label[char_index] = 1
  94. # print("label", np.argmax(label), char_index)
  95. img1 = cv2.imread(data_path + path)
  96. img1 = pil_resize(img1, shape[0], shape[1])
  97. # img2 = copy.deepcopy(img1)
  98. # 数据增强
  99. if random.choice([0, 1]):
  100. img1_pil = np2pil(img1)
  101. aug = random.choice([0, 1, 2, 4, 5])
  102. # aug = 6
  103. if aug == 0:
  104. img1_pil = image_enhance_color(img1_pil)
  105. elif aug == 1:
  106. img1_pil = image_enhance_brightness(img1_pil)
  107. elif aug == 3:
  108. img1_pil = image_enhance_contrast(img1_pil)
  109. elif aug == 4:
  110. img1_pil = image_enhance_sharpness(img1_pil)
  111. elif aug == 5:
  112. img1_pil = image_enhance_blur(img1_pil)
  113. img1 = pil2np(img1_pil)
  114. if aug == 6:
  115. img1 = image_enhance_distort(img1)
  116. # print(aug)
  117. # cv2.imshow("origin", img2)
  118. # cv2.imshow("gen_char", img1)
  119. # cv2.waitKey(0)
  120. img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
  121. img1 = np.expand_dims(img1, axis=-1)
  122. img1 = img1 / 255.
  123. X[j] = img1
  124. Y[j] = label
  125. i += 1
  126. j += 1
  127. # print("error_num", error_num)
  128. yield X, Y
  129. def gen_yolo_char(paths, batch_size, input_shape, anchors, num_classes, box_num=6):
  130. """data generator for fit_generator"""
  131. n = len(paths)
  132. data_path = os.path.dirname(os.path.abspath(__file__)) + "/../data/detect/"
  133. i = 0
  134. while True:
  135. image_data = []
  136. box_data = []
  137. batch_cnt = 0
  138. while batch_cnt < batch_size:
  139. try:
  140. if i == 0:
  141. np.random.shuffle(paths)
  142. ss = paths[i][:-1].split(" ")
  143. image_path = ss[0]
  144. image = cv2.imread(data_path+image_path)
  145. origin_h, origin_w = image.shape[:2]
  146. image = pil_resize(image, input_shape[0], input_shape[1])
  147. # 数据增强
  148. if random.choice([0, 0, 1]):
  149. img1_pil = np2pil(image)
  150. aug = random.choice([0, 1, 2, 4, 5])
  151. if aug == 0:
  152. img1_pil = image_enhance_color(img1_pil)
  153. elif aug == 1:
  154. img1_pil = image_enhance_brightness(img1_pil)
  155. elif aug == 3:
  156. img1_pil = image_enhance_contrast(img1_pil)
  157. elif aug == 4:
  158. img1_pil = image_enhance_sharpness(img1_pil)
  159. elif aug == 5:
  160. img1_pil = image_enhance_blur(img1_pil)
  161. image = pil2np(img1_pil)
  162. image_show = copy.deepcopy(image)
  163. image = image / 255.
  164. box = np.array([np.array(list(map(int, box.split(',')))) for box in ss[1:]])
  165. # box数不同,复制
  166. # print("box.shape", box.shape)
  167. if box.shape[0] < box_num:
  168. # box = np.concatenate([box]+[np.zeros(5)]*(box_num-box.shape[0]), axis=0)
  169. if box_num-box.shape[0] >= box.shape[0]:
  170. box = np.concatenate([box]+[box[0, :]]*(box_num-box.shape[0]), axis=0)
  171. else:
  172. box = np.concatenate([box, box[:box_num-box.shape[0], :]], axis=0)
  173. # show
  174. # box_show = box.tolist()
  175. # for b in box_show:
  176. # print("box", b)
  177. # cv2.rectangle(image_show, (b[0], b[1]), (b[2], b[3]), (255, 0, 0), 2)
  178. # cv2.imshow("image_show", image_show)
  179. # cv2.waitKey(0)
  180. # print("box.shape", box.shape)
  181. image_data.append(image)
  182. box_data.append(box)
  183. i = (i+1) % n
  184. batch_cnt += 1
  185. except:
  186. i = (i+1) % n
  187. continue
  188. # print
  189. # print(image.shape)
  190. # image_show = (image*255).astype(np.uint8)
  191. # print("annotation_lines[i]", annotation_lines[i])
  192. # for _b in box:
  193. # print(_b)
  194. # cv2.rectangle(image_show, (int(_b[0]), int(_b[1])), (int(_b[2]), int(_b[3])), (0, 255, 0), 1)
  195. # cv2.imshow("image", image_show)
  196. # cv2.waitKey(0)
  197. image_data = np.array(image_data)
  198. box_data = np.array(box_data)
  199. # print(image_data.shape, box_data.shape)
  200. y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes)
  201. yield [image_data, *y_true], np.zeros(batch_size)
  202. def gen_yolo_puzzle(paths, batch_size, input_shape, anchors, num_classes, box_num=1):
  203. """data generator for fit_generator"""
  204. n = len(paths)
  205. data_path = os.path.dirname(os.path.abspath(__file__)) + "/../data/detect2/"
  206. i = 0
  207. while True:
  208. image_data = []
  209. box_data = []
  210. batch_cnt = 0
  211. while batch_cnt < batch_size:
  212. try:
  213. if i == 0:
  214. np.random.shuffle(paths)
  215. ss = paths[i][:-1].split(" ")
  216. image_path = ss[0]
  217. image = cv2.imread(data_path+image_path)
  218. image = pil_resize(image, input_shape[0], input_shape[1])
  219. image_show = copy.deepcopy(image)
  220. image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  221. image = 255. - image
  222. image = np.uint8(image)
  223. # cv2.imshow("image", image)
  224. # cv2.waitKey(0)
  225. image = np.expand_dims(image, -1)
  226. image = image / 255.
  227. box = np.array([np.array(list(map(int, box.split(',')))) for box in ss[1:]])
  228. # box数不同,复制
  229. if box.shape[0] < box_num:
  230. box = np.concatenate([box, box[:2, :]], axis=0)
  231. # show
  232. # box_show = box.tolist()
  233. # for b in box_show:
  234. # print("box", b)
  235. # cv2.rectangle(image_show, (b[0], b[1]), (b[2], b[3]), (0, 0, 255), 2)
  236. # cv2.imshow("image_show", image_show)
  237. # cv2.waitKey(0)
  238. image_data.append(image)
  239. box_data.append(box)
  240. i = (i+1) % n
  241. batch_cnt += 1
  242. except:
  243. i = (i+1) % n
  244. continue
  245. # print
  246. # print(image.shape)
  247. # image_show = (image*255).astype(np.uint8)
  248. # for _b in box:
  249. # print(_b)
  250. # cv2.rectangle(image_show, (int(_b[0]), int(_b[1])), (int(_b[2]), int(_b[3])), (0, 255, 0), 1)
  251. # cv2.imshow("image", image_show)
  252. # cv2.waitKey(0)
  253. image_data = np.array(image_data)
  254. box_data = np.array(box_data)
  255. # print(image_data.shape, box_data.shape)
  256. y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes)
  257. yield [image_data, *y_true], np.zeros(batch_size)
  258. def gen_drag(paths, batch_size=32, shape=(128, 256), cls_num=2):
  259. num = len(paths)
  260. data_path = os.path.dirname(os.path.abspath(__file__)) + "/../data/drag/"
  261. map_path = data_path+"map.txt"
  262. with open(map_path, "r") as f:
  263. _list = f.readlines()
  264. map_dict = {}
  265. for s in _list:
  266. ss = s[:-1].split(" ")
  267. map_dict[ss[0]] = ss[1]
  268. i = 0
  269. random.shuffle(paths)
  270. while True:
  271. if i >= num:
  272. i = 0
  273. random.shuffle(paths)
  274. height, width = shape[:2]
  275. if len(shape) > 2:
  276. channel = 3
  277. else:
  278. channel = 1
  279. X = np.zeros((batch_size, height, width, channel))
  280. Y = np.zeros((batch_size, height, width, 1))
  281. for j in range(batch_size):
  282. if i >= num:
  283. random.shuffle(paths)
  284. i = 0
  285. path = paths[i].split(os.sep)[-1]
  286. w_index = int(map_dict.get(path))
  287. # label = np.zeros(cls_num)
  288. # print("char_index", char_index)
  289. # label[w_index] = 1
  290. # print("label", np.argmax(label), char_index)
  291. img1 = cv2.imread(data_path + path)
  292. img1 = pil_resize(img1, shape[0], shape[1])
  293. # cv2.imshow("image", img1)
  294. label = np.full((shape[0], shape[1], 1), 0, dtype='uint8')
  295. label[:, w_index, 0] = 1
  296. # label[:, w_index, 1] = 1
  297. # cv2.imshow("label", np.expand_dims(label[..., 0], -1))
  298. # cv2.waitKey(0)
  299. img1 = img1 / 255.
  300. # img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
  301. # img1 = np.expand_dims(img1, axis=-1)
  302. i += 1
  303. X[j] = img1
  304. Y[j] = label
  305. yield X, Y
  306. def gen_phrase(map_list, batch_size=32, shape=(5707, 3)):
  307. voc_dim, timesteps = shape[:2]
  308. data_list = []
  309. for line in map_list:
  310. data_list.append([eval(line[:-3]), int(line[-2:-1])])
  311. num = len(data_list)
  312. i = 0
  313. random.shuffle(data_list)
  314. while True:
  315. X = np.zeros((batch_size, timesteps))
  316. Y = np.zeros((batch_size, 1))
  317. for j in range(batch_size):
  318. if i >= num:
  319. random.shuffle(data_list)
  320. i = 0
  321. data = data_list[i]
  322. d_list = [x for x in data[0]]
  323. d_list = d_list + [voc_dim]*(timesteps-len(d_list))
  324. X[j] = np.array(d_list)
  325. Y[j] = data[1]
  326. i += 1
  327. yield X, Y
  328. def gen_equation(paths, batch_size=32, shape=(40, 40), input_len=21, label_len=8, cls_num=6270, data_path='equation'):
  329. num = len(paths)
  330. data_path = os.path.dirname(os.path.abspath(__file__)) + "/../data/" + data_path + "/"
  331. map_path = os.path.dirname(os.path.abspath(__file__)) + "/../data/equation.txt"
  332. with open(map_path, "r") as f:
  333. map_list = f.readlines()
  334. map_str = "".join(map_list)
  335. map_str = re.sub("\n", "", map_str)
  336. char_map_dict = {
  337. "星": '*',
  338. "斜": "/",
  339. "问": "?",
  340. 'x': '×',
  341. '?': '?'
  342. }
  343. i = 0
  344. random.shuffle(paths)
  345. while True:
  346. if i >= num:
  347. i = 0
  348. random.shuffle(paths)
  349. height, width = shape[:2]
  350. if len(shape) > 2 and shape[2] == 3:
  351. channel = 3
  352. else:
  353. channel = 1
  354. X = np.zeros((batch_size, height, width, channel))
  355. Y = np.zeros((batch_size, label_len))
  356. input_length = np.ones(batch_size) * input_len
  357. label_length = np.ones(batch_size) * label_len
  358. j = 0
  359. while j < batch_size:
  360. if i >= num:
  361. random.shuffle(paths)
  362. i = 0
  363. path = paths[i].split(os.sep)[-1]
  364. char_index_list = []
  365. for c in path.split(".")[0].split('_')[1:]:
  366. if c in char_map_dict.keys():
  367. c = char_map_dict.get(c)
  368. if not c:
  369. continue
  370. # print("c", c)
  371. char_index_list.append(map_str.index(c)+1)
  372. char_index_list.extend([0] * (label_len-len(char_index_list)))
  373. label = np.array(char_index_list)
  374. img1 = cv2.imread(data_path + path)
  375. img1 = pil_resize(img1, shape[0], shape[1])
  376. # img2 = copy.deepcopy(img1)
  377. # cv2.imshow("origin", img2)
  378. # cv2.imshow("gen_char", img1)
  379. # cv2.waitKey(0)
  380. img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
  381. img1 = np.expand_dims(img1, axis=-1)
  382. img1 = img1 / 255.
  383. X[j] = img1
  384. Y[j] = label
  385. i += 1
  386. j += 1
  387. yield [X, Y, input_length, label_length], np.ones(batch_size)
  388. def gen_equation2(paths, batch_size=32, shape=(40, 40), input_len=21, label_len=8, cls_num=6270, data_path='equation'):
  389. os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
  390. image_shape = (32, 192, 1)
  391. weights_path = "./models/e153-loss53.97-denoise.h5"
  392. model = u_net_denoise(input_shape=image_shape, class_num=image_shape[2])
  393. model.load_weights(weights_path)
  394. os.environ["CUDA_VISIBLE_DEVICES"] = "0"
  395. data_path = os.path.dirname(os.path.abspath(__file__)) + "/../data/" + data_path + "/"
  396. map_path = os.path.dirname(os.path.abspath(__file__)) + "/../data/equation.txt"
  397. with open(map_path, "r") as f:
  398. map_list = f.readlines()
  399. map_str = "".join(map_list)
  400. map_str = re.sub("\n", "", map_str)
  401. blank_index = len(map_str)+1
  402. char_map_dict = {
  403. "星": '*',
  404. "斜": "/",
  405. "问": "?",
  406. 'x': '×',
  407. '?': '?'
  408. }
  409. i = 0
  410. while True:
  411. height, width = shape[:2]
  412. if len(shape) > 2 and shape[2] == 3:
  413. channel = 3
  414. else:
  415. channel = 1
  416. X = np.zeros((batch_size, height, width, channel))
  417. Y = np.zeros((batch_size, label_len))
  418. input_length = np.ones(batch_size) * input_len
  419. label_length = np.ones(batch_size) * label_len
  420. noise = random.choice([False, True, True])
  421. result_list = generate_data_equation2(batch_size, noise=noise)
  422. # 模型降噪
  423. img_list = [np.expand_dims(cv2.cvtColor(pil_resize(x[0], image_shape[0], image_shape[1]), cv2.COLOR_BGR2GRAY), axis=-1) for x in result_list]
  424. img_data = np.array(img_list) / 255.
  425. pred = model.predict(img_data)
  426. img_list = np.uint8(pred*255.)
  427. # for j in range(len(result_list)):
  428. # img1 = img_list[j]
  429. # img1 = add_contrast(img1)
  430. # ratio = get_image_legal(img1)
  431. # if ratio >= 0.02:
  432. for j in range(len(result_list)):
  433. if random.choice([0, 1, 1, 1]):
  434. img1 = img_list[j]
  435. img1 = add_contrast(img1)
  436. else:
  437. img1 = result_list[j][0]
  438. img1 = pil_resize(img1, shape[0], shape[1])
  439. img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
  440. img1 = np.expand_dims(img1, axis=-1)
  441. # img1 = cv2.adaptiveThreshold(img1, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,
  442. # 11, 20)
  443. # img1 = np.expand_dims(img1, axis=-1)
  444. # cv2.imshow("origin", img1)
  445. # if noise:
  446. # if random.choice([0, 1]):
  447. # img1 = 255 - img1
  448. # _, img1 = cv2.threshold(img1, 110, 255, cv2.THRESH_BINARY)
  449. char_list = result_list[j][1]
  450. if char_list[0] is None:
  451. # char_index_list = [0] * len(char_list)
  452. # print("len(map_str)+1", len(map_str)+1)
  453. char_index_list = [blank_index] * len(char_list)
  454. else:
  455. char_index_list = []
  456. for c in char_list:
  457. if c in char_map_dict.keys():
  458. c = char_map_dict.get(c)
  459. if not c:
  460. continue
  461. # print("c", c)
  462. # char_index_list.append(map_str.index(c)+1)
  463. char_index_list.append(map_str.index(c))
  464. char_index_list.extend([blank_index] * (label_len-len(char_index_list)))
  465. label = np.array(char_index_list)
  466. ratio = get_image_legal(img1)
  467. # img1 = pil_resize(img, shape[0], shape[1])
  468. # img2 = copy.deepcopy(img1)
  469. # print(char_list)
  470. # print(char_index_list)
  471. # print("ratio", ratio)
  472. # cv2.imshow("gen_char", img1)
  473. # cv2.waitKey(0)
  474. # img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
  475. # img1 = np.expand_dims(img1, axis=-1)
  476. img1 = img1 / 255.
  477. X[j] = img1
  478. Y[j] = label
  479. i += 1
  480. yield [X, Y, input_length, label_length], np.ones(batch_size)
  481. def gen_equation_denoise(paths, batch_size=32, shape=(40, 40)):
  482. while True:
  483. height, width = shape[:2]
  484. if len(shape) > 2 and shape[2] == 3:
  485. channel = 3
  486. else:
  487. channel = 1
  488. X = np.zeros((batch_size, height, width, channel))
  489. Y = np.zeros((batch_size, height, width, channel))
  490. result_list = generate_data_denoise(batch_size)
  491. j = 0
  492. for img, noise in result_list:
  493. img1 = pil_resize(img, shape[0], shape[1])
  494. img2 = pil_resize(noise, shape[0], shape[1])
  495. # img1 = add_contrast(img1)
  496. # img2 = add_contrast(img2)
  497. # cv2.imshow("origin", img2)
  498. img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
  499. img1 = np.expand_dims(img1, axis=-1)
  500. img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
  501. img2 = np.expand_dims(img2, axis=-1)
  502. # cv2.imshow("bg", img1)
  503. # cv2.imshow("noise", img2)
  504. # cv2.waitKey(0)
  505. img1 = img1 / 255.
  506. img2 = img2 / 255.
  507. X[j] = img2
  508. Y[j] = img1
  509. j += 1
  510. yield X, Y
  511. def generate_data_siamese(char_num=6, char_shape=(40, 40)):
  512. bg_paths = glob("../data/base/*")
  513. char_path = "../data/chinese_2500.txt"
  514. with open(char_path, "r") as f:
  515. char_str = f.read()
  516. data_dir = "../data/click/"
  517. for i in range(1000):
  518. bg = cv2.imread(random.sample(bg_paths, 1)[0])
  519. char_list = [char_str[x] for x in random.sample(range(len(char_str)), char_num)]
  520. image_np, position_list, tips_image_list = char_on_image(bg, char_list, char_shape)
  521. # for j in range(len(char_list)):
  522. # char = char_list[j]
  523. # p = position_list[j]
  524. # print(char)
  525. # cv2.rectangle(image_np, [p[1], p[0]], [p[1]+char_shape[1], p[0]+char_shape[0]], (255, 0, 0), 2)
  526. # cv2.imshow("generate_data", image_np)
  527. # cv2.waitKey(0)
  528. # 保存tips图片
  529. tips_path_list = []
  530. for k in range(len(tips_image_list)):
  531. tips_image = tips_image_list[k]
  532. tips_path = str(i) + "_" + str(k) + ".jpg"
  533. tips_path_list.append(tips_path)
  534. cv2.imwrite(data_dir+tips_path, tips_image)
  535. # 保存文字区域图片
  536. char_path_list = []
  537. for j in range(len(char_list)):
  538. p = position_list[j]
  539. char_path = str(i) + "_" + str(len(tips_image_list)+j) + ".jpg"
  540. char_path_list.append(char_path)
  541. cv2.imwrite(data_dir+char_path, image_np[p[0]:p[0]+char_shape[0], p[1]:p[1]+char_shape[1], :])
  542. # 生成映射数据
  543. with open("../data/click/map.txt", "a") as f:
  544. for j in range(len(tips_path_list)):
  545. tips_path = tips_path_list[j]
  546. for k in range(len(char_path_list)):
  547. char_path = char_path_list[k]
  548. if j == k:
  549. f.write(tips_path + "\t" + char_path + "\t" + str(1) + "\n")
  550. else:
  551. f.write(tips_path + "\t" + char_path + "\t" + str(0) + "\n")
  552. def generate_data_char(char_num=6, char_shape=(40, 40), image_shape=(160, 260)):
  553. # (40,40) (160, 260)
  554. # (80,80) (360, 590)
  555. bg_paths = glob("../data/base/*") + glob("../data/base1/*")*100
  556. char_path = "../data/chinese_simple_5649.txt"
  557. with open(char_path, "r") as f:
  558. char_list = f.readlines()
  559. # random.shuffle(char_list)
  560. char_str = "".join(char_list)
  561. char_str = re.sub("\n", "", char_str)
  562. data_dir = "../data/click_simple/"
  563. # 每个字生成多张图片
  564. start_time = time.time()
  565. # 0- 1520 4000- 5760
  566. for i in range(0, 6000):
  567. if i % 20 == 0:
  568. print("Loop", i, time.time()-start_time)
  569. start_time = time.time()
  570. char = char_str[i]
  571. # 生成带背景图数
  572. image_cnt = 1
  573. char_list = [char] * image_cnt
  574. tips_cnt = 0
  575. image_cnt = 265
  576. tips_list = []
  577. for l in range(10):
  578. try:
  579. # 背景图
  580. bg = cv2.imread(random.sample(bg_paths, 1)[0])
  581. if random.choice([0, 0, 1]):
  582. bg = image_enhance_distort(bg)
  583. if random.choice([0, 0, 1]):
  584. bg = image_enhance_flip(bg)
  585. # 生成4张tips图,6张带背景的旋转图
  586. image_np, p_list, t_list = char_on_image(bg, char_list, char_shape, image_shape,
  587. char_stretch=False)
  588. # cv2.imshow("char_on_image", image_np)
  589. # cv2.waitKey(0)
  590. tips_list += t_list
  591. for p in p_list:
  592. char_path = str(i) + "_" + str(image_cnt) + "_2" + ".jpg"
  593. # 放大缩小box
  594. if random.choice([1, 1, 1, 0]):
  595. threshold = random.randint(12, 25)
  596. y1 = max(0, p[0]-random.choice([0, threshold]))
  597. y2 = min(image_np.shape[0], p[0]+char_shape[0]+random.choice([0, threshold]))
  598. x1 = max(0, p[1]-random.choice([0, threshold]))
  599. x2 = min(image_np.shape[1], p[1]+char_shape[1]+random.choice([0, threshold]))
  600. # print(threshold)
  601. else:
  602. threshold = random.randint(4, 8)
  603. y1 = p[0]+random.choice([0, threshold])
  604. y2 = p[0]+char_shape[0]-random.choice([0, threshold])
  605. x1 = p[1]+random.choice([0, threshold])
  606. x2 = p[1]+char_shape[1]-random.choice([0, threshold])
  607. # 平移box
  608. if random.choice([0, 0, 1]):
  609. threshold = random.randint(8, 13)
  610. h_flag, w_flag = 0, 0
  611. if random.choice([0, 1]):
  612. threshold = -threshold
  613. if random.choice([0, 1, 1]):
  614. h_flag = 1
  615. if random.choice([0, 1, 1]):
  616. w_flag = 1
  617. y1 = p[0]+threshold*h_flag
  618. y2 = p[0]+char_shape[0]+threshold*h_flag
  619. x1 = p[1]+threshold*w_flag
  620. x2 = p[1]+char_shape[1]+threshold*w_flag
  621. sub_image_np = image_np[y1:y2,
  622. x1:x2,
  623. :]
  624. if sub_image_np.shape[0] == 0 or sub_image_np.shape[1] == 0:
  625. continue
  626. sub_image_np = pil_resize(sub_image_np, char_shape[0], char_shape[1])
  627. # cv2.imshow("sub_image_np", sub_image_np)
  628. # cv2.waitKey(0)
  629. cv2.imwrite(data_dir+char_path, sub_image_np)
  630. image_cnt += 1
  631. except:
  632. print(1)
  633. continue
  634. for tips_image in tips_list[:1]:
  635. tips_path = str(i) + "_" + str(tips_cnt) + "_1" + ".jpg"
  636. # cv2.imshow("tips_image", tips_image)
  637. # cv2.waitKey(0)
  638. cv2.imwrite(data_dir+tips_path, tips_image)
  639. tips_cnt += 1
  640. def generate_data_char_from_yolo():
  641. _dir = "D:/Project/captcha/data/detect/"
  642. map_path = _dir + "map.txt"
  643. with open(map_path, "r") as f:
  644. map_list = f.readlines()
  645. char_image_list = []
  646. for line in map_list[:10]:
  647. image_path = _dir + line.split(" ")[0]
  648. boxes = line[:-1].split(" ")[1:]
  649. boxes = [list(map(int, box.split(','))) for box in boxes]
  650. print(image_path, boxes)
  651. image = cv2.imread(image_path)
  652. for box in boxes:
  653. char_image = image[box[1]:box[3], box[0]:box[2], :]
  654. char_image_list.append(char_image)
  655. return
  656. def generate_data_yolo_char(image_shape=(160, 256)):
  657. bg_paths = glob("../data/base1/*")
  658. char_path = "../data/chinese_6270.txt"
  659. with open(char_path, "r") as f:
  660. char_map_list = f.readlines()
  661. random.shuffle(char_map_list)
  662. data_dir = "../data/detect/"
  663. # with open(data_dir+"map.txt", "w") as f:
  664. # f.write("")
  665. j = 0
  666. start_time = time.time()
  667. for i in range(46121, 46500):
  668. if i % 50 == 0:
  669. print("Loop", i, time.time()-start_time)
  670. start_time = time.time()
  671. if j >= len(char_map_list)-1:
  672. j = 0
  673. random.shuffle(char_map_list)
  674. # 随机底图大小
  675. r = random.randint(160, 256)
  676. # random_image_shape = (r, random.choice([r*3, int(r*2.5), int(r*3.5), r*4]))
  677. random_image_shape = (r, r*3)
  678. # 随机shape和num
  679. r = random.randint(30, 40)
  680. char_shape = (r, r)
  681. char_num = random.randint(4, 6)
  682. tips_char_num = min(random.randint(3, char_num), 4)
  683. # 背景
  684. try:
  685. bg = cv2.imread(random.sample(bg_paths, 1)[0])
  686. # bg = pil_resize(bg, random_image_shape[0], random_image_shape[1])
  687. if random.choice([0, 0, 0]):
  688. bg = image_enhance_distort(bg)
  689. if random.choice([0, 0, 0]):
  690. bg = image_enhance_flip(bg)
  691. except:
  692. print(1)
  693. continue
  694. if bg is None:
  695. print(2)
  696. continue
  697. # 随机取char
  698. char_list = [x[:-1] for x in char_map_list[j:j+char_num]]
  699. # print("char_list", char_list)
  700. j = j+char_num
  701. # 生成图
  702. image_np, position_list, tips_image_list = char_on_image(bg, char_list, char_shape, random_image_shape, tips_char_num)
  703. if i < 5000:
  704. tips_image_np, tips_position_list = get_tips_image(tips_image_list, char_shape, random_image_shape)
  705. image_np_path = str(i) + ".jpg"
  706. # print(image_np.shape)
  707. image_np = pil_resize(image_np, image_shape[0], image_shape[1])
  708. cv2.imwrite(data_dir+image_np_path, image_np)
  709. if i < 5000:
  710. tips_image_np_path = str(i) + "_0.jpg"
  711. tips_image_np = pil_resize(tips_image_np, image_shape[0], image_shape[1])
  712. cv2.imwrite(data_dir+tips_image_np_path, tips_image_np)
  713. # 生成映射数据
  714. with open(data_dir+"map.txt", "a") as f:
  715. box_str = ""
  716. for p in position_list:
  717. x1 = int(p[1] * image_shape[1] / random_image_shape[1])
  718. y1 = int(p[0] * image_shape[0] / random_image_shape[0])
  719. x2 = int((p[1]+char_shape[1]) * image_shape[1] / random_image_shape[1])
  720. y2 = int((p[0]+char_shape[0]) * image_shape[0] / random_image_shape[0])
  721. threshold = random.randint(2, 4)
  722. if random.choice([0, 1]):
  723. y1 = max(0, y1 - threshold)
  724. y2 = min(image_np.shape[0], y2 + threshold)
  725. x1 = max(0, x1 - threshold)
  726. x2 = min(image_np.shape[1], x2 + threshold)
  727. # print(threshold)
  728. box_str += str(x1) + "," + str(y1) + "," + \
  729. str(x2) + "," + str(y2) + "," + \
  730. str(0) + " "
  731. # cv2.rectangle(image_np, (x1, y1), (x2, y2), (255, 0, 0), 2)
  732. # cv2.imshow("image_np", image_np)
  733. # cv2.waitKey(0)
  734. box_str = box_str[:-1]
  735. f.write(image_np_path + " " + box_str + "\n")
  736. if i < 5000:
  737. box_str = ""
  738. x1 = int(p[1] * image_shape[1] / random_image_shape[1])
  739. y1 = int(p[0] * image_shape[0] / random_image_shape[0])
  740. x2 = int((p[1]+char_shape[1]) * image_shape[1] / random_image_shape[1])
  741. y2 = int((p[0]+char_shape[0]) * image_shape[0] / random_image_shape[0])
  742. for p in tips_position_list:
  743. box_str += str(x1) + "," + str(y1) + "," + \
  744. str(x2) + "," + str(y2) + "," + \
  745. str(0) + " "
  746. cv2.rectangle(tips_image_np, (x1, y1), (x2, y2), (255, 0, 0), 2)
  747. # cv2.imshow("tips_image_np", tips_image_np)
  748. box_str = box_str[:-1]
  749. f.write(tips_image_np_path + " " + box_str + "\n")
  750. def generate_data_yolo_char_1(image_shape=(160, 256)):
  751. bg_paths = glob("../data/base/*")
  752. char_path = "../data/chinese_6270.txt"
  753. with open(char_path, "r") as f:
  754. char_map_list = f.readlines()
  755. data_dir = "../data/detect/"
  756. # with open(data_dir+"map.txt", "w") as f:
  757. # f.write("")
  758. j = 0
  759. for i in range(20000, 25000):
  760. if i % 1000 == 0:
  761. print("Loop", i)
  762. if j >= len(char_map_list)-1:
  763. j = 0
  764. random.shuffle(char_map_list)
  765. # 随机shape和num
  766. r = random.randint(31, 51)
  767. char_shape = (r, r)
  768. char_num = random.randint(3, 6)
  769. tips_char_num = 0
  770. # 背景
  771. bg = cv2.imread(random.sample(bg_paths, 1)[0])
  772. if random.choice([0, 0, 1]):
  773. bg = image_enhance_distort(bg)
  774. if random.choice([0, 0, 1]):
  775. bg = image_enhance_flip(bg)
  776. # 随机取char
  777. char_list = [x[:-1] for x in char_map_list[j:j+char_num]]
  778. # print("char_list", char_list)
  779. j = j+char_num
  780. # 生成图
  781. image_np, position_list, tips_image_list = char_on_image(bg, char_list, char_shape,
  782. image_shape, tips_char_num,
  783. only_color=(0, 0, 0))
  784. image_np_path = str(i) + ".jpg"
  785. cv2.imwrite(data_dir+image_np_path, image_np)
  786. # 生成映射数据
  787. with open(data_dir+"map.txt", "a") as f:
  788. box_str = ""
  789. for p in position_list:
  790. box_str += str(p[1]) + "," \
  791. + str(p[0]) + "," \
  792. + str(p[1]) + "," \
  793. + str(p[0]) + "," \
  794. + str(0) + " "
  795. # cv2.rectangle(image_np, (p[1], p[0]), (p[1]+char_shape[1], p[0]+char_shape[0]), (255, 0, 0), 2)
  796. # cv2.imshow("image_np", image_np)
  797. # cv2.waitKey(0)
  798. box_str = box_str[:-1]
  799. f.write(image_np_path + " " + box_str + "\n")
  800. def generate_data_yolo_puzzle(image_shape=(160, 256)):
  801. bg_paths = glob("../data/base/*.jpeg")
  802. data_dir = "../data/detect2/"
  803. with open(data_dir+"map.txt", "w") as f:
  804. f.write("")
  805. for i in range(0, 10000):
  806. if i % 1000 == 0:
  807. print("Loop", i)
  808. bg = cv2.imread(random.sample(bg_paths, 1)[0])
  809. if random.choice([0, 0, 1]):
  810. bg = image_enhance_distort(bg)
  811. if random.choice([0, 0, 1]):
  812. bg = image_enhance_flip(bg)
  813. r = random.randint(35, 60)
  814. puzzle_shape = (r, r)
  815. image_np, position_list = puzzle_on_image(bg, puzzle_shape, image_shape)
  816. image_np_path = str(i) + ".jpg"
  817. cv2.imwrite(data_dir+image_np_path, image_np)
  818. # 生成映射数据
  819. with open(data_dir+"map.txt", "a") as f:
  820. box_str = ""
  821. for p in position_list:
  822. box_str += str(p[1]) + "," + str(p[0]) + "," + \
  823. str(p[1]+puzzle_shape[1]) + "," + str(p[0]+puzzle_shape[0]) + \
  824. "," + str(0) + " "
  825. # cv2.rectangle(image_np, (p[1], p[0]), (p[1]+puzzle_shape[1], p[0]+puzzle_shape[0]), (255, 0, 0), 2)
  826. # cv2.imshow("image_np", image_np)
  827. # cv2.waitKey(0)
  828. box_str = box_str[:-1]
  829. f.write(image_np_path + " " + box_str + "\n")
  830. def generate_data_drag_image(image_shape=(160, 260)):
  831. bg_paths = glob("../data/base/*")
  832. data_dir = "../data/drag/"
  833. with open(data_dir+"map.txt", "w") as f:
  834. f.write("")
  835. for i in range(10000):
  836. if i % 1000 == 0:
  837. print("Loop", i)
  838. bg = cv2.imread(random.sample(bg_paths, 1)[0])
  839. bg = pil_resize(bg, image_shape[0], image_shape[1])
  840. if random.choice([0, 0, 1]):
  841. bg = image_enhance_distort(bg)
  842. if random.choice([0, 0, 1]):
  843. bg = image_enhance_flip(bg)
  844. image_np, clip_line = get_drag_image(bg)
  845. image_np_path = str(i) + ".jpg"
  846. cv2.imwrite(data_dir+image_np_path, image_np)
  847. # 生成映射数据
  848. with open(data_dir+"map.txt", "a") as f:
  849. f.write(image_np_path + " " + str(clip_line[0][0]) + "\n")
  850. def generate_data_phrase():
  851. data_path = os.path.dirname(os.path.abspath(__file__)) + "/../data/phrase/"
  852. char_path = data_path+"char.txt"
  853. with open(char_path, "r") as f:
  854. char_list = f.readlines()
  855. char_dict = {}
  856. for i in range(len(char_list)):
  857. char_dict[char_list[i]] = i
  858. phrase_list = []
  859. phrase_path = data_path+"phrase3.txt"
  860. with open(phrase_path, "r") as f:
  861. phrase_list += f.readlines()
  862. phrase_path = data_path+"phrase4.txt"
  863. with open(phrase_path, "r") as f:
  864. phrase_list += f.readlines()
  865. phrase_path = data_path+"phrase5.txt"
  866. with open(phrase_path, "r") as f:
  867. phrase_list += f.readlines()
  868. phrase_set = set(phrase_list)
  869. map_path = data_path+"map3.txt"
  870. with open(map_path, "w") as f:
  871. f.write("")
  872. data_list = []
  873. start_time = time.time()
  874. i = 0
  875. negative_way_flag = False
  876. for phrase in phrase_list:
  877. if i % 500000 == 0:
  878. with open(map_path, "a") as f:
  879. f.writelines(data_list)
  880. data_list = []
  881. print("Loop", i, len(phrase_list), time.time()-start_time)
  882. start_time = time.time()
  883. i += 1
  884. # 正样本
  885. index_list = []
  886. for char in phrase[:-1]:
  887. index_list.append(char_dict.get(char+"\n"))
  888. data_list.append(str(index_list) + " 1\n")
  889. # 负样本
  890. if negative_way_flag:
  891. index1 = random.randint(0, len(index_list)-1)
  892. find_flag = False
  893. while not find_flag:
  894. index2 = random.randint(0, len(index_list)-1)
  895. if index1 != index2:
  896. find_flag = True
  897. temp = index_list[index1]
  898. index_list[index1] = index_list[index2]
  899. index_list[index2] = temp
  900. if "".join([char_list[x][:-1] for x in index_list]) + "\n" not in phrase_set:
  901. data_list.append(str(index_list) + " 0\n")
  902. else:
  903. products = list(product(index_list, repeat=len(index_list)))
  904. random.shuffle(products)
  905. negative_cnt = 0
  906. for p in products:
  907. if negative_cnt >= 2:
  908. break
  909. p = list(p)
  910. if len(set(p)) != len(p):
  911. continue
  912. if p != index_list and "".join([char_list[x][:-1] for x in p]) + "\n" not in phrase_set:
  913. data_list.append(str(p) + " 0\n")
  914. negative_cnt += 1
  915. with open(map_path, "a") as f:
  916. f.writelines(data_list)
  917. def generate_data_phrase_raw(word_len=5):
  918. paths = glob("D:/Chinese_corpus/answer/*/*.txt")
  919. phrase_path = "../data/phrase/phrase" + str(word_len) + "_new.txt"
  920. triple_list = []
  921. reg = "[^\u4e00-\u9fa5]"
  922. start_time = time.time()
  923. for i in range(len(paths)):
  924. if i % 1000 == 0:
  925. with open(phrase_path, "w") as f:
  926. f.writelines(triple_list)
  927. print("Loop", i, len(paths), time.time()-start_time)
  928. start_time = time.time()
  929. triple_list = []
  930. with open(paths[i], "rb") as f:
  931. _b = f.read()
  932. try:
  933. text = _b.decode("gbk")
  934. except:
  935. try:
  936. text = _b.decode("gb2312")
  937. except:
  938. try:
  939. text = _b.decode("gb18030")
  940. except:
  941. print(chardet.detect(_b), "is None")
  942. filter_word = ["的"]
  943. for word in filter_word:
  944. text = re.sub(word, "#"*len(word), text)
  945. word_list = jieba.lcut(text, cut_all=False, HMM=True)
  946. for j in range(1, len(word_list)):
  947. current = word_list[j]
  948. current_re = re.search(reg, current)
  949. last = word_list[j-1]
  950. last_re = re.search(reg, last)
  951. if current_re:
  952. continue
  953. if len(current) == word_len:
  954. triple_list.append(current + "\n")
  955. elif len(current) + len(last) == word_len and not last_re:
  956. triple_list.append(last+current + "\n")
  957. triple_list = list(set(triple_list))
  958. print("len(triple_list)", len(triple_list))
  959. with open(phrase_path, "w") as f:
  960. f.writelines(triple_list)
  961. def generate_data_equation():
  962. char_dict = {
  963. 1: ['1', '一'],
  964. 2: ['2', '二'],
  965. 3: ['3', '三'],
  966. 4: ['4', '四'],
  967. 5: ['5', '五'],
  968. 6: ['6', '六'],
  969. 7: ['7', '七'],
  970. 8: ['8', '八'],
  971. 9: ['9', '九'],
  972. 0: ['0', '零'],
  973. '+': ['+', '加', '加上'],
  974. '-': ['-', '减', '减去'],
  975. '*': ["*", "×", 'x', '乘', '乘以'],
  976. '/': ["/", '除', '÷'],
  977. '?': ['?', '?'],
  978. '去': ['去'],
  979. '上': ['上'],
  980. '以': ['以'],
  981. }
  982. only_op_dict = {
  983. '+': ['+', '加'],
  984. '-': ['-', '减'],
  985. '*': ["*", "×", 'x', '乘'],
  986. '/': ["/", '除', '÷'],
  987. }
  988. file_name_dict = {
  989. '*': "星",
  990. "/": "斜",
  991. "?": "问",
  992. }
  993. data_dir = "../data/equation/"
  994. # 每个字生成多张图片
  995. start_time = time.time()
  996. # 0- 1520 4000- 5760
  997. for i in range(0, 100):
  998. if i % 20 == 0:
  999. print("Loop", i, time.time()-start_time)
  1000. start_time = time.time()
  1001. if random.choice([1, 1]):
  1002. # 随机生成算式
  1003. char_list = []
  1004. result = -1
  1005. op = random.choice(['+', '-', '*', '/'])
  1006. while result < 0:
  1007. n1 = random.choice([random.randint(0, 9), random.randint(10, 99)])
  1008. n2 = random.choice([random.randint(0, 9), random.randint(10, 99)])
  1009. if op == '-':
  1010. result = n1 - n2
  1011. else:
  1012. result = 1
  1013. if len(str(n1)) > 1:
  1014. n1 = [x for x in str(n1)]
  1015. else:
  1016. n1 = [random.choice(char_dict[n1])]
  1017. if len(str(n2)) > 1:
  1018. n2 = [x for x in str(n2)]
  1019. else:
  1020. n2 = [random.choice(char_dict[n2])]
  1021. op = random.choice(char_dict[op])
  1022. if len(op) > 1:
  1023. op = [x for x in op]
  1024. else:
  1025. op = [op]
  1026. char_list.extend(n1)
  1027. char_list.extend(op)
  1028. char_list.extend(n2)
  1029. if random.choice([0, 0, 0, 1]):
  1030. char_list.append('=')
  1031. char_list.append(random.choice([''] + char_dict['?']))
  1032. else:
  1033. # 随机生成非算式
  1034. char_list = random.sample(list(char_dict.keys())+list(only_op_dict.keys())*2, random.randint(3, 6))
  1035. char_list = [random.choice(char_dict[x]) for x in char_list]
  1036. if random.choice([0, 0]):
  1037. # 生成背景图
  1038. big_flag = 0
  1039. if random.choice([0, 1]):
  1040. h = random.randint(50, 60)
  1041. w = random.randint(200, 280)
  1042. else:
  1043. h = random.randint(120, 150)
  1044. w = random.randint(400, 680)
  1045. big_flag = 1
  1046. bg = np.full((h, w, 3), random.randint(180, 255), dtype=np.uint8)
  1047. current_w = random.randint(0, int(w/3))
  1048. for char in char_list:
  1049. # 获取单字图片
  1050. if big_flag:
  1051. r = random.randint(80, 120)
  1052. else:
  1053. r = random.randint(35, 45)
  1054. char_image_pil = get_char_image2(char, (r, r), rotate=False)
  1055. # 字体添加到背景图上
  1056. position_h = random.randint(0, bg.shape[0]-r)
  1057. try:
  1058. position_w = random.randint(current_w-15, min(current_w+random.randint(0, 5), bg.shape[1]-r))
  1059. except:
  1060. position_w = current_w
  1061. current_w = position_w+r
  1062. bg = get_image_paste(bg, char_image_pil, position_h, position_w)
  1063. # 增加噪声
  1064. bg = create_noise(bg)
  1065. else:
  1066. fig_size = random.choice([(70, 25), (100, 26), (100, 40)])
  1067. line = (1, 4)
  1068. wavy = (1, 3)
  1069. font_size = random.choice([(18, 25), (35, 40)])
  1070. # 定制
  1071. fig_size = (90, 34)
  1072. line = (1, 4)
  1073. wavy = (0, 0)
  1074. font_size = (38, 50)
  1075. offset_w = (-10, -2)
  1076. bg = generate_data_equation_lsm("".join(char_list),
  1077. fig_size=fig_size,
  1078. font_color=random.choice([(20, 230, 20, 230, 20, 230),
  1079. (70, 100),
  1080. (10, 230, 10, 230, 10, 230),
  1081. ]),
  1082. font_size=font_size,
  1083. rotate=random.choice([0, ]),
  1084. shortline=(1, 5),
  1085. line=line,
  1086. line_width=(1, 3),
  1087. wavy=wavy,
  1088. offset_w=offset_w,
  1089. offset_h=5,
  1090. same_color=0,
  1091. )
  1092. bg = pil2np(bg)
  1093. bg = create_noise_short_lines(bg, random.randint(3, 8))
  1094. # 数据增强
  1095. if random.choice([0, 1]):
  1096. bg = np2pil(bg)
  1097. aug = random.choice([0, 1, 2, 3, 5])
  1098. if aug == 0:
  1099. bg = image_enhance_color(bg)
  1100. elif aug == 1:
  1101. bg = image_enhance_brightness(bg)
  1102. elif aug == 2:
  1103. bg = image_enhance_contrast(bg)
  1104. elif aug == 3:
  1105. bg = image_enhance_sharpness(bg)
  1106. elif aug == 4:
  1107. bg = image_enhance_blur(bg)
  1108. bg = pil2np(bg)
  1109. if aug == 5:
  1110. bg = image_enhance_distort(bg)
  1111. # print("aug", aug)
  1112. # show
  1113. cv2.imshow("bg", bg)
  1114. cv2.waitKey(0)
  1115. # write
  1116. for j in range(len(char_list)):
  1117. if char_list[j] in file_name_dict.keys():
  1118. char_list[j] = file_name_dict.get(char_list[j])
  1119. image_path = str(i) + "_" + "_".join(char_list) + ".jpg"
  1120. cv2.imwrite(data_dir+image_path, bg)
  1121. def generate_data_equation2(batch_size, noise=True):
  1122. char_dict = {
  1123. 1: ['1', '一'],
  1124. 2: ['2', '二'],
  1125. 3: ['3', '三'],
  1126. 4: ['4', '四'],
  1127. 5: ['5', '五'],
  1128. 6: ['6', '六'],
  1129. 7: ['7', '七'],
  1130. 8: ['8', '八'],
  1131. 9: ['9', '九'],
  1132. 0: ['0', '零'],
  1133. '+': ['+', '加', '加上'],
  1134. '-': ['-', '减', '减去'],
  1135. '*': ["*", "×", 'x', '乘', '乘以'],
  1136. '/': ['除', '÷'],
  1137. '?': ['?', '?'],
  1138. '去': ['去'],
  1139. '上': ['上'],
  1140. '以': ['以'],
  1141. }
  1142. only_op_dict = {
  1143. '+': ['+', '加', '加上'],
  1144. '-': ['-', '减', '减去'],
  1145. '*': ["*", "×", 'x', '乘', '乘以'],
  1146. '/': ['除', '÷'],
  1147. }
  1148. # 每个字生成多张图片
  1149. result_list = []
  1150. i = 0
  1151. while i < batch_size:
  1152. # for i in range(0, batch_size):
  1153. simple_flag = random.choice([0, 1])
  1154. # empty_flag = random.choice([0, 0, 0, 0, 0, 1, 0, 0, 0, 0])
  1155. empty_flag = 0
  1156. if random.choice([1, 1]):
  1157. # 随机生成算式
  1158. char_list = []
  1159. # result = -1
  1160. op = random.choice(['+', '-', '*'])
  1161. # while result < 0:
  1162. if not simple_flag:
  1163. n1 = random.choice([random.randint(0, 9), random.randint(10, 99)])
  1164. n2 = random.choice([random.randint(0, 9), random.randint(10, 99)])
  1165. # if op == '-':
  1166. # result = n1 - n2
  1167. # else:
  1168. # result = 1
  1169. if len(str(n1)) > 1:
  1170. n1 = [x for x in str(n1)]
  1171. else:
  1172. n1 = [random.choice(char_dict[n1])]
  1173. if len(str(n2)) > 1:
  1174. n2 = [x for x in str(n2)]
  1175. else:
  1176. n2 = [random.choice(char_dict[n2])]
  1177. else:
  1178. n1 = random.randint(0, 9)
  1179. n2 = random.randint(0, 9)
  1180. n1 = [random.choice(char_dict[n1])]
  1181. n2 = [random.choice(char_dict[n2])]
  1182. op = random.choice(char_dict[op])
  1183. # if simple_flag:
  1184. # op = op[0]
  1185. if len(op) > 1:
  1186. op = [x for x in op]
  1187. else:
  1188. op = [op]
  1189. char_list.extend(n1)
  1190. char_list.extend(op)
  1191. char_list.extend(n2)
  1192. if random.choice([0, 0, 0, 1]):
  1193. char_list.append('=')
  1194. if random.choice([0, 1]) and not simple_flag:
  1195. char_list.append(random.choice(char_dict['?']))
  1196. else:
  1197. # 随机生成非算式
  1198. char_list = random.sample(list(char_dict.keys())+list(only_op_dict.keys())*2, random.randint(3, 6))
  1199. char_list = [random.choice(char_dict[x]) for x in char_list]
  1200. new_char_list = []
  1201. for c in char_list:
  1202. if len(c) > 1:
  1203. new_char_list.extend([x for x in c])
  1204. else:
  1205. new_char_list.append(c)
  1206. char_list = new_char_list
  1207. char_list = char_list[:8]
  1208. if random.choice([0, 0]):
  1209. # 生成背景图
  1210. big_flag = 0
  1211. if random.choice([0, 1]):
  1212. h = random.randint(50, 60)
  1213. w = random.randint(200, 280)
  1214. else:
  1215. h = random.randint(120, 150)
  1216. w = random.randint(400, 680)
  1217. big_flag = 1
  1218. bg = np.full((h, w, 3), random.randint(180, 255), dtype=np.uint8)
  1219. current_w = random.randint(-10, 1)
  1220. for char in char_list:
  1221. # 获取单字图片
  1222. if big_flag:
  1223. r = random.randint(80, 120)
  1224. else:
  1225. r = random.randint(35, 45)
  1226. char_image_pil = get_char_image2(char, (r, r), rotate=False)
  1227. # 字体添加到背景图上
  1228. position_h = random.randint(0, bg.shape[0]-r)
  1229. try:
  1230. position_w = random.randint(current_w-15, min(current_w+random.randint(0, 5), bg.shape[1]-r))
  1231. except:
  1232. position_w = current_w
  1233. current_w = position_w+r
  1234. bg = get_image_paste(bg, char_image_pil, position_h, position_w)
  1235. # 增加噪声
  1236. bg = create_noise(bg)
  1237. else:
  1238. if random.choice([0, 1]):
  1239. fig_size = random.choice([(70, 25), (100, 26), (100, 40)])
  1240. line = (0, 0)
  1241. wavy = (0, 0)
  1242. font_size = random.choice([(18, 25), (35, 40)])
  1243. # offset_w = (-20, 6)
  1244. else:
  1245. # 定制
  1246. fig_size = (90, 34)
  1247. line = (0, 0)
  1248. wavy = (0, 0)
  1249. font_size = (38, 50)
  1250. offset_w = (0, 1)
  1251. if simple_flag:
  1252. fig_size = (random.randint(120, 240), 32)
  1253. font_size = (18, 28)
  1254. if empty_flag:
  1255. bg = np.full((fig_size[1], fig_size[0], 3), fill_value=random.randint(125, 255), dtype=np.uint8)
  1256. char_list = [None] * random.randint(3, 8)
  1257. else:
  1258. bg = generate_data_equation_lsm("".join(char_list),
  1259. fig_size=fig_size,
  1260. font_color=random.choice([(0, 100)]),
  1261. font_size=font_size,
  1262. rotate=random.choice([0, ]),
  1263. shortline=(0, 0),
  1264. line=line,
  1265. line_width=(1, 3),
  1266. wavy=wavy,
  1267. offset_w=offset_w,
  1268. offset_h=5,
  1269. same_color=0,
  1270. simple_flag=simple_flag
  1271. )
  1272. bg = pil2np(bg)
  1273. if get_image_legal(bg) < 0.02:
  1274. continue
  1275. if noise:
  1276. bg = create_noise_point(bg, random.randint(15, 50))
  1277. bg = create_noise_short_lines(bg, random.randint(1, 5))
  1278. # 数据增强
  1279. if random.choice([0, 1]):
  1280. bg = np2pil(bg)
  1281. aug = random.choice([0, 1, 2, 3, 5])
  1282. if aug == 0:
  1283. bg = image_enhance_color(bg)
  1284. elif aug == 1:
  1285. bg = image_enhance_brightness(bg)
  1286. elif aug == 2:
  1287. bg = image_enhance_contrast(bg)
  1288. elif aug == 3:
  1289. bg = image_enhance_sharpness(bg)
  1290. elif aug == 4:
  1291. bg = image_enhance_blur(bg)
  1292. bg = pil2np(bg)
  1293. if aug == 5:
  1294. bg = image_enhance_distort(bg)
  1295. # print("aug", aug)
  1296. # show
  1297. # cv2.imshow("bg", bg)
  1298. # gray = cv2.cvtColor(bg, cv2.COLOR_BGR2GRAY)
  1299. # gray = eight_neighbour(gray, 4)
  1300. # cv2.imshow("gray", gray)
  1301. # cv2.waitKey(0)
  1302. result_list.append([bg, char_list])
  1303. i += 1
  1304. return result_list
  1305. def generate_data_equation_lsm(text, fig_size=(200, 70), fonts=glob("../font/*"), font_color=(10, 100),
  1306. same_color=1, font_size=(25, 35), rotate=0, font_noise=0,
  1307. offset_w=(0, 0), offset_h=0, line=(0, 0), shortline=(0, 0),
  1308. line_width=(0, 1), line_color=(200, 250), point=(0, 500),
  1309. point_color=(150, 250), frame_color=None, wavy=(0, 0),
  1310. bg=(200, 255), simple_flag=0):
  1311. """
  1312. text:验证码文本
  1313. size:验证码图片宽高
  1314. fonts:字体列表,随机选择一个
  1315. font_noise: 字体散点干扰,0不加干扰,1加干扰
  1316. offset_hor: 左右偏移值
  1317. offset_var: 上下偏移值
  1318. fill:字体颜色范围
  1319. rotate:字体旋转角度
  1320. line:干扰线条数范围
  1321. point:干扰点数范围
  1322. wavy:波浪线数范围
  1323. color:干扰线、点 颜色
  1324. bg:背景色范围
  1325. """
  1326. def random_xy(width, height):
  1327. """
  1328. 随机位置函数,返回指定范围随机位置坐标
  1329. 参数:width:图片宽,height:图片高
  1330. """
  1331. x = random.randint(0, width)
  1332. y = random.randint(0, height)
  1333. return x, y
  1334. def random_color(color_tuple):
  1335. """
  1336. 随机颜色函数,返回指定范围随机颜色值
  1337. 参数:start:颜色最低值,end:颜色最高值
  1338. """
  1339. if len(color_tuple)==2:
  1340. rs, re = color_tuple
  1341. gs = bs = rs
  1342. ge = be = re
  1343. else:
  1344. rs, re, gs, ge, bs, be = color_tuple
  1345. red = random.randint(rs, re)
  1346. green = random.randint(gs, ge)
  1347. blue = random.randint(bs, be)
  1348. return (red, green, blue)
  1349. def Asin(x, A=8, w=0.05, b=6, k=40):
  1350. """
  1351. y=Asin(ωx+φ)+k在直角坐标系上的图象
  1352. A——振幅,当物体作轨迹符合正弦曲线的直线往复运动时,其值为行程的1/2。
  1353. (ωx+φ)——相位,反映变量y所处的状态。
  1354. φ——初相,x=0时的相位;反映在坐标系上则为图像的左右移动。
  1355. k——偏距,反映在坐标系上则为图像的上移或下移。
  1356. ω——角速度, 控制正弦周期(单位弧度内震动的次数)。
  1357. """
  1358. return A*math.sin(w*x+b)+k
  1359. def get_wavy_line(w=(0, 100), h=(30, 50)):
  1360. """产生波浪线坐标"""
  1361. import random
  1362. n = 50
  1363. x = 0
  1364. y = random.randint(h[0],h[1])
  1365. flag = random.randint(0,2)
  1366. xy = [(x, y)]
  1367. while x < w[1]:
  1368. temp_y = random.randint(1, 3)
  1369. temp_x = random.randint(5, 10)
  1370. if flag == 0:
  1371. if y + temp_y > h[1]:
  1372. y -= temp_y
  1373. flag = 1
  1374. else:
  1375. y += temp_y
  1376. else:
  1377. if y - temp_y < h[0]:
  1378. y += temp_y
  1379. flag = 0
  1380. else:
  1381. y -= temp_y
  1382. x = x+temp_x if x+temp_x < w[1] else w[1]
  1383. xy.append((x, y))
  1384. return xy
  1385. def get_char_img(char, font, font_color, rotate, bg, font_noise=0):
  1386. """
  1387. 生成单个字符图片,随机颜色加随机旋转
  1388. """
  1389. w, h = draw.textsize(char, font=font)
  1390. im = Image.new('RGBA', (w, h), color=bg)
  1391. ImageDraw.Draw(im).text((0,0), char, font=font, fill=font_color)
  1392. if rotate and char not in ['+', '-', '×']:
  1393. im = im.rotate(random.randint(-rotate, rotate), Image.BILINEAR, expand=1)
  1394. im = im.crop(im.getbbox())
  1395. if font_noise:
  1396. im_draw = ImageDraw.Draw(im)
  1397. # for i in range(random.randint(1,20)):
  1398. for i in range(random.randint(int(w*h*0.01),min(int(w*h*0.05), 5))):
  1399. im_draw.point(xy=(random.randint(0, w), random.randint(0, h)),fill=bg)
  1400. table = []
  1401. for i in range(256):
  1402. table.append(i * 97) # 5.97
  1403. mask = im.convert('L').point(table)
  1404. return (im, mask)
  1405. bg = random_color(bg)
  1406. img = Image.new(mode='RGB', size=fig_size, color=bg)
  1407. draw = ImageDraw.Draw(im=img, mode='RGB')
  1408. font_path = random.choice(fonts)
  1409. # print("font_path", font_path)
  1410. font_size1 = random.randint(font_size[0], font_size[1])
  1411. font = ImageFont.truetype(font_path, size=font_size1) # font=None, size=10, index=0, encoding=""
  1412. rotate = random.randint(0, rotate)
  1413. char_color = random_color(font_color)
  1414. re_s = re.search('(\d+|\?)(\+|-|\*|×)(\d+|\?)(=)(-?\d+|\?)?', text)
  1415. if re_s:
  1416. # print(re_s.group(0))
  1417. char_imgs = []
  1418. char_list = []
  1419. if same_color:
  1420. for i in range(1, 6):
  1421. if re_s.group(i) is not None:
  1422. char_list.append(re_s.group(i))
  1423. char_imgs.append(get_char_img(re_s.group(i), font, font_color=char_color, rotate=rotate, bg=bg, font_noise=font_noise))
  1424. else:
  1425. for i in range(1, 6):
  1426. if re_s.group(i) is not None:
  1427. char_list.append(re_s.group(i))
  1428. char_imgs.append(get_char_img(re_s.group(i), font, font_color=random_color(font_color), rotate=rotate, bg=bg, font_noise=font_noise))
  1429. else:
  1430. if same_color:
  1431. char_imgs = [get_char_img(char, font, font_color=char_color, rotate=rotate, bg=bg, font_noise=font_noise) for char in text]
  1432. else:
  1433. char_imgs = [get_char_img(char, font, font_color=random_color(font_color), rotate=rotate, bg=bg, font_noise=font_noise) for char in text]
  1434. ws = [img[0].size[0] for img in char_imgs]
  1435. hs = [img[0].size[1] for img in char_imgs]
  1436. w = max(sum(ws), fig_size[0])
  1437. h = max(max(hs), fig_size[1])
  1438. if w>fig_size[0] or h>fig_size[1]:
  1439. img = Image.new('RGB', (w+6, h+6), color=bg)
  1440. draw = ImageDraw.Draw(im=img, mode='RGB') # im, mode=None
  1441. w, h = img.size
  1442. fig_size = img.size
  1443. # 短线
  1444. for i in range(random.randint(shortline[0], shortline[1])):
  1445. x0, y0 = random_xy(w, h)
  1446. x1 = x0 + random.randint(2, 5)
  1447. y1 = y0 + random.randint(2, 5)
  1448. draw.line(xy=((x0,y0),(x1,y1)),
  1449. fill=random_color(line_color),
  1450. width=random.randint(line_width[0], line_width[1])) # xy, fill=None, width=0
  1451. if rotate:
  1452. temp_x = random.randint(0, min(570, int((fig_size[0]-sum(ws))/2+1))) # int((fig_size[0]-sum(ws))/5)
  1453. # temp_y = random.randint(int((fig_size[1]-hs[0])/8), int((fig_size[1]-hs[0])/2+1))
  1454. temp_y = random.randint(0, int(fig_size[1]/4))
  1455. # print('len(char_imgs):',len(char_imgs))
  1456. for i in range(len(char_imgs)):
  1457. # tmp_offset = random.randint(offset_w[0], offset_w[1]) if sum(ws)+(len(ws)-1)*offset_w[1]<fig_size[0] else 0
  1458. tmp_offset = random.randint(offset_w[0], offset_w[1])
  1459. if i > 0:
  1460. temp_x = new_x
  1461. temp_y = new_y
  1462. # temp_x = new_x if new_x+ws[i] < fig_size[0] else temp_x+ws[i-1]
  1463. # temp_y = new_y if 0 < new_y and new_y+hs[i] < fig_size[1] else random.randint(0, h-hs[i]+1)
  1464. table = []
  1465. for _i in range(256):
  1466. table.append(_i * 97) # 5.97
  1467. mask = img.crop((temp_x, temp_y, temp_x+char_imgs[i][0].size[0], temp_y+char_imgs[i][0].size[1])).convert('L').point(table)
  1468. img.paste(char_imgs[i][0], box=(temp_x, temp_y), mask=mask)
  1469. new_x = temp_x+ws[i]+tmp_offset
  1470. new_y = temp_y+random.randint(-offset_h, offset_h)
  1471. # 直线
  1472. for i in range(random.randint(line[0], line[1])):
  1473. x0, y0 = random_xy(w, h)
  1474. x1, y1 = random_xy(w, h)
  1475. draw.line(xy=((x0, y0), (x1, y1)),
  1476. fill=random_color(line_color),
  1477. width=random.randint(line_width[0], line_width[1]))
  1478. # 散点
  1479. # for i in range(random.randint(point[0], point[1])):
  1480. # if font_color == point_color:
  1481. # draw.point(xy=(random.randint(0, fig_size[0]), random.randint(0, fig_size[1])),
  1482. # fill=char_color)
  1483. # else:
  1484. # draw.point(xy=(random.randint(0, fig_size[0]), random.randint(0, fig_size[1])),
  1485. # fill=random_color(point_color))
  1486. if random.random() >= 0.5:
  1487. A_ = random.uniform(hs[1]*0.1, hs[1]*0.2)
  1488. w_ = math.pi*4/w # random.uniform(0.04, 0.06)
  1489. b_ = random.random()*math.pi
  1490. k_ = random.uniform(h*0.5, h*0.7)
  1491. # 波浪线
  1492. for _ in range(random.randint(wavy[0],wavy[1])):
  1493. draw.line(xy=[(x, Asin(x, A_, w_, b_, k_)) for x in range(int(w))],
  1494. fill=char_color, width=random.randint(line_width[0], line_width[1]))
  1495. else:
  1496. # 波浪线
  1497. for _ in range(random.randint(wavy[0], wavy[1])):
  1498. draw.line(xy=get_wavy_line(w=(0, w), h=(min(hs)-5, max(hs)+5)),
  1499. fill=char_color, width=random.randint(line_width[0], line_width[1]))
  1500. # 边框
  1501. if frame_color is not None:
  1502. draw.line(xy=[(0, 0), (0, h), (0, 0), (w, 0), (w-1, 0), (w-1, h), (0, h-1), (w-1, h-1)], fill=random_color(frame_color))
  1503. if simple_flag:
  1504. offset_w = (int(1/15*fig_size[0]), int(1/12*fig_size[0]))
  1505. else:
  1506. offset_w = (int(-1/5*font_size1), int(-1/10*font_size1))
  1507. if not rotate:
  1508. # temp_x = random.randint(0, min(70, int((fig_size[0]-sum(ws))/2+1))) #int((fig_size[0]-sum(ws))/5)
  1509. # temp_y = random.randint(int((fig_size[1]-hs[0])/8), int((fig_size[1]-hs[0])/2+1))
  1510. if simple_flag:
  1511. temp_x = random.randint(0, int(fig_size[0]/8))
  1512. else:
  1513. temp_x = random.randint(0, int(fig_size[0]/4))
  1514. temp_y = 0
  1515. for i in range(len(char_imgs)):
  1516. # tmp_offset = random.randint(offset_w[0], offset_w[1]) if sum(ws)+(len(ws)-1)*offset_w[1]<fig_size[0] else 0
  1517. tmp_offset = random.randint(offset_w[0], offset_w[1])
  1518. if i > 0:
  1519. temp_x = new_x
  1520. temp_y = new_y
  1521. # temp_x = new_x if new_x+ws[i] < fig_size[0] else temp_x+ws[i-1]
  1522. # temp_y = new_y if 0 < new_y and new_y+hs[i] < fig_size[1] else temp_y
  1523. if same_color:
  1524. if re_s:
  1525. draw.text((temp_x, temp_y), char_list[i], font=font, fill=char_color)
  1526. else:
  1527. draw.text((temp_x, temp_y), text[i], font=font, fill=char_color)
  1528. else:
  1529. if re_s:
  1530. draw.text((temp_x, temp_y), char_list[i], font=font, fill=random_color(font_color))
  1531. else:
  1532. draw.text((temp_x, temp_y), text[i], font=font, fill=random_color(font_color)) #
  1533. new_x = temp_x+ws[i]+tmp_offset
  1534. # print("new_x", new_x, temp_x, ws[i], tmp_offset)
  1535. new_y = temp_y+random.randint(-offset_h, offset_h)
  1536. # filename = font_name+"_"+str(uuid.uuid1())+"_"+text
  1537. # img.save('/data/python/lsm/gen_captcha/{}.jpg'.format(filename))
  1538. # return img
  1539. return img
  1540. def generate_data_denoise(batch_size):
  1541. char_dict = {
  1542. 1: ['1', '一'],
  1543. 2: ['2', '二'],
  1544. 3: ['3', '三'],
  1545. 4: ['4', '四'],
  1546. 5: ['5', '五'],
  1547. 6: ['6', '六'],
  1548. 7: ['7', '七'],
  1549. 8: ['8', '八'],
  1550. 9: ['9', '九'],
  1551. 0: ['0', '零'],
  1552. '+': ['+', '加', '加上'],
  1553. '-': ['-', '减', '减去'],
  1554. '*': ["*", "×", 'x', '乘', '乘以'],
  1555. '/': ["/", '除', '÷'],
  1556. '?': ['?', '?'],
  1557. '去': ['去'],
  1558. '上': ['上'],
  1559. '以': ['以'],
  1560. }
  1561. only_op_dict = {
  1562. '+': ['+', '加', '加上'],
  1563. '-': ['-', '减', '减去'],
  1564. '*': ["*", "×", 'x', '乘', '乘以'],
  1565. '/': ["/", '除', '÷'],
  1566. }
  1567. # 每个字生成多张图片
  1568. result_list = []
  1569. for i in range(0, batch_size):
  1570. if random.choice([1, 1, 0]):
  1571. # 随机生成算式
  1572. char_list = []
  1573. result = -1
  1574. op = random.choice(['+', '-', '*', '/'])
  1575. while result < 0:
  1576. n1 = random.choice([random.randint(0, 9), random.randint(10, 99)])
  1577. n2 = random.choice([random.randint(0, 9), random.randint(10, 99)])
  1578. if op == '-':
  1579. result = n1 - n2
  1580. else:
  1581. result = 1
  1582. if len(str(n1)) > 1:
  1583. n1 = [x for x in str(n1)]
  1584. else:
  1585. n1 = [random.choice(char_dict[n1])]
  1586. if len(str(n2)) > 1:
  1587. n2 = [x for x in str(n2)]
  1588. else:
  1589. n2 = [random.choice(char_dict[n2])]
  1590. op = random.choice(char_dict[op])
  1591. if len(op) > 1:
  1592. op = [x for x in op]
  1593. else:
  1594. op = [op]
  1595. char_list.extend(n1)
  1596. char_list.extend(op)
  1597. char_list.extend(n2)
  1598. if random.choice([0, 0, 0, 1]):
  1599. char_list.append('=')
  1600. char_list.append(random.choice([''] + char_dict['?']))
  1601. else:
  1602. # 随机生成非算式
  1603. char_list = random.sample(list(char_dict.keys())+list(only_op_dict.keys())*2, random.randint(3, 6))
  1604. char_list = [random.choice(char_dict[x]) for x in char_list]
  1605. new_char_list = []
  1606. for c in char_list:
  1607. if len(c) > 1:
  1608. new_char_list.extend([x for x in c])
  1609. else:
  1610. new_char_list.append(c)
  1611. char_list = new_char_list
  1612. char_list = char_list[:8]
  1613. if random.choice([0, 1]):
  1614. fig_size = random.choice([(70, 25), (100, 26), (100, 40)])
  1615. line = (0, 0)
  1616. wavy = (0, 0)
  1617. font_size = random.choice([(18, 25), (35, 40)])
  1618. # offset_w = (-20, 6)
  1619. else:
  1620. # 定制
  1621. fig_size = (90, 34)
  1622. line = (0, 0)
  1623. wavy = (0, 0)
  1624. font_size = (38, 50)
  1625. offset_w = (-8, -2)
  1626. bg = generate_data_equation_lsm("".join(char_list),
  1627. fig_size=fig_size,
  1628. font_color=random.choice([(20, 230, 20, 230, 20, 230),
  1629. (70, 100),
  1630. (10, 230, 10, 230, 10, 230),
  1631. ]),
  1632. font_size=font_size,
  1633. rotate=random.choice([0, ]),
  1634. shortline=(0, 0),
  1635. line=line,
  1636. line_width=(0, 0),
  1637. wavy=wavy,
  1638. offset_w=offset_w,
  1639. offset_h=5,
  1640. same_color=0,
  1641. )
  1642. bg = pil2np(bg)
  1643. # print(1)
  1644. noise = create_noise_point(bg, random.randint(15, 50))
  1645. # print(2)
  1646. noise = create_noise_short_lines(noise, random.randint(1, 5))
  1647. # 数据增强
  1648. if random.choice([0, 1]):
  1649. bg = np2pil(bg)
  1650. noise = np2pil(noise)
  1651. aug = random.choice([0, 1, 2, 3])
  1652. if aug == 0:
  1653. r = random.uniform(.5, 6.)
  1654. bg = image_enhance_color(bg, _range=(r, r))
  1655. noise = image_enhance_color(noise, _range=(r, r))
  1656. elif aug == 1:
  1657. r = random.uniform(.3, 2.)
  1658. bg = image_enhance_brightness(bg, (r, r))
  1659. noise = image_enhance_brightness(noise, (r, r))
  1660. elif aug == 2:
  1661. r = random.uniform(.3, 6.)
  1662. bg = image_enhance_contrast(bg, (r, r))
  1663. noise = image_enhance_contrast(noise, (r, r))
  1664. elif aug == 3:
  1665. r = random.uniform(4., 8.)
  1666. bg = image_enhance_sharpness(bg, (r, r))
  1667. noise = image_enhance_sharpness(noise, (r, r))
  1668. elif aug == 4:
  1669. bg = image_enhance_blur(bg)
  1670. noise = image_enhance_blur(noise)
  1671. bg = pil2np(bg)
  1672. noise = pil2np(noise)
  1673. if aug == 5:
  1674. bg = image_enhance_distort(bg)
  1675. # print("aug", aug)
  1676. # show
  1677. # cv2.imshow("bg", bg)
  1678. # cv2.imshow("noise", noise)
  1679. # cv2.waitKey(0)
  1680. result_list.append([bg, noise])
  1681. return result_list
  1682. def char_on_image(image_np, char_list, char_shape, image_shape, tip_char_num=1, only_color=None, char_stretch=False):
  1683. position_list = []
  1684. for char in char_list:
  1685. # 获取单字图片
  1686. char_image_pil = get_char_image2(char, char_shape, char_color=only_color)
  1687. image_np = pil_resize(image_np, image_shape[0], image_shape[1])
  1688. # h, w
  1689. fg_w, fg_h = char_image_pil.size[:2]
  1690. bg_h, bg_w = image_np.shape[:2]
  1691. # 字体放置的位置,且位置不重叠
  1692. find_flag = 0
  1693. while not find_flag:
  1694. position_h = random.randint(0, bg_h-fg_h)
  1695. position_w = random.randint(0, bg_w-fg_w)
  1696. if len(position_list) < 1:
  1697. find_flag = 1
  1698. break
  1699. for p in position_list:
  1700. if get_iou(position_w, position_h, position_w+fg_w, position_h+fg_h,
  1701. p[1], p[0], p[1]+fg_w, p[0]+fg_h) > 0:
  1702. find_flag = 0
  1703. break
  1704. else:
  1705. find_flag = 1
  1706. position_list.append([position_h, position_w])
  1707. # 字体添加到背景图上
  1708. # image_np = get_image_roi(image_np, char_image_np, position_h, position_w)
  1709. image_np = get_image_paste(image_np, char_image_pil, position_h, position_w, stretch=char_stretch)
  1710. # 生成提示图片
  1711. image_list = []
  1712. for char in char_list[:tip_char_num]:
  1713. char_image_pil = get_char_image2(char, char_shape, rotate=True, is_tips=True)
  1714. char_image_np = pil2np_a(char_image_pil)
  1715. # char_image_np = pil_resize(char_image_np, char_shape[0], char_shape[1])
  1716. image_list.append(char_image_np)
  1717. if image_list:
  1718. tips_image_np = np.concatenate(image_list, axis=1)
  1719. # 加干扰
  1720. tips_image_np = create_noise(tips_image_np)
  1721. # 切割
  1722. image_list = []
  1723. for i in range(tip_char_num):
  1724. image_list.append(tips_image_np[:, i*char_shape[1]:(i+1)*char_shape[1], :])
  1725. return image_np, position_list, image_list
  1726. def get_char_image(char, char_shape, rotate=True, bg_color=(0, 0, 0, 0)):
  1727. # 创建空图
  1728. image_pil = Image.new('RGBA', (80, 80), bg_color)
  1729. # 空图上写字
  1730. # font_size = 35 # (40, 40)
  1731. font_size = 75 # (80, 80)
  1732. font_type_list = glob("../font/*")
  1733. font_type = random.sample(font_type_list, 1)[0]
  1734. font_config = ImageFont.truetype(font_type, int(font_size))
  1735. dr = ImageDraw.Draw(image_pil)
  1736. fill_color = random_color()
  1737. fill_color = (fill_color[0], fill_color[1], fill_color[2])
  1738. dr.text((3, -6), char, font=font_config, fill=fill_color)
  1739. if rotate:
  1740. if random.choice([0, 1]):
  1741. angle = random.randint(0, 80)
  1742. else:
  1743. angle = random.randint(280, 360)
  1744. image_pil = image_pil.rotate(angle, expand=False, fillcolor=bg_color)
  1745. # image_pil.show("1")
  1746. image_pil = image_pil.resize(char_shape)
  1747. # cv2.imshow("get_char_image", pil2np(image_pil))
  1748. # cv2.waitKey(0)
  1749. return image_pil
  1750. def get_char_image2(char, char_shape, rotate=True, char_color=None, is_tips=False):
  1751. # plt.ion()
  1752. # plt.ioff()
  1753. font_files = ['simhei', 'simsun', "Microsoft YaHei"]
  1754. # 修改matplotlib中font_manager.py中defaultFamily
  1755. plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]
  1756. font_colors = [
  1757. 'aqua',
  1758. 'aquamarine',
  1759. 'bisque',
  1760. 'black',
  1761. 'blue',
  1762. 'blueviolet',
  1763. 'brown',
  1764. 'burlywood',
  1765. 'cadetblue',
  1766. 'chartreuse',
  1767. 'chocolate',
  1768. 'coral',
  1769. 'cornflowerblue',
  1770. 'cornsilk',
  1771. 'crimson',
  1772. 'cyan',
  1773. 'darkblue',
  1774. 'darkcyan',
  1775. 'darkgoldenrod',
  1776. 'darkgray',
  1777. 'darkgreen',
  1778. 'darkmagenta',
  1779. 'darkolivegreen',
  1780. 'darkorange',
  1781. 'darkorchid',
  1782. 'darkred',
  1783. 'darksalmon',
  1784. 'darkseagreen',
  1785. 'darkslategray',
  1786. 'darkturquoise',
  1787. 'darkviolet',
  1788. 'deeppink',
  1789. 'deepskyblue',
  1790. 'dimgray',
  1791. 'dodgerblue',
  1792. 'firebrick',
  1793. 'forestgreen',
  1794. 'fuchsia',
  1795. 'gold',
  1796. 'goldenrod',
  1797. 'gray',
  1798. 'green',
  1799. 'greenyellow',
  1800. 'hotpink',
  1801. 'indianred',
  1802. 'indigo',
  1803. 'lawngreen',
  1804. 'lightseagreen',
  1805. 'lightskyblue',
  1806. 'lightslategray',
  1807. 'lightsteelblue',
  1808. 'lime',
  1809. 'limegreen',
  1810. 'magenta',
  1811. 'maroon',
  1812. 'mediumaquamarine',
  1813. 'mediumblue',
  1814. 'mediumorchid',
  1815. 'mediumpurple',
  1816. 'mediumseagreen',
  1817. 'mediumslateblue',
  1818. 'mediumspringgreen',
  1819. 'mediumturquoise',
  1820. 'mediumvioletred',
  1821. 'midnightblue',
  1822. 'navy',
  1823. 'olive',
  1824. 'olivedrab',
  1825. 'orange',
  1826. 'orangered',
  1827. 'orchid',
  1828. 'palegoldenrod',
  1829. 'palegreen',
  1830. 'paleturquoise',
  1831. 'palevioletred',
  1832. 'peachpuff',
  1833. 'peru',
  1834. 'pink',
  1835. 'plum',
  1836. 'purple',
  1837. 'red',
  1838. 'rosybrown',
  1839. 'royalblue',
  1840. 'saddlebrown',
  1841. 'salmon',
  1842. 'sandybrown',
  1843. 'seagreen',
  1844. 'sienna',
  1845. 'silver',
  1846. 'skyblue',
  1847. 'slateblue',
  1848. 'slategray',
  1849. 'springgreen',
  1850. 'steelblue',
  1851. 'tan',
  1852. 'teal',
  1853. 'tomato',
  1854. 'turquoise',
  1855. 'violet',
  1856. 'yellow',
  1857. 'yellowgreen'
  1858. ]
  1859. line_width = random.choice([random.randint(1, 6), 0, 0])
  1860. # print("char_color", char_color)
  1861. if char_color == (0, 0, 0):
  1862. font_color = 'black'
  1863. line_color = 'black'
  1864. font_weight = random.randint(1, 300)
  1865. else:
  1866. if random.choice([1, 1, 1]) or is_tips:
  1867. font_weight = random.randint(200, 500)
  1868. font_color = random.sample(font_colors, 1)[0]
  1869. line_color = random.sample(font_colors, 1)[0]
  1870. else:
  1871. font_color = 'black'
  1872. line_color = 'black'
  1873. font_weight = random.randint(40, 100)
  1874. if rotate:
  1875. rotation = random.choice([random.randint(0, 70), random.randint(290, 360), 0])
  1876. else:
  1877. rotation = 0
  1878. # print("font_color", font_color, char)
  1879. # 写字
  1880. plt.rcParams['font.weight'] = font_weight
  1881. text = fig.text(0.5, 0.5, char, ha="center", va="center", size=55, color=font_color, rotation=rotation)
  1882. # 字体有边框
  1883. text.set_path_effects([path_effects.Stroke(linewidth=line_width, foreground=line_color), path_effects.Normal()])
  1884. # 更新图
  1885. # plt
  1886. plt.pause(0.0000001)
  1887. # fig = plt.gcf()
  1888. # plt.plot()
  1889. # plt.show()
  1890. # plt.legend()
  1891. # 申请缓存
  1892. _buffer = io.BytesIO()
  1893. fig.savefig(_buffer, format='png')
  1894. _buffer.seek(0)
  1895. image_pil = Image.open(_buffer)
  1896. plt.cla()
  1897. plt.clf()
  1898. # plt.close('all')
  1899. gc.collect()
  1900. # 大小限制
  1901. image_pil = image_pil.crop((105, 0, image_pil.size[0]-105, image_pil.size[1]-12))
  1902. image_pil = image_pil.resize(char_shape)
  1903. # image_pil.show()
  1904. return image_pil
  1905. def get_tips_image(tips_image_list, char_shape, image_shape):
  1906. new_list = []
  1907. for img in tips_image_list:
  1908. # if random.choice([0, 0, 1]):
  1909. # angle = random.choice([random.randint(0, 70), random.randint(290, 360)])
  1910. # img = pil_rotate(img, angle, (255, 255, 255))
  1911. new_list.append(img)
  1912. tips_image_np = np.concatenate(new_list, axis=1)
  1913. new_image = np.full((image_shape[0], image_shape[1], 3), 0, np.uint8)
  1914. new_image[:tips_image_np.shape[0], :tips_image_np.shape[1], :] = tips_image_np
  1915. position_list = []
  1916. for i in range(len(new_list)):
  1917. h = 0
  1918. w = i*char_shape[1]
  1919. position_list.append([h, w])
  1920. if random.choice([0, 1]):
  1921. new_image[np.all(new_image==0, axis=2)] = 255
  1922. return new_image, position_list
  1923. def get_image_roi(image_bg, image_fg, roi_h, roi_w):
  1924. # h, w
  1925. fg_h, fg_w = image_fg.shape[:2]
  1926. bg_h, bg_w = image_bg.shape[:2]
  1927. # roi取值范围
  1928. roi = image_bg[roi_h:roi_h+fg_h, roi_w:roi_w+fg_w]
  1929. # 获取bg中非fg字体部分的掩码,相当于排除fg的字体部分,只保留bg的除fg字体外的部分
  1930. img_fg_gray = cv2.cvtColor(image_fg, cv2.COLOR_BGR2GRAY)
  1931. ret, mask = cv2.threshold(img_fg_gray, 0, 255, cv2.THRESH_OTSU)
  1932. bg_roi = cv2.bitwise_and(roi, roi, mask=mask)
  1933. # 获取fg中字体部分的掩码,相当于排除fg中的白色背景,只保留fg的字体部分
  1934. mask_inv = cv2.bitwise_not(mask)
  1935. fg_roi = cv2.bitwise_and(image_fg, image_fg, mask=mask_inv)
  1936. # 膨胀腐蚀去掉白色颗粒
  1937. # kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
  1938. # fg_roi = cv2.erode(fg_roi, kernel)
  1939. # fg_roi = cv2.dilate(fg_roi, kernel)
  1940. # bg的除字体外背景部分 + fg的字体部分
  1941. image_roi = cv2.add(bg_roi, fg_roi)
  1942. # 将roi部分放回原bg
  1943. image_bg[roi_h:roi_h+fg_h, roi_w:roi_w+fg_w, :] = image_roi
  1944. # cv2.imshow("image_fg", image_fg)
  1945. # cv2.imshow("get_image_roi", image_bg)
  1946. # cv2.waitKey(0)
  1947. return image_bg
  1948. def get_image_paste(image_bg, image_fg, roi_h, roi_w, stretch=False):
  1949. fg_h, fg_w = image_fg.size[:2]
  1950. if stretch:
  1951. if random.choice([1, 1, 1]):
  1952. threshold = random.randint(7, 13)
  1953. # print(threshold)
  1954. if random.choice([0, 1]):
  1955. image_fg = image_fg.resize((fg_w, fg_h-threshold), Image.BICUBIC)
  1956. else:
  1957. image_fg = image_fg.resize((fg_w-threshold, fg_h), Image.BICUBIC)
  1958. image_bg = cv2.cvtColor(image_bg, cv2.COLOR_BGR2BGRA)
  1959. image_bg = np2pil_a(image_bg)
  1960. # image_fg = np2pil_a(image_fg)
  1961. image_bg.paste(image_fg, (roi_w, roi_h), image_fg)
  1962. image_bg = pil2np(image_bg)
  1963. # cv2.imshow("get_image_paste", image_bg)
  1964. # cv2.waitKey(0)
  1965. return image_bg
  1966. def random_color(dims=3):
  1967. color = [0]*dims
  1968. find_flag = 0
  1969. while not find_flag:
  1970. for dim in range(dims):
  1971. color[dim] = random.randint(0, 255)
  1972. if color[dim] <= 125:
  1973. find_flag = 1
  1974. # RGB
  1975. # color_list = [
  1976. # [207, 91, 85],
  1977. # [0, 201, 88],
  1978. # [117, 74, 57],
  1979. # [210, 210, 27],
  1980. # [160, 157, 152],
  1981. # [181, 210, 210],
  1982. # [27, 112, 107],
  1983. # [87, 26, 44],
  1984. # [115, 19, 20],
  1985. # [161, 210, 68],
  1986. # [210, 108, 12],
  1987. # [112, 9, 142],
  1988. # [50, 41, 84],
  1989. # [72, 52, 210],
  1990. # [210, 177, 89],
  1991. # [148, 200, 89],
  1992. # [173, 116, 109],
  1993. # [185, 185, 210],
  1994. # [181, 7, 210],
  1995. # [80, 210, 30],
  1996. # [65, 72, 98],
  1997. # [210, 123, 109],
  1998. # [19, 64, 95],
  1999. # [128, 21, 210],
  2000. # [129, 137, 60]
  2001. # ]
  2002. # color = random.sample(color_list, 1)[0]
  2003. return tuple(color)
  2004. def create_noise(image_np):
  2005. ic = ImageCaptcha()
  2006. image_pil = np2pil(image_np)
  2007. if random.choice([0, 1]):
  2008. draw = ImageDraw.Draw(image_pil)
  2009. for i in range(0, random.randint(100, 1000)):
  2010. xy = (random.randrange(0, image_pil.size[0]), random.randrange(0, image_pil.size[1]))
  2011. r = random.randint(0, 200)
  2012. fill = (r, r, r)
  2013. draw.point(xy, fill=fill)
  2014. del draw
  2015. for i in range(random.randint(2, 4)):
  2016. image_pil = ic.create_noise_curve(image_pil, random_color())
  2017. image_pil = ic.create_noise_dots(image_pil, random_color(), random.randint(3, 6), random.randint(30, 60))
  2018. image_np = pil2np(image_pil)
  2019. return image_np
  2020. def create_noise_short_lines(image_np, line_num):
  2021. image_np = copy.deepcopy(image_np)
  2022. h, w = image_np.shape[:2]
  2023. len_range = (5, int(w/2))
  2024. for i in range(line_num):
  2025. p1 = (random.randint(0, w), random.randint(0, h))
  2026. find_flag = False
  2027. while not find_flag:
  2028. p2 = (random.randint(0, w), random.randint(0, h))
  2029. p_len = math.sqrt(math.pow((p1[0]-p2[0]), 2) + math.pow((p1[1]-p2[1]), 2))
  2030. if p_len < len_range[0] or p_len > len_range[1]:
  2031. find_flag = True
  2032. color = (random.randint(50, 200), random.randint(50, 200), random.randint(50, 200))
  2033. thickness = random.randint(1, 1)
  2034. cv2.line(image_np, p1, p2, color, thickness=thickness)
  2035. return image_np
  2036. def create_noise_point(image_np, point_num):
  2037. image_np = copy.deepcopy(image_np)
  2038. h, w = image_np.shape[:2]
  2039. for i in range(point_num):
  2040. p_center = (random.randint(1, w-2), random.randint(1, h-2))
  2041. p_list = [(p_center[0]-1, p_center[1]),
  2042. (p_center[0]+1, p_center[1]),
  2043. p_center,
  2044. (p_center[0], p_center[1]-1),
  2045. (p_center[0], p_center[1]+1)]
  2046. p_color = [random.randint(0, 130), random.randint(0, 130), random.randint(0, 130)]
  2047. for p in p_list:
  2048. if random.choice([0, 1]):
  2049. if random.choice([0, 1]):
  2050. _index = p_color.index(max(p_color))
  2051. p_color[_index] = random.randint(200, 255)
  2052. image_np[p[1], p[0], 0] = p_color[0]
  2053. image_np[p[1], p[0], 1] = p_color[1]
  2054. image_np[p[1], p[0], 2] = p_color[2]
  2055. return image_np
  2056. def get_iou(x1, y1, x2, y2, a1, b1, a2, b2):
  2057. # 相交区域左上角横坐标
  2058. ax = max(x1, a1)
  2059. # 相交区域左上角纵坐标
  2060. ay = max(y1, b1)
  2061. # 相交区域右下角横坐标
  2062. bx = min(x2, a2)
  2063. # 相交区域右下角纵坐标
  2064. by = min(y2, b2)
  2065. area_n = (x2 - x1) * (y2 - y1)
  2066. area_m = (a2 - a1) * (b2 - b1)
  2067. w = max(0, bx - ax)
  2068. h = max(0, by - ay)
  2069. area_x = w * h
  2070. return area_x / (area_n + area_m - area_x)
  2071. def preprocess_true_boxes(true_boxes, input_shape, anchors, num_classes):
  2072. """Preprocess true boxes to training input format
  2073. Parameters
  2074. ----------
  2075. true_boxes: array, shape=(m, T, 5)
  2076. Absolute x_min, y_min, x_max, y_max, class_id relative to input_shape.
  2077. input_shape: array-like, hw, multiples of 32
  2078. anchors: array, shape=(N, 2), wh
  2079. num_classes: integer
  2080. Returns
  2081. -------
  2082. y_true: list of array, shape like yolo_outputs, xywh are reletive value
  2083. """
  2084. # print(true_boxes.shape)
  2085. # print(true_boxes[..., 4])
  2086. # print(num_classes)
  2087. try:
  2088. sss = (true_boxes[..., 4] < num_classes).all()
  2089. except:
  2090. print(true_boxes[..., 4])
  2091. assert (true_boxes[..., 4] < num_classes).all(), 'class id must be less than num_classes'
  2092. # default setting
  2093. num_layers = len(anchors)//3
  2094. anchor_mask = [[6, 7, 8], [3, 4, 5], [0, 1, 2]] if num_layers == 3 else [[3, 4, 5], [1, 2, 3]]
  2095. true_boxes = np.array(true_boxes, dtype='float32')
  2096. input_shape = np.array(input_shape, dtype='int32')
  2097. boxes_xy = (true_boxes[..., 0:2] + true_boxes[..., 2:4]) // 2
  2098. boxes_wh = true_boxes[..., 2:4] - true_boxes[..., 0:2]
  2099. true_boxes[..., 0:2] = boxes_xy/input_shape[::-1]
  2100. true_boxes[..., 2:4] = boxes_wh/input_shape[::-1]
  2101. m = true_boxes.shape[0]
  2102. grid_shapes = [input_shape//{0: 32, 1: 16, 2: 8}[l] for l in range(num_layers)]
  2103. y_true = [np.zeros((m, grid_shapes[l][0], grid_shapes[l][1],len(anchor_mask[l]), 5+num_classes),
  2104. dtype='float32') for l in range(num_layers)]
  2105. # Expand dim to apply broadcasting.
  2106. anchors = np.expand_dims(anchors, 0)
  2107. anchor_maxes = anchors / 2.
  2108. anchor_mins = -anchor_maxes
  2109. valid_mask = boxes_wh[..., 0] > 0
  2110. for b in range(m):
  2111. # Discard zero rows.
  2112. wh = boxes_wh[b, valid_mask[b]]
  2113. if len(wh) == 0:
  2114. continue
  2115. # Expand dim to apply broadcasting.
  2116. wh = np.expand_dims(wh, -2)
  2117. box_maxes = wh / 2.
  2118. box_mins = -box_maxes
  2119. intersect_mins = np.maximum(box_mins, anchor_mins)
  2120. intersect_maxes = np.minimum(box_maxes, anchor_maxes)
  2121. intersect_wh = np.maximum(intersect_maxes - intersect_mins, 0.)
  2122. intersect_area = intersect_wh[..., 0] * intersect_wh[..., 1]
  2123. box_area = wh[..., 0] * wh[..., 1]
  2124. anchor_area = anchors[..., 0] * anchors[..., 1]
  2125. iou = intersect_area / (box_area + anchor_area - intersect_area)
  2126. # Find best anchor for each true box
  2127. best_anchor = np.argmax(iou, axis=-1)
  2128. for t, n in enumerate(best_anchor):
  2129. for l in range(num_layers):
  2130. if n in anchor_mask[l]:
  2131. i = np.floor(true_boxes[b,t,0]*grid_shapes[l][1]).astype('int32')
  2132. j = np.floor(true_boxes[b,t,1]*grid_shapes[l][0]).astype('int32')
  2133. k = anchor_mask[l].index(n)
  2134. c = true_boxes[b, t, 4].astype('int32')
  2135. y_true[l][b, j, i, k, 0:4] = true_boxes[b, t, 0:4]
  2136. y_true[l][b, j, i, k, 4] = 1
  2137. y_true[l][b, j, i, k, 5+c] = 1
  2138. return y_true
  2139. def get_puzzle(shape=(80, 80)):
  2140. # 创建空图
  2141. image_pil = Image.new('RGBA', (shape[1], shape[0]), (255, 255, 255, 0))
  2142. draw = ImageDraw.Draw(image_pil)
  2143. # 居中创建矩形
  2144. rec_shape = (40, 40)
  2145. left_up_point = [int((shape[0]-rec_shape[0])/2), int((shape[1]-rec_shape[1])/2)]
  2146. right_down_point = [left_up_point[0]+rec_shape[0], left_up_point[1]+rec_shape[1]]
  2147. # 透明度
  2148. flag = random.choice([0, 1])
  2149. if flag:
  2150. alpha = random.randint(100, 150)
  2151. else:
  2152. alpha = random.randint(160, 255)
  2153. # 背景色
  2154. if flag:
  2155. r = random.randint(0, 30)
  2156. else:
  2157. r = random.randint(100, 180)
  2158. # r = random.randint(0, 255)
  2159. fill_color = (r, r, r, alpha)
  2160. # 边缘色
  2161. if random.choice([0, 1, 1]):
  2162. if flag:
  2163. r = random.randint(140, 170)
  2164. else:
  2165. r = random.randint(70, 100)
  2166. outline_color = (r, r, r)
  2167. else:
  2168. outline_color = (fill_color[0], fill_color[1], fill_color[2])
  2169. draw.rectangle((left_up_point[1],
  2170. left_up_point[0],
  2171. left_up_point[1]+rec_shape[1],
  2172. left_up_point[0]+rec_shape[0]),
  2173. fill=fill_color,
  2174. outline=outline_color)
  2175. # 拼图的圆或半圆
  2176. radius = random.randint(int(rec_shape[0] / 3 / 2), int(rec_shape[0] / 3 / 1.2))
  2177. center_list = [[left_up_point[1], int((right_down_point[0]+left_up_point[0])/2), 1],
  2178. [right_down_point[1], int((right_down_point[0]+left_up_point[0])/2), 1],
  2179. [int((right_down_point[1]+left_up_point[1])/2), left_up_point[0], 0],
  2180. [int((right_down_point[1]+left_up_point[1])/2), right_down_point[0], 0]
  2181. ]
  2182. circle_num = random.randint(1, 4)
  2183. # print("circle_num", circle_num)
  2184. center_list = random.sample(center_list, circle_num)
  2185. min_w, min_h = left_up_point[1], left_up_point[0]
  2186. max_w, max_h = right_down_point[1], right_down_point[0]
  2187. for center in center_list:
  2188. w, h = center[:2]
  2189. is_width = center[2]
  2190. # 判断长宽
  2191. into_ratio = random.randint(int(1/2*radius), int(3/4*radius))
  2192. if is_width:
  2193. # 挑选圆是凸还是凹进去
  2194. if random.choice([0, 1]):
  2195. center = (center[0]+into_ratio, center[1])
  2196. else:
  2197. center = (center[0]-into_ratio, center[1])
  2198. else:
  2199. if random.choice([0, 1]):
  2200. center = (center[0], center[1]+into_ratio)
  2201. else:
  2202. center = (center[0], center[1]-into_ratio)
  2203. # 判断透明度
  2204. color = fill_color
  2205. if is_width:
  2206. if left_up_point[1] <= center[0] <= right_down_point[1]:
  2207. color = (0, 0, 0, 0)
  2208. else:
  2209. if left_up_point[0] <= center[1] <= right_down_point[0]:
  2210. color = (0, 0, 0, 0)
  2211. # print("center, color, alpha", center, color, alpha)
  2212. draw.ellipse([(center[0]-radius, center[1]-radius),
  2213. (center[0]+radius, center[1]+radius)],
  2214. fill=color,
  2215. outline=outline_color)
  2216. # 修补内部圆的边缘颜色
  2217. if color[3] == alpha:
  2218. if is_width:
  2219. if center[0] < w:
  2220. draw.rectangle((w,
  2221. h-radius,
  2222. center[0]+radius,
  2223. center[1]+radius),
  2224. fill=fill_color)
  2225. else:
  2226. draw.rectangle((center[0]-radius,
  2227. center[1]-radius,
  2228. w,
  2229. h+radius),
  2230. fill=fill_color)
  2231. else:
  2232. if center[1] < h:
  2233. draw.rectangle((w-radius,
  2234. h,
  2235. center[0]+radius,
  2236. center[1]+radius),
  2237. fill=fill_color)
  2238. else:
  2239. draw.rectangle((center[0]-radius,
  2240. center[1]-radius,
  2241. w+radius,
  2242. h),
  2243. fill=fill_color)
  2244. # 修补外部圆的边缘颜色
  2245. else:
  2246. if is_width:
  2247. if center[0] > w:
  2248. draw.rectangle((center[0]-radius,
  2249. center[1]-radius,
  2250. w,
  2251. h+radius),
  2252. fill=(0, 0, 0, 0))
  2253. else:
  2254. draw.rectangle((w,
  2255. h-radius,
  2256. center[0]+radius,
  2257. center[1]+radius),
  2258. fill=(0, 0, 0, 0))
  2259. else:
  2260. if center[1] > h:
  2261. draw.rectangle((center[0]-radius,
  2262. center[1]-radius,
  2263. w+radius,
  2264. h),
  2265. fill=(0, 0, 0, 0))
  2266. else:
  2267. draw.rectangle((w-radius,
  2268. h,
  2269. center[0]+radius,
  2270. center[1]+radius),
  2271. fill=(0, 0, 0, 0))
  2272. # 新增面积
  2273. if color[3] == alpha:
  2274. if center[0]-radius <= min_w:
  2275. min_w = center[0]-radius
  2276. if center[0]+radius >= max_w:
  2277. max_w = center[0]+radius
  2278. if center[1]-radius <= min_h:
  2279. min_h = center[1]-radius
  2280. if center[1]+radius >= max_h:
  2281. max_h = center[1]+radius
  2282. image_pil = image_pil.crop([min_w, min_h, max_w+1, max_h+1])
  2283. # image_pil.show("2")
  2284. return image_pil
  2285. def puzzle_on_image(image_np, puzzle_shape, image_shape):
  2286. position_list = []
  2287. # 获取拼图图片
  2288. puzzle_image_pil = get_puzzle()
  2289. puzzle_image_pil = puzzle_image_pil.resize(puzzle_shape)
  2290. image_np = pil_resize(image_np, image_shape[0], image_shape[1])
  2291. # h, w
  2292. fg_w, fg_h = puzzle_image_pil.size[:2]
  2293. bg_h, bg_w = image_np.shape[:2]
  2294. # 拼图放置的位置
  2295. position_h = random.randint(0, bg_h-fg_h)
  2296. position_w = random.randint(0, bg_w-fg_w)
  2297. position_list.append([position_h, position_w])
  2298. # for p in position_list:
  2299. # cv2.rectangle(image_np, (p[1], p[0]),
  2300. # (p[1]+puzzle_shape[1], p[0]+puzzle_shape[0]),
  2301. # (0, 0, 255), 1)
  2302. # 拼图添加到背景图上
  2303. image_np = get_image_paste(image_np, puzzle_image_pil, position_h, position_w)
  2304. # cv2.imshow("puzzle_on_image", image_np)
  2305. # cv2.waitKey(0)
  2306. return image_np, position_list
  2307. def get_drag_image(image_np):
  2308. h, w = image_np.shape[:2]
  2309. # 取一定高度图片
  2310. clip_h = random.randint(int(1/4*h), int(3/4*h))
  2311. image_clip = image_np[:clip_h, ...]
  2312. # 将图片在一定宽度截断,重新拼接
  2313. clip_w = random.randint(int(1/6*w), int(5/6*w))
  2314. image_w1 = image_clip[:, :clip_w, ...]
  2315. image_w2 = image_clip[:, clip_w:, ...]
  2316. image_new = np.concatenate([image_w2, image_w1], axis=1)
  2317. # 分割线
  2318. clip_line = [(image_w2.shape[1], 0), (image_w2.shape[1], clip_h)]
  2319. # show
  2320. # print(clip_line)
  2321. # cv2.line(image_new, clip_line[0], clip_line[1], (0, 0, 255), 2)
  2322. # cv2.imshow("get_drag_image", image_new)
  2323. # cv2.waitKey(0)
  2324. return image_new, clip_line
  2325. def get_real_data_puzzle(shape=(160, 256)):
  2326. paths = glob("../data/detect2_real/*")
  2327. i = 10000
  2328. for p in paths:
  2329. image = cv2.imread(p)
  2330. image = pil_resize(image, shape[0], shape[1])
  2331. cv2.imwrite("../data/detect2_real/"+str(i)+".jpg", image)
  2332. i += 1
  2333. image = image_enhance_distort(image)
  2334. cv2.imwrite("../data/detect2_real/"+str(i)+".jpg", image)
  2335. i += 1
  2336. image = image_enhance_flip(image)
  2337. cv2.imwrite("../data/detect2_real/"+str(i)+".jpg", image)
  2338. i += 1
  2339. def read_label_puzzle():
  2340. paths = glob("../data/detect2_real/*.json")
  2341. map_path = "../data/detect2_real/map.txt"
  2342. with open(map_path, "a") as f:
  2343. for p in paths:
  2344. with open(p, "r") as fp:
  2345. _dict = json.loads(fp.read())
  2346. points = _dict.get("shapes")[0].get("points")
  2347. image_path = _dict.get("imagePath")
  2348. ps = [str(int(points[0][0])), str(int(points[0][1])),
  2349. str(int(points[1][0])), str(int(points[1][1]))]
  2350. p_str = ",".join(ps)
  2351. f.write(image_path + " " + p_str + ",0" + "\n")
  2352. def fix_map_txt():
  2353. path = "../data/map.txt"
  2354. with open(path, "r") as f:
  2355. _list = f.readlines()
  2356. with open("../data/map_new.txt", "w") as f:
  2357. new_list = []
  2358. for line in _list:
  2359. ss = line.split(" ")
  2360. ps = ss[-1][:-1].split(",")[:-1]
  2361. if random.choice([0, 1, 1, 1]):
  2362. pix = random.choice([1, 2, 2, 3, 3, 4, 4])
  2363. for i in range(len(ps)):
  2364. if i < 2:
  2365. ps[i] = str(int(ps[i]) - pix)
  2366. else:
  2367. ps[i] = str(int(ps[i]) + pix)
  2368. new_line = ss[0] + " " + ",".join(ps) + ",0\n"
  2369. new_list.append(new_line)
  2370. print("line", line)
  2371. print("new_line", new_line)
  2372. f.writelines(new_list)
  2373. def get_char_map():
  2374. path = "../data/phrase/phrase3.txt"
  2375. with open(path, "r") as f:
  2376. _list = f.readlines()
  2377. path = "../data/phrase/phrase4.txt"
  2378. with open(path, "r") as f:
  2379. _list += f.readlines()
  2380. path = "../data/phrase/phrase5.txt"
  2381. with open(path, "r") as f:
  2382. _list += f.readlines()
  2383. _str = "".join(_list)
  2384. _str = re.sub("\n", "", _str)
  2385. _list = list(set([x+"\n" for x in _str]))
  2386. _list.sort(key=lambda x: x)
  2387. with open("../data/phrase/char.txt", "w") as f:
  2388. f.writelines(_list)
  2389. def resize_base_image():
  2390. paths = glob("../data/base/*")
  2391. for p in paths:
  2392. _img = cv2.imread(p)
  2393. h, w = _img.shape[:2]
  2394. if h > 600 and h > w:
  2395. best_h = 600
  2396. best_w = int(best_h * w / h)
  2397. _img = pil_resize(_img, best_h, best_w)
  2398. cv2.imwrite(p, _img)
  2399. elif w > 600 and w > h:
  2400. best_w = 600
  2401. best_h = int(best_w * h / w)
  2402. _img = pil_resize(_img, best_h, best_w)
  2403. cv2.imwrite(p, _img)
  2404. def image_enhance_distort(image_np, hue=.3, sat=3., val=3.):
  2405. """
  2406. 数据增强:色彩扰动
  2407. :return:
  2408. """
  2409. def rand(a=0, b=1):
  2410. return np.random.rand()*(b-a) + a
  2411. # cv2.imshow("distort_image1", image_np)
  2412. hue = rand(-hue, 0)
  2413. sat = rand(1, sat) if rand() < .2 else 1/rand(1, sat)
  2414. val = rand(1, val) if rand() < .2 else 1/rand(1, val)
  2415. # print(hue, sat, val)
  2416. image_np = cv2.cvtColor(image_np, cv2.COLOR_BGR2RGB)
  2417. x = rgb_to_hsv(image_np/255.)
  2418. x[..., 0] += hue
  2419. x[..., 0][x[..., 0] > 1] -= 1
  2420. x[..., 0][x[..., 0] < 0] += 1
  2421. x[..., 1] *= sat
  2422. x[..., 2] *= val
  2423. x[x > 1] = 1
  2424. x[x < 0] = 0
  2425. image_np = hsv_to_rgb(x)
  2426. image_np = cv2.cvtColor(np.uint8(image_np*255), cv2.COLOR_RGB2BGR)
  2427. # cv2.imshow("distort_image2", image_np)
  2428. # cv2.waitKey(0)
  2429. return image_np
  2430. def image_enhance_flip(image_np):
  2431. """
  2432. 数据增强:翻转
  2433. :param image_np:
  2434. :return:
  2435. """
  2436. # cv2.imshow("flip_image1", image_np)
  2437. if random.choice([0, 1]):
  2438. # 水平翻转
  2439. image_np = cv2.flip(image_np, 1)
  2440. else:
  2441. # 垂直翻转
  2442. image_np = cv2.flip(image_np, 0)
  2443. # cv2.imshow("flip_image2", image_np)
  2444. # cv2.waitKey(0)
  2445. return image_np
  2446. def image_enhance_blur(image_pil, blur_mode=2):
  2447. """
  2448. 数据增强:模糊
  2449. :param image_pil:
  2450. :param blur_mode: 1:标准模糊 2:高斯模糊 3:均值模糊
  2451. :return:
  2452. """
  2453. # image_pil.show()
  2454. if blur_mode == 1:
  2455. image_pil = image_pil.filter(ImageFilter.BLUR)
  2456. elif blur_mode == 2:
  2457. image_pil = image_pil.filter(ImageFilter.GaussianBlur(1))
  2458. elif blur_mode == 3:
  2459. image_pil = image_pil.filter(ImageFilter.BoxBlur(10))
  2460. # image_pil.show()
  2461. return image_pil
  2462. def image_enhance_color(image_pil, _range=(.5, 6.)):
  2463. """
  2464. 数据增强:色彩饱和度
  2465. :param image_pil:
  2466. :param _range:
  2467. :return:
  2468. """
  2469. # image_pil.show()
  2470. enh_col = ImageEnhance.Color(image_pil)
  2471. color = random.uniform(_range[0], _range[1])
  2472. # print("color", color)
  2473. image_colored = enh_col.enhance(color)
  2474. # image_colored.show()
  2475. return image_colored
  2476. def image_enhance_brightness(image_pil, _range=(.3, 2.)):
  2477. """
  2478. 数据增强:亮度
  2479. :param image_pil:
  2480. :param _range:
  2481. :return:
  2482. """
  2483. enh_bri = ImageEnhance.Brightness(image_pil)
  2484. brightness = random.uniform(_range[0], _range[1])
  2485. # print("brightness", brightness)
  2486. image_brightened = enh_bri.enhance(brightness)
  2487. return image_brightened
  2488. def image_enhance_contrast(image_pil, _range=(.3, 6.)):
  2489. """
  2490. 数据增强:对比度
  2491. :param image_pil:
  2492. :param _range:
  2493. :return:
  2494. """
  2495. # image_pil.show()
  2496. enh_con = ImageEnhance.Contrast(image_pil)
  2497. contrast = random.uniform(_range[0], _range[1])
  2498. # print("contrast", contrast)
  2499. image_contrasted = enh_con.enhance(contrast)
  2500. # image_contrasted.show()
  2501. return image_contrasted
  2502. def image_enhance_sharpness(image_pil, _range=(4., 8.)):
  2503. """
  2504. 数据增强:锐度
  2505. :param image_pil:
  2506. :param _range:
  2507. :return:
  2508. """
  2509. # image_pil.show()
  2510. enh_sha = ImageEnhance.Sharpness(image_pil)
  2511. sharpness = random.uniform(_range[0], _range[1])
  2512. # print("sharpness", sharpness)
  2513. image_sharped = enh_sha.enhance(sharpness)
  2514. # image_sharped.show()
  2515. return image_sharped
  2516. def image_enhance_wrap(image_pil, dx_factor=0.3, dy_factor=0.3):
  2517. """图像扭曲"""
  2518. width, height = image_pil.size
  2519. dx = width * dx_factor
  2520. dy = height * dy_factor
  2521. x1 = int(random.uniform(-dx, dx))
  2522. y1 = int(random.uniform(-dy, dy))
  2523. x2 = int(random.uniform(-dx, dx))
  2524. y2 = int(random.uniform(-dy, dy))
  2525. warp_image = Image.new('RGB', (width + abs(x1) + abs(x2), height + abs(y1) + abs(y2)))
  2526. warp_image.paste(image_pil, (abs(x1), abs(y1)))
  2527. width2, height2 = warp_image.size
  2528. warp_image = warp_image.transform((width, height),
  2529. Image.QUAD,
  2530. (x1, y1, -x1, height2 - y2, width2 + x2, height2 + y2, width2 - x2, -y1))
  2531. warp_image.show()
  2532. return warp_image
  2533. def eight_neighbour(image_np, k=4):
  2534. """
  2535. 8邻域降噪
  2536. :return:
  2537. """
  2538. def calculate_noise_count(img_obj, w, h):
  2539. """
  2540. 计算邻域非白色的个数
  2541. """
  2542. count = 0
  2543. width, height = img_obj.shape
  2544. for _w_ in [w - 1, w, w + 1]:
  2545. for _h_ in [h - 1, h, h + 1]:
  2546. if _w_ > width - 1:
  2547. continue
  2548. if _h_ > height - 1:
  2549. continue
  2550. if _w_ == w and _h_ == h:
  2551. continue
  2552. if img_obj[_w_, _h_] < 230: # 二值化的图片设置为255
  2553. count += 1
  2554. return count
  2555. w, h = image_np.shape
  2556. for _w in range(w):
  2557. for _h in range(h):
  2558. if _w == 0 or _h == 0:
  2559. image_np[_w, _h] = 255
  2560. continue
  2561. # 计算邻域pixel值小于255的个数
  2562. pixel = image_np[_w, _h]
  2563. if pixel == 255:
  2564. continue
  2565. if calculate_noise_count(image_np, _w, _h) < k:
  2566. image_np[_w, _h] = 255
  2567. return image_np
  2568. def connected_component(image_np):
  2569. # 黑白转化
  2570. image_np = 255 - image_np
  2571. # 二值化
  2572. ret, image_np = cv2.threshold(image_np, 60, 255, cv2.THRESH_BINARY)
  2573. # 膨胀
  2574. kernel = np.ones((2, 2), np.uint8)
  2575. image_np = cv2.dilate(image_np, kernel, iterations=1)
  2576. kernel = np.ones((2, 2), np.uint8)
  2577. image_np = cv2.erode(image_np, kernel, iterations=1)
  2578. return image_np
  2579. w, h = binary_img.shape
  2580. color = []
  2581. color.append((0, 0, 0))
  2582. img_color = np.zeros((w, h, 3), dtype=np.uint8)
  2583. retval, labels, stats, centroids = cv2.connectedComponentsWithStats(binary_img)
  2584. for num in range(1, retval):
  2585. color_b = random.randint(0, 255)
  2586. color_g = random.randint(0, 255)
  2587. color_r = random.randint(0, 255)
  2588. color.append((color_b, color_g, color_r))
  2589. for x in range(w):
  2590. for y in range(h):
  2591. lable = labels[x, y]
  2592. img_color[x, y, :] = color[int(lable)]
  2593. # cv2.imshow("img_color", img_color)
  2594. #
  2595. # cv2.waitKey(0)
  2596. return img_color
  2597. def add_contrast(image_np):
  2598. # cv2.imshow("image_np", image_np)
  2599. img = image_np.astype(np.float32)
  2600. bri_mean = np.mean(img)
  2601. # a = np.arange(5, 16, 5) / 10
  2602. # b = np.arange(-30, 31, 30)
  2603. #
  2604. # a_len = len(a)
  2605. # b_len = len(b)
  2606. # print(a_len, b_len)
  2607. #
  2608. # for i in range(a_len):
  2609. # for j in range(b_len):
  2610. # aa = a[i]
  2611. # bb = b[j]
  2612. # img_a = aa * (img-bri_mean) + bb + bri_mean
  2613. # print(i, j, aa, bb)
  2614. # img_a = np.clip(img_a, 0, 255).astype(np.uint8)
  2615. # cv2.imshow("img_a", img_a)
  2616. # cv2.waitKey(0)
  2617. aa = 3
  2618. bb = -50
  2619. img_a = aa * (img-bri_mean) + bb + bri_mean
  2620. img_a = np.clip(img_a, 0, 255).astype(np.uint8)
  2621. # cv2.imshow("img_a", img_a)
  2622. # cv2.waitKey(0)
  2623. return img_a
  2624. def get_image_legal(image_np):
  2625. white = np.sum(image_np > 80)
  2626. black = np.sum(image_np <= 80)
  2627. if black > white:
  2628. ratio = white / black
  2629. else:
  2630. ratio = black / white
  2631. return ratio
  2632. if __name__ == "__main__":
  2633. generate_data_char()
  2634. # for _p in glob("../data/test/FileInfo1021/*"):
  2635. # add_contrast(cv2.imread(_p))
  2636. # print(random.uniform(0.5, 0.5))
  2637. # paths = glob('../data/equation/*')
  2638. # for p in paths:
  2639. # img = cv2.imread(p)
  2640. # if img.shape[0] == 69 and img.shape[1] == 330:
  2641. # print(p)
  2642. # os.remove(p)
  2643. # image_enhance_wrap(Image.open("D:/Project/captcha/data/equation/30_4_-_零.jpg"))