-
Notifications
You must be signed in to change notification settings - Fork 0
/
processImg.py
144 lines (124 loc) · 5.17 KB
/
processImg.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/python
"""
This script is used to preprocess captchas. Typically, it is called by other scripts.
Run it to convert download captchas to single characters (You need to run downloadCaptchas.py beforehand)
"""
from PIL import Image
import numpy
import os
import random
__author__ = 'smartjinyu'
def convertRawImg():
inputPath = './trainData/rawData'
outputPath_train = './trainData'
outputPath_validate = './valData'
if not os.path.exists(outputPath_train + '/processed'):
os.makedirs(outputPath_train + '/processed')
if not os.path.exists(outputPath_validate + '/processed'):
os.makedirs(outputPath_validate + '/processed')
for i in range(0, 10):
if not os.path.exists(outputPath_train + '/' + str(i)):
os.makedirs(outputPath_train + '/' + str(i))
if not os.path.exists(outputPath_validate + '/' + str(i)):
os.makedirs(outputPath_validate + '/' + str(i))
fileList = os.listdir(inputPath)
random.shuffle(fileList)
length = len(fileList)
j = 0
for filename in fileList:
# filename = '0008_b823fc04-81b0-11e7-b502-000c29187544.jpg'
rawImg = Image.open(inputPath + '/' + filename)
print('Processing ' + inputPath + '/' + filename)
imgs, processed = processImg(rawImg)
# processed.show()
# input("Input to continue...")
if j < round(length * 0.8):
outputPath = outputPath_train
else:
outputPath = outputPath_validate
outputFilename = outputPath + '/processed/' + filename
processed.save(outputFilename, 'JPEG')
names = filename.split('_')
for i in range(0, 4):
imgs[i].save(outputPath + '/' + names[0][i] + '/' + names[1], 'JPEG')
j = j + 1
return
def processImg(rawImg):
"""
process the raw image, eliminate the interfering line, separate into four images, with only one digit in eah
:param rawImg: the captcha to process
:return: list of four images,first four with only one digit in each image; and the full processed image
"""
BlackWhiteImage = rawImg.convert('1')
imArray = numpy.array(BlackWhiteImage)[:, 5:193] # discard the start and end columns
# print(imArray.shape)
# compute start and end points of two lines in first and last column
indexFirstColumn = []
indexLastColumn = []
i = 0
while i < imArray.shape[0]:
if imArray[i, 0] == 0:
indexFirstColumn.append(i + 1)
if len(indexFirstColumn) == 2:
break
else:
i = i + 5
i = i + 1
i = 0
while i < imArray.shape[0]:
if imArray[i, 187] == 0:
indexLastColumn.append(i + 1)
if len(indexLastColumn) == 2:
break
else:
i = i + 5
i = i + 1
# avoid two lines intersect at the start or the end
if len(indexFirstColumn) == 1:
indexFirstColumn.append(indexFirstColumn[0] + 2)
if len(indexLastColumn) == 1:
indexLastColumn.append(indexLastColumn[0] + 2)
# print(indexFirstColumn)
# print(indexLastColumn)
# check whether indexFirstColumn[0] and indexLastColumn[0] are in the same line
k0 = (indexLastColumn[0] - indexFirstColumn[0]) / 188.0
count = 0
for x in range(0, 188, 10):
y = round(k0 * x + indexFirstColumn[0])
if imArray[y, x] == 0:
count = count + 1
# print(count)
if count < 14: # typically if they are in the same line, count >= 18
temp = indexLastColumn[1]
indexLastColumn[1] = indexLastColumn[0]
indexLastColumn[0] = temp
k0 = (indexLastColumn[0] - indexFirstColumn[0]) / 188.0
k1 = (indexLastColumn[1] - indexFirstColumn[1]) / 188.0
# eliminate interfering lines
lowerBound = 2.7
upperBound = 3.9
# points in [y-lowerBond,y+upperBound] will be set to True (if no digit pixel)
for x in range(0, 188):
y0 = k0 * x + indexFirstColumn[0]
lower = max(round(y0 - lowerBound), 0)
upper = min(round(y0 + upperBound), 99) # avoid array index out of bound
# imArray[round(y0), x] = True
if (imArray[lower, x] != 0) and (imArray[upper, x] != 0):
for j in range(lower, upper + 1):
imArray[j, x] = True
y1 = k1 * x + indexFirstColumn[1]
lower = max(round(y1 - lowerBound), 0)
upper = min(round(y1 + upperBound), 99)
# imArray[round(y1), x] = True
if (imArray[lower, x] != 0) and (imArray[upper, x] != 0):
for j in range(lower, upper + 1):
imArray[j, x] = True
# result = tesserocr.image_to_text(im)
imgs = [Image.fromarray(numpy.uint8(imArray[:, 0:47] * 255))]
imgs.append(Image.fromarray(numpy.uint8(imArray[:, 47:94] * 255)))
imgs.append(Image.fromarray(numpy.uint8(imArray[:, 94:141] * 255)))
imgs.append(Image.fromarray(numpy.uint8(imArray[:, 141:188] * 255)))
processed = Image.fromarray(numpy.uint8(imArray * 255))
return imgs, processed
if __name__ == '__main__':
convertRawImg()