Spaces:
Sleeping
Sleeping
Add pick color
Browse files- pages/About.py +1 -0
- pages/App.py +156 -130
pages/About.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
import streamlit as st
|
| 2 |
|
|
|
|
| 3 |
st.title("OCR solutions comparator")
|
| 4 |
|
| 5 |
st.write("")
|
|
|
|
| 1 |
import streamlit as st
|
| 2 |
|
| 3 |
+
st.set_page_config(page_title='OCR Comparator', layout ="wide")
|
| 4 |
st.title("OCR solutions comparator")
|
| 5 |
|
| 6 |
st.write("")
|
pages/App.py
CHANGED
|
@@ -6,6 +6,7 @@ import plotly.express as px
|
|
| 6 |
import numpy as np
|
| 7 |
import math
|
| 8 |
import pandas as pd
|
|
|
|
| 9 |
|
| 10 |
import cv2
|
| 11 |
from PIL import Image, ImageColor
|
|
@@ -59,7 +60,6 @@ def initializations():
|
|
| 59 |
(['EasyOCR', 'PPOCR', 'MMOCR', 'Tesseract'])
|
| 60 |
dict : names and indices of the OCR solutions
|
| 61 |
({'EasyOCR': 0, 'PPOCR': 1, 'MMOCR': 2, 'Tesseract': 3})
|
| 62 |
-
tuple : color of the detected boxes
|
| 63 |
list of dicts : list of languages supported by each OCR solution
|
| 64 |
list of int : columns for recognition details results
|
| 65 |
dict : confidence color scale
|
|
@@ -72,9 +72,6 @@ def initializations():
|
|
| 72 |
# Columns for recognition details results
|
| 73 |
out_cols_size = [2] + [2,1]*(len(out_reader_type_list)-1) # Except Tesseract
|
| 74 |
|
| 75 |
-
# Color of the detected boxes
|
| 76 |
-
out_color = (0, 76, 153)
|
| 77 |
-
|
| 78 |
# Dicts of laguages supported by each reader
|
| 79 |
out_dict_lang_easyocr = {'Abaza': 'abq', 'Adyghe': 'ady', 'Afrikaans': 'af', 'Angika': 'ang', \
|
| 80 |
'Arabic': 'ar', 'Assamese': 'as', 'Avar': 'ava', 'Azerbaijani': 'az', 'Belarusian': 'be', \
|
|
@@ -156,6 +153,8 @@ def initializations():
|
|
| 156 |
if 'columns_color' not in st.session_state:
|
| 157 |
st.session_state.columns_color = ["rgb(228,26,28)"] + \
|
| 158 |
["rgb(0,0,0)" for x in out_reader_type_list[1:]]
|
|
|
|
|
|
|
| 159 |
|
| 160 |
# Confidence color scale
|
| 161 |
out_list_confid = list(np.arange(0,101,1))
|
|
@@ -176,7 +175,7 @@ def initializations():
|
|
| 176 |
out_fig.update_layout(paper_bgcolor="white", margin=dict(b=0,r=0,t=0,l=0), xaxis_side="top", \
|
| 177 |
showlegend=False)
|
| 178 |
|
| 179 |
-
return out_reader_type_list, out_reader_type_dict,
|
| 180 |
out_cols_size, out_dict_back_colors, out_fig
|
| 181 |
|
| 182 |
###
|
|
@@ -250,7 +249,6 @@ def init_readers(in_list_params):
|
|
| 250 |
return out_list_readers
|
| 251 |
|
| 252 |
###
|
| 253 |
-
@st.experimental_memo(show_spinner=False)
|
| 254 |
def load_image(in_image_file):
|
| 255 |
"""Load input file and open it
|
| 256 |
|
|
@@ -262,10 +260,17 @@ def load_image(in_image_file):
|
|
| 262 |
PIL.Image : input file opened with Pillow
|
| 263 |
matrix : input file opened with Opencv
|
| 264 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 265 |
if isinstance(in_image_file, str):
|
| 266 |
-
out_image_path = "
|
| 267 |
else:
|
| 268 |
-
out_image_path = "
|
|
|
|
| 269 |
img = Image.open(in_image_file)
|
| 270 |
img_saved = img.save(out_image_path)
|
| 271 |
|
|
@@ -393,12 +398,13 @@ def cropped_1box(in_box, in_img):
|
|
| 393 |
|
| 394 |
###
|
| 395 |
@st.experimental_memo(show_spinner=False)
|
| 396 |
-
def tesserocr_detect(_in_img, in_params):
|
| 397 |
"""Detection with Tesseract
|
| 398 |
|
| 399 |
Args:
|
| 400 |
-
|
| 401 |
-
|
|
|
|
| 402 |
|
| 403 |
Returns:
|
| 404 |
list : list of the boxes coordinates
|
|
@@ -407,6 +413,7 @@ def tesserocr_detect(_in_img, in_params):
|
|
| 407 |
try:
|
| 408 |
dict_param = in_params[1]
|
| 409 |
df_res = pytesseract.image_to_data(_in_img, **dict_param, output_type=Output.DATAFRAME)
|
|
|
|
| 410 |
df_res['box'] = df_res.apply(lambda d: [[d['left'], d['top']], \
|
| 411 |
[d['left'] + d['width'], d['top']], \
|
| 412 |
[d['left'] + d['width'], d['top'] + d['height']], \
|
|
@@ -454,7 +461,7 @@ def process_detect(in_image_path, _in_list_images, _in_list_readers, in_list_par
|
|
| 454 |
# Visualization
|
| 455 |
if ppocr_boxes_coordinates:
|
| 456 |
ppocr_image_detect = draw_detected(_in_list_images[0], ppocr_boxes_coordinates, \
|
| 457 |
-
in_color, 'None',
|
| 458 |
else:
|
| 459 |
ppocr_image_detect = ppocr_status
|
| 460 |
##
|
|
@@ -465,19 +472,20 @@ def process_detect(in_image_path, _in_list_images, _in_list_readers, in_list_par
|
|
| 465 |
# Visualization
|
| 466 |
if mmocr_boxes_coordinates:
|
| 467 |
mmocr_image_detect = draw_detected(_in_list_images[0], mmocr_boxes_coordinates, \
|
| 468 |
-
in_color, 'None',
|
| 469 |
else:
|
| 470 |
mmocr_image_detect = mmocr_status
|
| 471 |
##
|
| 472 |
|
| 473 |
## ------- Tesseract Text detection
|
| 474 |
with st.spinner('Tesseract Text detection in progress ...'):
|
| 475 |
-
tesserocr_boxes_coordinates, tesserocr_status = tesserocr_detect(
|
|
|
|
| 476 |
in_list_params[3])
|
| 477 |
# Visualization
|
| 478 |
-
if
|
| 479 |
tesserocr_image_detect = draw_detected(_in_list_images[0],tesserocr_boxes_coordinates,\
|
| 480 |
-
in_color, 'None',
|
| 481 |
else:
|
| 482 |
tesserocr_image_detect = tesserocr_status
|
| 483 |
##
|
|
@@ -508,19 +516,22 @@ def draw_detected(in_image, in_boxes_coordinates, in_color, posit='None', in_thi
|
|
| 508 |
PIL.Image : original image with detected areas
|
| 509 |
"""
|
| 510 |
work_img = in_image.copy()
|
| 511 |
-
|
| 512 |
-
|
| 513 |
-
|
| 514 |
-
|
| 515 |
-
|
| 516 |
-
if posit
|
| 517 |
-
|
| 518 |
-
|
| 519 |
-
|
| 520 |
-
|
| 521 |
-
|
| 522 |
-
|
| 523 |
-
|
|
|
|
|
|
|
|
|
|
| 524 |
|
| 525 |
return out_image_drawn
|
| 526 |
|
|
@@ -820,11 +831,16 @@ def draw_reco_images(in_image, in_boxes_coordinates, in_list_texts, in_list_conf
|
|
| 820 |
list_reco_images[ind_tessocr] = \
|
| 821 |
cv2.rectangle(list_reco_images[ind_tessocr], (box[0][0], box[0][1]), \
|
| 822 |
(box[2][0], box[2][1]), rgb_color, -1)
|
| 823 |
-
|
| 824 |
-
|
| 825 |
-
|
| 826 |
-
|
| 827 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 828 |
|
| 829 |
with show_reco.container():
|
| 830 |
# Draw the results, 2 images per line
|
|
@@ -852,7 +868,8 @@ def draw_reco_images(in_image, in_boxes_coordinates, in_list_texts, in_list_conf
|
|
| 852 |
cols[ind_col].write(list_reco_status[ind], \
|
| 853 |
use_column_width=True)
|
| 854 |
|
| 855 |
-
st.markdown(' 💡
|
|
|
|
| 856 |
###
|
| 857 |
def highlight():
|
| 858 |
"""Draw recognized text on original image, for each OCR solution used
|
|
@@ -868,7 +885,6 @@ def highlight():
|
|
| 868 |
Returns:
|
| 869 |
shows the results container
|
| 870 |
"""
|
| 871 |
-
show_detect.empty()
|
| 872 |
with show_detect.container():
|
| 873 |
columns_size = [1 for x in reader_type_list]
|
| 874 |
column_width = [400 for x in reader_type_list]
|
|
@@ -906,6 +922,10 @@ def get_demo():
|
|
| 906 |
|
| 907 |
return out_img_demo_1, out_img_demo_2
|
| 908 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 909 |
###################################################################################################
|
| 910 |
## MAIN
|
| 911 |
###################################################################################################
|
|
@@ -925,7 +945,7 @@ st.markdown("##### *EasyOCR, PPOCR, MMOCR, Tesseract*")
|
|
| 925 |
|
| 926 |
# Initializations
|
| 927 |
with st.spinner("Initializations in progress ..."):
|
| 928 |
-
reader_type_list, reader_type_dict,
|
| 929 |
cols_size, dict_back_colors, fig_colorscale = initializations()
|
| 930 |
img_demo_1, img_demo_2 = get_demo()
|
| 931 |
|
|
@@ -942,24 +962,27 @@ tesserocr_key_lang = lang_col[3].selectbox(reader_type_list[3]+" :", list_dict_l
|
|
| 942 |
tesserocr_lang = list_dict_lang[3][tesserocr_key_lang]
|
| 943 |
|
| 944 |
st.markdown("#### Choose picture:")
|
| 945 |
-
cols_pict = st.columns([1,
|
| 946 |
-
img_typ = cols_pict[0].radio("", ['Upload file', 'Take a picture', 'Use a demo file'],
|
|
|
|
| 947 |
|
| 948 |
if img_typ == 'Upload file':
|
| 949 |
-
image_file = cols_pict[
|
| 950 |
if img_typ == 'Take a picture':
|
| 951 |
-
image_file = cols_pict[
|
| 952 |
if img_typ == 'Use a demo file':
|
| 953 |
-
|
| 954 |
-
|
| 955 |
-
|
| 956 |
-
|
| 957 |
-
|
| 958 |
-
|
| 959 |
-
|
| 960 |
-
|
| 961 |
-
|
| 962 |
-
|
|
|
|
|
|
|
| 963 |
|
| 964 |
##----------- Process input image -----------------------------------------------------------------
|
| 965 |
if image_file is not None:
|
|
@@ -1076,6 +1099,9 @@ Use rectlar box to calculate faster, and polygonal box more accurate for curved
|
|
| 1076 |
placeholder='Limit tesseract to recognize only this characters', \
|
| 1077 |
help='Example for numbers only : 0123456789')
|
| 1078 |
|
|
|
|
|
|
|
|
|
|
| 1079 |
|
| 1080 |
submit_detect = st.form_submit_button("Launch detection")
|
| 1081 |
|
|
@@ -1127,14 +1153,13 @@ Use rectlar box to calculate faster, and polygonal box more accurate for curved
|
|
| 1127 |
list_params_det, color)
|
| 1128 |
show_info1.empty()
|
| 1129 |
|
| 1130 |
-
|
| 1131 |
-
|
| 1132 |
-
|
| 1133 |
-
|
| 1134 |
-
|
| 1135 |
-
|
| 1136 |
-
|
| 1137 |
-
st.session_state.list_params_det = list_params_det
|
| 1138 |
|
| 1139 |
if 'columns_size' not in st.session_state:
|
| 1140 |
st.session_state.columns_size = [2] + [1 for x in reader_type_list[1:]]
|
|
@@ -1144,7 +1169,7 @@ Use rectlar box to calculate faster, and polygonal box more accurate for curved
|
|
| 1144 |
st.session_state.columns_color = ["rgb(228,26,28)"] + \
|
| 1145 |
["rgb(0,0,0)" for x in reader_type_list[1:]]
|
| 1146 |
|
| 1147 |
-
if
|
| 1148 |
list_coordinates = st.session_state.list_coordinates
|
| 1149 |
list_images = st.session_state.list_images
|
| 1150 |
list_readers = st.session_state.list_readers
|
|
@@ -1310,81 +1335,82 @@ Use rectlar box to calculate faster, and polygonal box more accurate for curved
|
|
| 1310 |
st.session_state.list_reco_status = list_reco_status
|
| 1311 |
|
| 1312 |
if 'df_results' in st.session_state:
|
|
|
|
| 1313 |
##----------- Show recognition results ------------------------------------------------------------
|
| 1314 |
-
|
| 1315 |
-
|
| 1316 |
-
|
| 1317 |
-
|
| 1318 |
-
|
| 1319 |
-
|
| 1320 |
-
|
| 1321 |
-
|
| 1322 |
-
|
| 1323 |
-
|
| 1324 |
-
|
| 1325 |
-
|
| 1326 |
-
|
| 1327 |
-
|
| 1328 |
-
|
| 1329 |
-
|
| 1330 |
-
|
| 1331 |
-
|
| 1332 |
-
|
| 1333 |
-
|
| 1334 |
-
|
| 1335 |
-
|
| 1336 |
-
|
| 1337 |
-
|
| 1338 |
-
|
| 1339 |
-
|
| 1340 |
-
|
| 1341 |
-
|
| 1342 |
-
|
| 1343 |
-
|
| 1344 |
-
|
| 1345 |
-
|
| 1346 |
-
|
| 1347 |
-
|
| 1348 |
-
|
| 1349 |
-
|
| 1350 |
-
|
| 1351 |
-
|
| 1352 |
-
cols = st.columns(cols_size)
|
| 1353 |
-
cols[0].markdown('#### Detected area')
|
| 1354 |
-
for i in range(1, (len(reader_type_list)-1)*2, 2):
|
| 1355 |
-
cols[i].markdown('#### with ' + reader_type_list[i//2])
|
| 1356 |
-
|
| 1357 |
-
for row in st.session_state.df_results.itertuples():
|
| 1358 |
-
#cols = st.columns(1 + len(reader_type_list)*2)
|
| 1359 |
cols = st.columns(cols_size)
|
| 1360 |
-
cols[0].image(row.cropped_image, width=150)
|
| 1361 |
-
for ind_col in range(1, len(cols), 2):
|
| 1362 |
-
cols[ind_col].write(getattr(row, results_cols[ind_col]))
|
| 1363 |
-
cols[ind_col+1].write("("+str( \
|
| 1364 |
-
getattr(row, results_cols[ind_col+1]))+"%)")
|
| 1365 |
-
|
| 1366 |
-
st.download_button(
|
| 1367 |
-
label="Download results as CSV file",
|
| 1368 |
-
data=convert_df(st.session_state.df_results),
|
| 1369 |
-
file_name='OCR_comparator_results.csv',
|
| 1370 |
-
mime='text/csv',
|
| 1371 |
-
)
|
| 1372 |
-
|
| 1373 |
-
if not st.session_state.df_results_tesseract.empty:
|
| 1374 |
-
with st.expander("Detailed areas for Tesseract", expanded=False):
|
| 1375 |
-
cols = st.columns([2,2,1])
|
| 1376 |
cols[0].markdown('#### Detected area')
|
| 1377 |
-
|
| 1378 |
-
|
| 1379 |
-
|
| 1380 |
-
|
| 1381 |
-
cols
|
| 1382 |
-
cols
|
| 1383 |
-
cols[
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1384 |
|
| 1385 |
st.download_button(
|
| 1386 |
-
label="Download
|
| 1387 |
data=convert_df(st.session_state.df_results),
|
| 1388 |
-
file_name='
|
| 1389 |
mime='text/csv',
|
| 1390 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
import numpy as np
|
| 7 |
import math
|
| 8 |
import pandas as pd
|
| 9 |
+
from time import sleep
|
| 10 |
|
| 11 |
import cv2
|
| 12 |
from PIL import Image, ImageColor
|
|
|
|
| 60 |
(['EasyOCR', 'PPOCR', 'MMOCR', 'Tesseract'])
|
| 61 |
dict : names and indices of the OCR solutions
|
| 62 |
({'EasyOCR': 0, 'PPOCR': 1, 'MMOCR': 2, 'Tesseract': 3})
|
|
|
|
| 63 |
list of dicts : list of languages supported by each OCR solution
|
| 64 |
list of int : columns for recognition details results
|
| 65 |
dict : confidence color scale
|
|
|
|
| 72 |
# Columns for recognition details results
|
| 73 |
out_cols_size = [2] + [2,1]*(len(out_reader_type_list)-1) # Except Tesseract
|
| 74 |
|
|
|
|
|
|
|
|
|
|
| 75 |
# Dicts of laguages supported by each reader
|
| 76 |
out_dict_lang_easyocr = {'Abaza': 'abq', 'Adyghe': 'ady', 'Afrikaans': 'af', 'Angika': 'ang', \
|
| 77 |
'Arabic': 'ar', 'Assamese': 'as', 'Avar': 'ava', 'Azerbaijani': 'az', 'Belarusian': 'be', \
|
|
|
|
| 153 |
if 'columns_color' not in st.session_state:
|
| 154 |
st.session_state.columns_color = ["rgb(228,26,28)"] + \
|
| 155 |
["rgb(0,0,0)" for x in out_reader_type_list[1:]]
|
| 156 |
+
if 'list_coordinates' not in st.session_state:
|
| 157 |
+
st.session_state.list_coordinates = []
|
| 158 |
|
| 159 |
# Confidence color scale
|
| 160 |
out_list_confid = list(np.arange(0,101,1))
|
|
|
|
| 175 |
out_fig.update_layout(paper_bgcolor="white", margin=dict(b=0,r=0,t=0,l=0), xaxis_side="top", \
|
| 176 |
showlegend=False)
|
| 177 |
|
| 178 |
+
return out_reader_type_list, out_reader_type_dict, out_list_dict_lang, \
|
| 179 |
out_cols_size, out_dict_back_colors, out_fig
|
| 180 |
|
| 181 |
###
|
|
|
|
| 249 |
return out_list_readers
|
| 250 |
|
| 251 |
###
|
|
|
|
| 252 |
def load_image(in_image_file):
|
| 253 |
"""Load input file and open it
|
| 254 |
|
|
|
|
| 260 |
PIL.Image : input file opened with Pillow
|
| 261 |
matrix : input file opened with Opencv
|
| 262 |
"""
|
| 263 |
+
|
| 264 |
+
#if isinstance(in_image_file, str):
|
| 265 |
+
# out_image_path = "img."+in_image_file.split('.')[-1]
|
| 266 |
+
#else:
|
| 267 |
+
# out_image_path = "img."+in_image_file.name.split('.')[-1]
|
| 268 |
+
|
| 269 |
if isinstance(in_image_file, str):
|
| 270 |
+
out_image_path = "wrk_"+in_image_file
|
| 271 |
else:
|
| 272 |
+
out_image_path = "wrk_"+in_image_file.name
|
| 273 |
+
|
| 274 |
img = Image.open(in_image_file)
|
| 275 |
img_saved = img.save(out_image_path)
|
| 276 |
|
|
|
|
| 398 |
|
| 399 |
###
|
| 400 |
@st.experimental_memo(show_spinner=False)
|
| 401 |
+
def tesserocr_detect(in_image_path, _in_img, in_params):
|
| 402 |
"""Detection with Tesseract
|
| 403 |
|
| 404 |
Args:
|
| 405 |
+
in_image_path (string) : locally saved image path
|
| 406 |
+
_in_img (PIL.Image) : image to consider
|
| 407 |
+
in_params (list) : list with the parameters for detection
|
| 408 |
|
| 409 |
Returns:
|
| 410 |
list : list of the boxes coordinates
|
|
|
|
| 413 |
try:
|
| 414 |
dict_param = in_params[1]
|
| 415 |
df_res = pytesseract.image_to_data(_in_img, **dict_param, output_type=Output.DATAFRAME)
|
| 416 |
+
|
| 417 |
df_res['box'] = df_res.apply(lambda d: [[d['left'], d['top']], \
|
| 418 |
[d['left'] + d['width'], d['top']], \
|
| 419 |
[d['left'] + d['width'], d['top'] + d['height']], \
|
|
|
|
| 461 |
# Visualization
|
| 462 |
if ppocr_boxes_coordinates:
|
| 463 |
ppocr_image_detect = draw_detected(_in_list_images[0], ppocr_boxes_coordinates, \
|
| 464 |
+
in_color, 'None', 3)
|
| 465 |
else:
|
| 466 |
ppocr_image_detect = ppocr_status
|
| 467 |
##
|
|
|
|
| 472 |
# Visualization
|
| 473 |
if mmocr_boxes_coordinates:
|
| 474 |
mmocr_image_detect = draw_detected(_in_list_images[0], mmocr_boxes_coordinates, \
|
| 475 |
+
in_color, 'None', 3)
|
| 476 |
else:
|
| 477 |
mmocr_image_detect = mmocr_status
|
| 478 |
##
|
| 479 |
|
| 480 |
## ------- Tesseract Text detection
|
| 481 |
with st.spinner('Tesseract Text detection in progress ...'):
|
| 482 |
+
tesserocr_boxes_coordinates, tesserocr_status = tesserocr_detect(in_image_path, \
|
| 483 |
+
_in_list_images[0], \
|
| 484 |
in_list_params[3])
|
| 485 |
# Visualization
|
| 486 |
+
if tesserocr_status == 'OK':
|
| 487 |
tesserocr_image_detect = draw_detected(_in_list_images[0],tesserocr_boxes_coordinates,\
|
| 488 |
+
in_color, 'None', 3)
|
| 489 |
else:
|
| 490 |
tesserocr_image_detect = tesserocr_status
|
| 491 |
##
|
|
|
|
| 516 |
PIL.Image : original image with detected areas
|
| 517 |
"""
|
| 518 |
work_img = in_image.copy()
|
| 519 |
+
if in_boxes_coordinates:
|
| 520 |
+
font = cv2.FONT_HERSHEY_SIMPLEX
|
| 521 |
+
for ind_box, box in enumerate(in_boxes_coordinates):
|
| 522 |
+
box = np.reshape(np.array(box), [-1, 1, 2]).astype(np.int64)
|
| 523 |
+
work_img = cv2.polylines(np.array(work_img), [box], True, in_color, in_thickness)
|
| 524 |
+
if posit != 'None':
|
| 525 |
+
if posit == 'top_left':
|
| 526 |
+
pos = tuple(box[0][0])
|
| 527 |
+
elif posit == 'top_right':
|
| 528 |
+
pos = tuple(box[1][0])
|
| 529 |
+
work_img = cv2.putText(work_img, str(ind_box+1), pos, font, 5.5, color, \
|
| 530 |
+
in_thickness,cv2.LINE_AA)
|
| 531 |
+
|
| 532 |
+
out_image_drawn = Image.fromarray(work_img)
|
| 533 |
+
else:
|
| 534 |
+
out_image_drawn = work_img
|
| 535 |
|
| 536 |
return out_image_drawn
|
| 537 |
|
|
|
|
| 831 |
list_reco_images[ind_tessocr] = \
|
| 832 |
cv2.rectangle(list_reco_images[ind_tessocr], (box[0][0], box[0][1]), \
|
| 833 |
(box[2][0], box[2][1]), rgb_color, -1)
|
| 834 |
+
try:
|
| 835 |
+
list_reco_images[ind_tessocr] = \
|
| 836 |
+
cv2.putText(list_reco_images[ind_tessocr], \
|
| 837 |
+
in_df_results_tesseract.iloc[num]['text'], \
|
| 838 |
+
(box[0][0],int(np.round((box[0][1]+box[2][1])/2,0))), \
|
| 839 |
+
cv2.FONT_HERSHEY_DUPLEX, in_font_scale, text_color, 2)
|
| 840 |
+
|
| 841 |
+
except:
|
| 842 |
+
|
| 843 |
+
pass
|
| 844 |
|
| 845 |
with show_reco.container():
|
| 846 |
# Draw the results, 2 images per line
|
|
|
|
| 868 |
cols[ind_col].write(list_reco_status[ind], \
|
| 869 |
use_column_width=True)
|
| 870 |
|
| 871 |
+
st.markdown(' 💡 Bad font size? you can adjust it below and refresh:')
|
| 872 |
+
|
| 873 |
###
|
| 874 |
def highlight():
|
| 875 |
"""Draw recognized text on original image, for each OCR solution used
|
|
|
|
| 885 |
Returns:
|
| 886 |
shows the results container
|
| 887 |
"""
|
|
|
|
| 888 |
with show_detect.container():
|
| 889 |
columns_size = [1 for x in reader_type_list]
|
| 890 |
column_width = [400 for x in reader_type_list]
|
|
|
|
| 922 |
|
| 923 |
return out_img_demo_1, out_img_demo_2
|
| 924 |
|
| 925 |
+
###
|
| 926 |
+
def raz():
|
| 927 |
+
st.session_state.list_coordinates = []
|
| 928 |
+
|
| 929 |
###################################################################################################
|
| 930 |
## MAIN
|
| 931 |
###################################################################################################
|
|
|
|
| 945 |
|
| 946 |
# Initializations
|
| 947 |
with st.spinner("Initializations in progress ..."):
|
| 948 |
+
reader_type_list, reader_type_dict, list_dict_lang, \
|
| 949 |
cols_size, dict_back_colors, fig_colorscale = initializations()
|
| 950 |
img_demo_1, img_demo_2 = get_demo()
|
| 951 |
|
|
|
|
| 962 |
tesserocr_lang = list_dict_lang[3][tesserocr_key_lang]
|
| 963 |
|
| 964 |
st.markdown("#### Choose picture:")
|
| 965 |
+
cols_pict = st.columns([1, 2])
|
| 966 |
+
img_typ = cols_pict[0].radio("", ['Upload file', 'Take a picture', 'Use a demo file'], \
|
| 967 |
+
index=0, on_change=raz)
|
| 968 |
|
| 969 |
if img_typ == 'Upload file':
|
| 970 |
+
image_file = cols_pict[1].file_uploader("Upload a file:", type=["jpg","jpeg"], on_change=raz)
|
| 971 |
if img_typ == 'Take a picture':
|
| 972 |
+
image_file = cols_pict[1].camera_input("Take a picture:", on_change=raz)
|
| 973 |
if img_typ == 'Use a demo file':
|
| 974 |
+
with st.expander('Choose a demo file:', expanded=True):
|
| 975 |
+
demo_used = st.radio('', ['File 1', 'File 2'], index=0, \
|
| 976 |
+
horizontal=True, on_change=raz)
|
| 977 |
+
cols_demo = st.columns([1, 2])
|
| 978 |
+
cols_demo[0].markdown('###### File 1')
|
| 979 |
+
cols_demo[0].image(img_demo_1, width=150)
|
| 980 |
+
cols_demo[1].markdown('###### File 2')
|
| 981 |
+
cols_demo[1].image(img_demo_2, width=300)
|
| 982 |
+
if demo_used == 'File 1':
|
| 983 |
+
image_file = 'img_demo_1.jpg'
|
| 984 |
+
else:
|
| 985 |
+
image_file = 'img_demo_2.jpg'
|
| 986 |
|
| 987 |
##----------- Process input image -----------------------------------------------------------------
|
| 988 |
if image_file is not None:
|
|
|
|
| 1099 |
placeholder='Limit tesseract to recognize only this characters', \
|
| 1100 |
help='Example for numbers only : 0123456789')
|
| 1101 |
|
| 1102 |
+
color_hex = col2.color_picker('Pick a color for boxes outlines', '#004C99')
|
| 1103 |
+
color_part = color_hex.lstrip('#')
|
| 1104 |
+
color = tuple(int(color_part[i:i+2], 16) for i in (0, 2, 4))
|
| 1105 |
|
| 1106 |
submit_detect = st.form_submit_button("Launch detection")
|
| 1107 |
|
|
|
|
| 1153 |
list_params_det, color)
|
| 1154 |
show_info1.empty()
|
| 1155 |
|
| 1156 |
+
# Clear previous recognition results
|
| 1157 |
+
st.session_state.df_results = pd.DataFrame([])
|
| 1158 |
+
|
| 1159 |
+
st.session_state.list_readers = list_readers
|
| 1160 |
+
st.session_state.list_coordinates = list_coordinates
|
| 1161 |
+
st.session_state.list_images = list_images
|
| 1162 |
+
st.session_state.list_params_det = list_params_det
|
|
|
|
| 1163 |
|
| 1164 |
if 'columns_size' not in st.session_state:
|
| 1165 |
st.session_state.columns_size = [2] + [1 for x in reader_type_list[1:]]
|
|
|
|
| 1169 |
st.session_state.columns_color = ["rgb(228,26,28)"] + \
|
| 1170 |
["rgb(0,0,0)" for x in reader_type_list[1:]]
|
| 1171 |
|
| 1172 |
+
if st.session_state.list_coordinates:
|
| 1173 |
list_coordinates = st.session_state.list_coordinates
|
| 1174 |
list_images = st.session_state.list_images
|
| 1175 |
list_readers = st.session_state.list_readers
|
|
|
|
| 1335 |
st.session_state.list_reco_status = list_reco_status
|
| 1336 |
|
| 1337 |
if 'df_results' in st.session_state:
|
| 1338 |
+
if not st.session_state.df_results.empty:
|
| 1339 |
##----------- Show recognition results ------------------------------------------------------------
|
| 1340 |
+
results_cols = st.session_state.df_results.columns
|
| 1341 |
+
list_col_text = np.arange(1, len(cols_size), 2)
|
| 1342 |
+
list_col_confid = np.arange(2, len(cols_size), 2)
|
| 1343 |
+
|
| 1344 |
+
dict_draw_reco = {'in_image': st.session_state.list_images[1], \
|
| 1345 |
+
'in_boxes_coordinates': st.session_state.list_boxes, \
|
| 1346 |
+
'in_list_texts': [st.session_state.df_results[x].to_list() \
|
| 1347 |
+
for x in results_cols[list_col_text]], \
|
| 1348 |
+
'in_list_confid': [st.session_state.df_results[x].to_list() \
|
| 1349 |
+
for x in results_cols[list_col_confid]], \
|
| 1350 |
+
'in_dict_back_colors': dict_back_colors, \
|
| 1351 |
+
'in_df_results_tesseract' : st.session_state.df_results_tesseract, \
|
| 1352 |
+
'in_reader_type_list': reader_type_list
|
| 1353 |
+
}
|
| 1354 |
+
show_reco = st.empty()
|
| 1355 |
+
|
| 1356 |
+
with st.form("form3"):
|
| 1357 |
+
st.plotly_chart(fig_colorscale, use_container_width=True)
|
| 1358 |
+
|
| 1359 |
+
col_font, col_threshold = st.columns(2)
|
| 1360 |
+
|
| 1361 |
+
col_font.slider('Font scale', 1, 7, 4, step=1, key="font_scale_sld")
|
| 1362 |
+
col_threshold.slider('% confidence threshold for text color change', 40, 100, 64, \
|
| 1363 |
+
step=1, key="conf_threshold_sld")
|
| 1364 |
+
col_threshold.write("(text color is black below this % confidence threshold, \
|
| 1365 |
+
and white above)")
|
| 1366 |
+
|
| 1367 |
+
draw_reco_images(**dict_draw_reco)
|
| 1368 |
+
|
| 1369 |
+
submit_resize = st.form_submit_button("Refresh")
|
| 1370 |
+
|
| 1371 |
+
if submit_resize:
|
| 1372 |
+
draw_reco_images(**dict_draw_reco, \
|
| 1373 |
+
in_font_scale=st.session_state.font_scale_sld, \
|
| 1374 |
+
in_conf_threshold=st.session_state.conf_threshold_sld)
|
| 1375 |
+
|
| 1376 |
+
st.subheader("Recognition details")
|
| 1377 |
+
with st.expander("Detailed areas for EasyOCR, PPOCR, MMOCR", expanded=True):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1378 |
cols = st.columns(cols_size)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1379 |
cols[0].markdown('#### Detected area')
|
| 1380 |
+
for i in range(1, (len(reader_type_list)-1)*2, 2):
|
| 1381 |
+
cols[i].markdown('#### with ' + reader_type_list[i//2])
|
| 1382 |
+
|
| 1383 |
+
for row in st.session_state.df_results.itertuples():
|
| 1384 |
+
#cols = st.columns(1 + len(reader_type_list)*2)
|
| 1385 |
+
cols = st.columns(cols_size)
|
| 1386 |
+
cols[0].image(row.cropped_image, width=150)
|
| 1387 |
+
for ind_col in range(1, len(cols), 2):
|
| 1388 |
+
cols[ind_col].write(getattr(row, results_cols[ind_col]))
|
| 1389 |
+
cols[ind_col+1].write("("+str( \
|
| 1390 |
+
getattr(row, results_cols[ind_col+1]))+"%)")
|
| 1391 |
|
| 1392 |
st.download_button(
|
| 1393 |
+
label="Download results as CSV file",
|
| 1394 |
data=convert_df(st.session_state.df_results),
|
| 1395 |
+
file_name='OCR_comparator_results.csv',
|
| 1396 |
mime='text/csv',
|
| 1397 |
)
|
| 1398 |
+
|
| 1399 |
+
if not st.session_state.df_results_tesseract.empty:
|
| 1400 |
+
with st.expander("Detailed areas for Tesseract", expanded=False):
|
| 1401 |
+
cols = st.columns([2,2,1])
|
| 1402 |
+
cols[0].markdown('#### Detected area')
|
| 1403 |
+
cols[1].markdown('#### with Tesseract')
|
| 1404 |
+
|
| 1405 |
+
for row in st.session_state.df_results_tesseract.itertuples():
|
| 1406 |
+
cols = st.columns([2,2,1])
|
| 1407 |
+
cols[0].image(row.cropped, width=150)
|
| 1408 |
+
cols[1].write(getattr(row, 'text'))
|
| 1409 |
+
cols[2].write("("+str(getattr(row, 'conf'))+"%)")
|
| 1410 |
+
|
| 1411 |
+
st.download_button(
|
| 1412 |
+
label="Download Tesseract results as CSV file",
|
| 1413 |
+
data=convert_df(st.session_state.df_results),
|
| 1414 |
+
file_name='OCR_comparator_Tesseract_results.csv',
|
| 1415 |
+
mime='text/csv',
|
| 1416 |
+
)
|