3ndetz commited on
Commit
ea92577
·
verified ·
1 Parent(s): bb42c1a

Upload 11 files

Browse files
README.md CHANGED
@@ -1,10 +1,10 @@
1
  ---
2
- title: Mc Map Resolver
3
- emoji: 🐠
4
- colorFrom: purple
5
- colorTo: blue
6
  sdk: gradio
7
- sdk_version: 4.31.0
8
  app_file: app.py
9
  pinned: false
10
  license: mit
 
1
  ---
2
+ title: MC Map Captcha Resolver
3
+ emoji: 📈
4
+ colorFrom: blue
5
+ colorTo: pink
6
  sdk: gradio
7
+ sdk_version: 3.41.2
8
  app_file: app.py
9
  pinned: false
10
  license: mit
app.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import io
3
+ def solve_captcha(data_bytes: bytes = None, file_name: str = None):
4
+ import time
5
+ import os
6
+ import sys
7
+ import cv2
8
+ import numpy as np
9
+ import onnxruntime
10
+
11
+
12
+ real_tests = False
13
+ from config import characters, img_height, img_width, img_type, max_length, transpose_perm, OUTPUT_ONNX
14
+
15
+ sess = onnxruntime.InferenceSession(f"out.model.onnx")
16
+ name = sess.get_inputs()[0].name
17
+ def get_result(pred):
18
+ """CTC decoder of the output tensor
19
+ https://distill.pub/2017/ctc/
20
+ https://en.wikipedia.org/wiki/Connectionist_temporal_classification
21
+ :return string, float
22
+ """
23
+ accuracy = 1
24
+ last = None
25
+ ans = []
26
+ # pred - 3d tensor, we need 2d array - first element
27
+ for item in pred[0]:
28
+ # get index of element with max accuracy
29
+ char_ind = item.argmax()
30
+ # ignore duplicates and special characters
31
+ if char_ind != last and char_ind != 0 and char_ind != len(characters)+1:
32
+ # this element is a character - append it to answer
33
+ ans.append(characters[char_ind - 1])
34
+ # Get accuracy for current character and multiply global accuracy by it
35
+ accuracy *= item[char_ind]
36
+ last = char_ind
37
+
38
+ answ = "".join(ans)[:max_length]
39
+ return answ, accuracy
40
+
41
+
42
+ def decode_img(data_bytes: bytes):
43
+ # same actions, as for tensorflow
44
+ image = cv2.imdecode(np.asarray(bytearray(data_bytes), dtype=np.uint8), 1)
45
+ image: "np.ndarray" = image.astype(np.float32) / 255.
46
+ if image.shape != (img_height, img_width, 3):
47
+ image = cv2.resize(image, (img_width, img_height))
48
+ image = image.transpose(transpose_perm)
49
+ # Creating tensor ( adding 4d dimension )
50
+ image = np.array([image])
51
+ return image
52
+
53
+ def decode_img_array(nump_array):
54
+ # same actions, as for tensorflow
55
+ #image = cv2.imdecode(nump_array, 1)
56
+ image: "np.ndarray" = nump_array.astype(np.float32) / 255.
57
+ if image.shape != (img_height, img_width, 3):
58
+ image = cv2.resize(image, (img_width, img_height))
59
+ image = image.transpose(transpose_perm)
60
+ # Creating tensor ( adding 4d dimension )
61
+ image = np.array([image])
62
+ return image
63
+
64
+ def solve(data_bytes: bytes=None, file_name=None):
65
+ if file_name:
66
+ with open(file_name, 'rb') as F:
67
+ data_bytes = F.read()
68
+ if data_bytes is None:
69
+ print('[CAPTCHA RESOLVER NN] ПУСТОТА ВМЕСТО БАЙТОВ!')
70
+ return None
71
+ if isinstance(data_bytes,np.ndarray):
72
+ print('Img is ndarray')
73
+ img = decode_img_array(data_bytes)
74
+ else:
75
+ print('Img is bytes')
76
+ img_byte_arr = io.BytesIO()
77
+ data_bytes.save(img_byte_arr, format='PNG')
78
+ img_byte_arr = img_byte_arr.getvalue()
79
+ img = decode_img(data_bytes)
80
+ #print(img)
81
+ pred_onx = sess.run(None, {name: img})[0]
82
+ ans = get_result(pred_onx)
83
+ return ans
84
+ result = solve(data_bytes,file_name)
85
+ print ('solved', result)
86
+ return {"result":result[0], "predict":result[1]}
87
+
88
+ def image_classifier(inp):
89
+ if inp is None:
90
+ return "Не загружена картинка"
91
+ print('INPUT GOT>>>', inp)
92
+ #gradio img inp - numpy ndarray
93
+
94
+
95
+ result = solve_captcha(inp)
96
+ return result
97
+ #inputs=gr.Image(type="pil")
98
+ examples_names = ["1089","3569","5989","18769","73295","89238"]
99
+ examples = []
100
+ for n in examples_names:
101
+ examples.append("examples/"+n+".png")
102
+ demo = gr.Interface(fn=image_classifier, inputs=gr.Image(), outputs="textbox", examples=examples)
103
+ demo.launch(show_api = True)
config.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ img_type = "*.png" # "*.jpeg" # "*.png"
2
+ characters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
3
+ # Desired image dimensions
4
+ img_width = 70#130
5
+ img_height = 50#50
6
+ # Maximum length of any captcha in the dataset
7
+ max_length = 5
8
+
9
+ MODEL_FNAME_TRANING = "output/output.traning2.model"
10
+ MODEL_FNAME = "output/output2.model"
11
+ OUTPUT_ONNX = "output/out.model.onnx"
12
+
13
+ # Training config
14
+ batch_size = 16 # 16 #48 мое норм 77%
15
+ epochs = 100 # 400мое норм 77
16
+ early_stopping_patience = 20 #было 10 #40 мое норм 77%
17
+ train_ratio = 0.8
18
+
19
+ # соотношение TRAIN IMAGES к TEST IMAGES, 0.9 означает 0.9 для трейн и 0.1 для тест.
20
+ # Ставь 1.0 если для теста юзать только те что в папке тест
21
+
22
+ transpose_perm = [1, 0, 2]
23
+ # батч епохи патиенс
24
+
25
+ # 1
26
+ # 48 400 40 нормас 77% вроде 170 эпоха
27
+
28
+ # 2
29
+ #96 800 80
30
+ # loss 0.2-0.1 на 200 эпохе; 300 эпоха стабильно 0.1 потом меньше 0.1
examples/1089.png ADDED
examples/18769.png ADDED
examples/3569.png ADDED
examples/5989.png ADDED
examples/73295.png ADDED
examples/89238.png ADDED
out.model.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:22fce976f92bc8abe8ee3b1f4fcd3a1032e17cf006bca2b88624a332ef4031dc
3
+ size 1750703
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ onnx
2
+ onnxruntime
3
+ opencv-python
4
+ numpy