-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreateCaptchas.py
110 lines (92 loc) · 3.07 KB
/
createCaptchas.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
## Ref: https://code-maven.com/create-images-with-python-pil-pillow
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import numpy as np
import os
import sys
# img size
im_w = 200
im_h = 100
# To force an character to appear and index of new character
force_chr = True
chgenidx = 0
## character quantity
qnt = 5
# fonts path
fontpath = './fonts'
# letters domain config
lower = (97, 122+1)
upper = (65,90+1)
nums = (48,57+1)
iterate = [lower, upper, nums]
domain = []
# domain letters for captcha
for i in iterate:
for j in range(i[0],i[1]):
domain.append(chr(j))
def gen_background():
arr = (np.random.rand(2,2,3) * 200) + 55
image = Image.fromarray(arr.astype('uint8')).convert('RGB')
image = image.resize((im_w,im_h))
image = image.filter(ImageFilter.GaussianBlur(1))
return image
def random_text(forced=None):
# randomize indexes of domain
ret = []
for i in range(0,qnt):
ret.append(domain[int(np.random.rand(1)*(len(domain)))])
# force to have an character (it's good to make sure that the our model will see all characters at least n times)
if forced:
ret[int(np.random.rand(1)*(len(ret)))] = domain[forced]
return ''.join(ret)
def drawText(draw, text, fnt_size=(35,50)):
size = (im_w/(qnt))-5
fontSize = int(np.random.rand(1)*(fnt_size[1]-fnt_size[0])) + fnt_size[0]
for idx, l in enumerate(text):
allfonts = os.listdir(fontpath)
fnt_name = fontpath + '/' + allfonts[int(np.random.rand(1)*len(allfonts))]
fnt = ImageFont.truetype(fnt_name,fontSize)
text_w, text_h = draw.textsize(l, font=fnt)
y = (np.random.rand(1)*(im_h-(fontSize)))
# check char height is in bound
if y - (text_h/2) < 0:
y = y + abs(y-(text_h))
if y + (text_h/2) > im_h:
y = y - ((y+text_h) - im_h)
x = (np.random.rand(1)*size) + (size*idx)
# check char width is in bound
if x - (text_w/2) < size*idx:
x = (size*idx) + (text_w/2)
if x + (text_w/2) > size*(idx+1):
x = (size*(idx+1)) - (text_w)
draw.text((x,y), l, font=fnt, fill=tuple((np.random.rand(3)*150).astype('uint8')))
def next_chr():
global chgenidx
chgenidx = (chgenidx + 1) % len(domain)
def gen_img():
back = gen_background()
draw = ImageDraw.Draw(back)
label = ""
if force_chr:
global chgenidx
label = random_text(chgenidx)
next_chr()
else:
label = random_text()
drawText(draw, label)
draw.line((np.random.rand(1)*im_w,0) + (np.random.rand(1)*im_w, im_h), fill=0, width=1)
#drawText(draw, '12345')
#draw.text((50,50),random_text(), fill=(255,255,0))
return (back, label)
def save_new(path='./generated/'):
img, label = gen_img()
img.save(path+label+'.png')
if len(sys.argv) > 1:
try:
int(sys.argv[1])
except:
print("the first argument should be an number")
sys.exit()
for i in range(int(sys.argv[1])):
save_new()
else:
print("You must pass an argument number with the quantity of samples to be created")