Spaces:
No application file
No application file
import streamlit as st | |
from natsort import natsorted | |
import os | |
from PIL import Image | |
import math | |
from streamlit_sparrow_labeling import st_sparrow_labeling | |
import json | |
class DataReview: | |
class Model: | |
# pageTitle = "Data Review" | |
subheader_2 = "Select" | |
subheader_3 = "Result" | |
selection_text = "File to review" | |
initial_msg = "Please select a file to review" | |
img_file = None | |
def set_image_file(self, img_file): | |
st.session_state['img_file_review'] = img_file | |
def get_image_file(self): | |
if 'img_file_review' not in st.session_state: | |
return None | |
return st.session_state['img_file_review'] | |
json_file = None | |
def set_json_file(self, json_file): | |
st.session_state['json_file_review'] = json_file | |
def get_json_file(self): | |
if 'json_file_review' not in st.session_state: | |
return None | |
return st.session_state['json_file_review'] | |
def view(self, model, ui_width, device_type, device_width): | |
# st.title(model.pageTitle) | |
with st.sidebar: | |
st.markdown("---") | |
st.subheader(model.subheader_2) | |
# get list of files in inference directory | |
processed_file_names = self.get_processed_file_names('docs/inference/') | |
if 'selection_index' not in st.session_state: | |
st.session_state['selection_index'] = 0 | |
selection_index = 0 | |
else: | |
selection_index = st.session_state['selection_index'] | |
selection = st.selectbox(model.selection_text, processed_file_names, index=selection_index) | |
selection_index = self.get_selection_index(selection, processed_file_names) | |
st.session_state['selection_index'] = selection_index | |
img_file = "docs/inference/" + selection + ".jpg" | |
json_file = "docs/inference/" + selection + ".json" | |
model.set_image_file(img_file) | |
model.set_json_file(json_file) | |
if model.get_image_file() is not None: | |
doc_img = Image.open(model.get_image_file()) | |
doc_height = doc_img.height | |
doc_width = doc_img.width | |
canvas_width, number_of_columns = self.canvas_available_width(ui_width, doc_width, device_type, | |
device_width) | |
if number_of_columns > 1: | |
col1, col2 = st.columns([number_of_columns, 10 - number_of_columns]) | |
with col1: | |
pass | |
self.render_doc(model, doc_img, canvas_width, doc_height, doc_width) | |
with col2: | |
pass | |
self.render_results(model) | |
else: | |
pass | |
self.render_doc(model, doc_img, canvas_width, doc_height, doc_width) | |
self.render_results(model) | |
else: | |
st.title(model.initial_msg) | |
def get_processed_file_names(self, dir_name): | |
# get ordered list of files without file extension, excluding hidden files, with JSON extension only | |
file_names = [os.path.splitext(f)[0] for f in os.listdir(dir_name) if | |
os.path.isfile(os.path.join(dir_name, f)) and not f.startswith('.') and f.endswith('.json')] | |
file_names = natsorted(file_names) | |
return file_names | |
def get_selection_index(self, file, files_list): | |
return files_list.index(file) | |
def canvas_available_width(self, ui_width, doc_width, device_type, device_width): | |
doc_width_pct = (doc_width * 100) / ui_width | |
if doc_width_pct < 45: | |
canvas_width_pct = 37 | |
elif doc_width_pct < 55: | |
canvas_width_pct = 49 | |
else: | |
canvas_width_pct = 60 | |
if ui_width > 700 and canvas_width_pct == 37 and device_type == "desktop": | |
return math.floor(canvas_width_pct * ui_width / 100), 4 | |
elif ui_width > 700 and canvas_width_pct == 49 and device_type == "desktop": | |
return math.floor(canvas_width_pct * ui_width / 100), 5 | |
elif ui_width > 700 and canvas_width_pct == 60 and device_type == "desktop": | |
return math.floor(canvas_width_pct * ui_width / 100), 6 | |
else: | |
if device_type == "desktop": | |
ui_width = device_width - math.floor((device_width * 22) / 100) | |
elif device_type == "mobile": | |
ui_width = device_width - math.floor((device_width * 13) / 100) | |
return ui_width, 1 | |
def render_doc(self, model, doc_img, canvas_width, doc_height, doc_width): | |
height = 1296 | |
width = 864 | |
annotations_json = { | |
"meta": { | |
"version": "v0.1", | |
"split": "train", | |
"image_id": 0, | |
"image_size": { | |
"width": doc_width, | |
"height": doc_height | |
} | |
}, | |
"words": [] | |
} | |
st_sparrow_labeling( | |
fill_color="rgba(0, 151, 255, 0.3)", | |
stroke_width=2, | |
stroke_color="rgba(0, 50, 255, 0.7)", | |
background_image=doc_img, | |
initial_rects=annotations_json, | |
height=height, | |
width=width, | |
drawing_mode="transform", | |
display_toolbar=False, | |
update_streamlit=False, | |
canvas_width=canvas_width, | |
doc_height=doc_height, | |
doc_width=doc_width, | |
image_rescale=True, | |
key="doc_annotation" + model.get_image_file() | |
) | |
def render_results(self, model): | |
json_file = model.get_json_file() | |
if json_file is not None: | |
with open(json_file) as f: | |
data_json = json.load(f) | |
st.subheader(model.subheader_3) | |
st.markdown("---") | |
st.json(data_json) | |
st.markdown("---") |