Spaces:
Sleeping
Sleeping
penut85420
commited on
Commit
•
8837f64
1
Parent(s):
d0f39fb
update
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- app.py +114 -22
- bg.png +0 -0
- chars/あ.png +0 -0
- chars/い.png +0 -0
- chars/う.png +0 -0
- chars/え.png +0 -0
- chars/お.png +0 -0
- chars/か.png +0 -0
- chars//343/201/214.png +0 -0
- chars/き.png +0 -0
- chars//343/201/216.png +0 -0
- chars/く.png +0 -0
- chars//343/201/220.png +0 -0
- chars/け.png +0 -0
- chars//343/201/222.png +0 -0
- chars/こ.png +0 -0
- chars//343/201/224.png +0 -0
- chars/さ.png +0 -0
- chars//343/201/226.png +0 -0
- chars/し.png +0 -0
- chars//343/201/230.png +0 -0
- chars/す.png +0 -0
- chars//343/201/232.png +0 -0
- chars/せ.png +0 -0
- chars//343/201/234.png +0 -0
- chars/そ.png +0 -0
- chars//343/201/236.png +0 -0
- chars/た.png +0 -0
- chars//343/201/240.png +0 -0
- chars/ち.png +0 -0
- chars//343/201/242.png +0 -0
- chars/つ.png +0 -0
- chars//343/201/245.png +0 -0
- chars/て.png +0 -0
- chars//343/201/247.png +0 -0
- chars/と.png +0 -0
- chars//343/201/251.png +0 -0
- chars/な.png +0 -0
- chars/に.png +0 -0
- chars/ぬ.png +0 -0
- chars/ね.png +0 -0
- chars/の.png +0 -0
- chars/は.png +0 -0
- chars//343/201/260.png +0 -0
- chars//343/201/261.png +0 -0
- chars/ひ.png +0 -0
- chars//343/201/263.png +0 -0
- chars//343/201/264.png +0 -0
- chars/ふ.png +0 -0
- chars//343/201/266.png +0 -0
app.py
CHANGED
@@ -3,55 +3,147 @@ import random
|
|
3 |
|
4 |
import gradio as gr
|
5 |
import numpy as np
|
|
|
6 |
|
7 |
from ocr import Recognizer
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
chars = [os.path.join(dn, fn) for dn, _, ff in os.walk("chars") for fn in ff]
|
10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
font = gr.themes.GoogleFont("Noto Sans")
|
12 |
theme = gr.themes.Soft(font=font)
|
13 |
|
14 |
with gr.Blocks(theme=theme, title="Kana Writer") as app:
|
15 |
-
|
16 |
-
|
|
|
17 |
recog = Recognizer("model/model.xml", "model/char_list.txt")
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
29 |
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
|
|
|
|
33 |
|
34 |
def parse_item(item):
|
35 |
prob = item["prob"]
|
36 |
char = item["char"]
|
37 |
-
return f"{char}: {prob:.2%}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
def do_recog(img: dict[str, np.ndarray]):
|
40 |
img: np.ndarray = img["layers"][0]
|
41 |
img[img == 0] = 255
|
42 |
img[img != 255] = 0
|
43 |
_, nbest = recog(img)
|
44 |
-
return "
|
45 |
|
46 |
-
def rand_char():
|
47 |
-
char =
|
48 |
-
return char,
|
49 |
|
50 |
def clear(curr_char):
|
51 |
return curr_char
|
52 |
|
|
|
|
|
|
|
|
|
53 |
check_btn.click(do_recog, sketch, result, show_progress="minimal")
|
54 |
-
rand_btn.click(
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
|
57 |
app.launch()
|
|
|
3 |
|
4 |
import gradio as gr
|
5 |
import numpy as np
|
6 |
+
from romkan import to_roma
|
7 |
|
8 |
from ocr import Recognizer
|
9 |
|
10 |
+
kana_list = """
|
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 |
+
kana_list = [c for c in kana_list if c.strip()]
|
46 |
+
|
47 |
chars = [os.path.join(dn, fn) for dn, _, ff in os.walk("chars") for fn in ff]
|
48 |
|
49 |
+
|
50 |
+
def get_char(ch=None, assist=True, kana=True):
|
51 |
+
if ch is None:
|
52 |
+
img_path = random.choice(chars)
|
53 |
+
ch = img_path[-5]
|
54 |
+
else:
|
55 |
+
img_path = f"chars/{ch}.png"
|
56 |
+
|
57 |
+
if not assist:
|
58 |
+
img_path = "bg.png"
|
59 |
+
|
60 |
+
info = f"{ch} ({to_roma(ch)})"
|
61 |
+
if not kana:
|
62 |
+
info = f"{to_roma(ch)}"
|
63 |
+
|
64 |
+
return ch, img_path, info
|
65 |
+
|
66 |
+
|
67 |
font = gr.themes.GoogleFont("Noto Sans")
|
68 |
theme = gr.themes.Soft(font=font)
|
69 |
|
70 |
with gr.Blocks(theme=theme, title="Kana Writer") as app:
|
71 |
+
ch, char_img, roma = get_char()
|
72 |
+
curr_img_path = gr.State(char_img)
|
73 |
+
curr_char = gr.State(ch)
|
74 |
recog = Recognizer("model/model.xml", "model/char_list.txt")
|
75 |
|
76 |
+
with gr.Tab("寫字練習"):
|
77 |
+
brush = gr.Brush(default_color="#111", default_size=15)
|
78 |
+
sketch = gr.Sketchpad(
|
79 |
+
char_img,
|
80 |
+
type="numpy",
|
81 |
+
brush=brush,
|
82 |
+
layers=False,
|
83 |
+
image_mode="RGB",
|
84 |
+
eraser=False,
|
85 |
+
show_label=False,
|
86 |
+
)
|
87 |
+
with gr.Row():
|
88 |
+
header = gr.Textbox(roma, label="目標")
|
89 |
+
result = gr.Textbox(label="辨識結果")
|
90 |
|
91 |
+
with gr.Row():
|
92 |
+
with gr.Row():
|
93 |
+
assist = gr.Checkbox(True, label="輔助")
|
94 |
+
kana = gr.Checkbox(True, label="假名")
|
95 |
+
rand_btn = gr.Button("隨機")
|
96 |
+
check_btn = gr.Button("辨識")
|
97 |
|
98 |
def parse_item(item):
|
99 |
prob = item["prob"]
|
100 |
char = item["char"]
|
101 |
+
return f"{char} ({to_roma(char)}): {prob:.2%}"
|
102 |
+
|
103 |
+
def valid_item(item):
|
104 |
+
if item["prob"] < 1e-2:
|
105 |
+
return False
|
106 |
+
if item["char"] not in kana_list:
|
107 |
+
return False
|
108 |
+
return True
|
109 |
|
110 |
def do_recog(img: dict[str, np.ndarray]):
|
111 |
img: np.ndarray = img["layers"][0]
|
112 |
img[img == 0] = 255
|
113 |
img[img != 255] = 0
|
114 |
_, nbest = recog(img)
|
115 |
+
return ", ".join(parse_item(item) for items in nbest for item in items if valid_item(item))
|
116 |
|
117 |
+
def rand_char(assist, kana):
|
118 |
+
char, img, roma = get_char(None, assist, kana)
|
119 |
+
return char, img, img, roma, None
|
120 |
|
121 |
def clear(curr_char):
|
122 |
return curr_char
|
123 |
|
124 |
+
def change_opt(curr_char, assist, kana):
|
125 |
+
char, img, roma = get_char(curr_char, assist, kana)
|
126 |
+
return char, img, img, roma
|
127 |
+
|
128 |
check_btn.click(do_recog, sketch, result, show_progress="minimal")
|
129 |
+
rand_btn.click(
|
130 |
+
rand_char,
|
131 |
+
[assist, kana],
|
132 |
+
[curr_char, sketch, curr_img_path, header, result],
|
133 |
+
show_progress="minimal",
|
134 |
+
)
|
135 |
+
sketch.clear(clear, curr_img_path, sketch, show_progress="minimal")
|
136 |
+
assist.change(
|
137 |
+
change_opt,
|
138 |
+
[curr_char, assist, kana],
|
139 |
+
[curr_char, sketch, curr_img_path, header],
|
140 |
+
show_progress="minimal",
|
141 |
+
)
|
142 |
+
kana.change(
|
143 |
+
change_opt,
|
144 |
+
[curr_char, assist, kana],
|
145 |
+
[curr_char, sketch, curr_img_path, header],
|
146 |
+
show_progress="minimal",
|
147 |
+
)
|
148 |
|
149 |
app.launch()
|
bg.png
ADDED
chars/あ.png
CHANGED
chars/い.png
CHANGED
chars/う.png
CHANGED
chars/え.png
CHANGED
chars/お.png
CHANGED
chars/か.png
CHANGED
chars//343/201/214.png
ADDED
chars/き.png
CHANGED
chars//343/201/216.png
ADDED
chars/く.png
CHANGED
chars//343/201/220.png
ADDED
chars/け.png
CHANGED
chars//343/201/222.png
ADDED
chars/こ.png
CHANGED
chars//343/201/224.png
ADDED
chars/さ.png
CHANGED
chars//343/201/226.png
ADDED
chars/し.png
CHANGED
chars//343/201/230.png
ADDED
chars/す.png
CHANGED
chars//343/201/232.png
ADDED
chars/せ.png
CHANGED
chars//343/201/234.png
ADDED
chars/そ.png
CHANGED
chars//343/201/236.png
ADDED
chars/た.png
CHANGED
chars//343/201/240.png
ADDED
chars/ち.png
CHANGED
chars//343/201/242.png
ADDED
chars/つ.png
CHANGED
chars//343/201/245.png
ADDED
chars/て.png
CHANGED
chars//343/201/247.png
ADDED
chars/と.png
CHANGED
chars//343/201/251.png
ADDED
chars/な.png
CHANGED
chars/に.png
CHANGED
chars/ぬ.png
CHANGED
chars/ね.png
CHANGED
chars/の.png
CHANGED
chars/は.png
CHANGED
chars//343/201/260.png
ADDED
chars//343/201/261.png
ADDED
chars/ひ.png
CHANGED
chars//343/201/263.png
ADDED
chars//343/201/264.png
ADDED
chars/ふ.png
CHANGED
chars//343/201/266.png
ADDED