Update app.py
Browse files
app.py
CHANGED
|
@@ -17,12 +17,26 @@ import time
|
|
| 17 |
|
| 18 |
st.set_page_config(page_title="Scratch Assay Segmentation", layout="wide")
|
| 19 |
|
| 20 |
-
APP_VERSION = "
|
| 21 |
DEFAULT_IMGSZ = 640
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
MODEL_OPTIONS = {
|
| 24 |
-
"
|
| 25 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
}
|
| 27 |
|
| 28 |
|
|
@@ -234,9 +248,12 @@ def process_image(uploaded_file, model, model_confidence, fov_um=None, pixel_siz
|
|
| 234 |
def save_feedback(result, avaliacao, observacao, selected_model_label):
|
| 235 |
image_name = result["Imagem"]
|
| 236 |
image_base_name = image_name.rsplit(".", 1)[0]
|
|
|
|
| 237 |
|
| 238 |
-
# 1) Sheet
|
| 239 |
-
|
|
|
|
|
|
|
| 240 |
|
| 241 |
# 2) Drive curation
|
| 242 |
if avaliacao in ["Acceptable", "Bad", "No segmentation"]:
|
|
@@ -247,14 +264,14 @@ def save_feedback(result, avaliacao, observacao, selected_model_label):
|
|
| 247 |
)
|
| 248 |
|
| 249 |
parent_folder = find_or_create_folder("Feedback Segmentacoes")
|
| 250 |
-
model_folder = find_or_create_folder(
|
| 251 |
subfolder = find_or_create_folder(image_base_name, model_folder)
|
| 252 |
|
| 253 |
resized_original = resize_image(result["Exibir"])
|
| 254 |
buf = BytesIO()
|
| 255 |
resized_original.save(buf, format="PNG")
|
| 256 |
buf.seek(0)
|
| 257 |
-
upload_to_drive(buf, f"
|
| 258 |
|
| 259 |
if avaliacao != "No segmentation" and result.get("Segmentada") and result.get("Poligono"):
|
| 260 |
resized_segmented = resize_image(Image.open(BytesIO(result["Segmentada"].getvalue())))
|
|
@@ -266,7 +283,7 @@ def save_feedback(result, avaliacao, observacao, selected_model_label):
|
|
| 266 |
buf.seek(0)
|
| 267 |
upload_to_drive(
|
| 268 |
buf,
|
| 269 |
-
f"{nome}
|
| 270 |
subfolder,
|
| 271 |
)
|
| 272 |
|
|
@@ -316,11 +333,11 @@ with col_input_1:
|
|
| 316 |
upload_option = st.radio("Choose upload type:", ["Single image", "Image folder"], horizontal=True)
|
| 317 |
|
| 318 |
with col_input_2:
|
| 319 |
-
selected_model_label = st.selectbox("
|
| 320 |
|
| 321 |
model = load_model(MODEL_OPTIONS[selected_model_label])
|
| 322 |
|
| 323 |
-
st.caption(f"Selected model
|
| 324 |
|
| 325 |
with st.expander("⚙️ Advanced Settings", expanded=False):
|
| 326 |
model_confidence = st.slider("Model confidence (%)", 20, 100, 80)
|
|
@@ -352,10 +369,17 @@ with st.sidebar:
|
|
| 352 |
with st.expander("About / Citation", expanded=False):
|
| 353 |
st.markdown(
|
| 354 |
"""
|
| 355 |
-
This tool was developed by the **Medical Physics Laboratory** of the Department of **Biophysics and Pharmacology – IBB, UNESP**.
|
| 356 |
-
**FAPESP Process:** 2024/01849-4.
|
| 357 |
-
**Coordination:** Prof. Allan Alves.
|
| 358 |
**Development:** Nycolas Mariotto.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 359 |
"""
|
| 360 |
)
|
| 361 |
|
|
|
|
| 17 |
|
| 18 |
st.set_page_config(page_title="Scratch Assay Segmentation", layout="wide")
|
| 19 |
|
| 20 |
+
APP_VERSION = "3.0"
|
| 21 |
DEFAULT_IMGSZ = 640
|
| 22 |
|
| 23 |
+
# Model nomenclature aligned with the companion manuscript (Mariotto et al.,
|
| 24 |
+
# Cytometry Part A 2026): Model 2 = Roboflow 3.0 Instance Segmentation Extra
|
| 25 |
+
# Large with black-edge padding (Roboflow project version 24); Model 6 =
|
| 26 |
+
# YOLOv11 Instance Segmentation Accurate variant with white-edge padding
|
| 27 |
+
# (Roboflow project version 37). The .pt filenames are kept as the upstream
|
| 28 |
+
# Roboflow version identifiers for traceability with the private model repo.
|
| 29 |
MODEL_OPTIONS = {
|
| 30 |
+
"Model 2": "24.pt",
|
| 31 |
+
"Model 6": "37.pt",
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
# Stable, filesystem-safe key used for Drive folder names and Sheet logging.
|
| 35 |
+
# Decoupled from the user-visible label so future relabeling does not affect
|
| 36 |
+
# stored data.
|
| 37 |
+
MODEL_STORAGE_KEY = {
|
| 38 |
+
"Model 2": "Model_2",
|
| 39 |
+
"Model 6": "Model_6",
|
| 40 |
}
|
| 41 |
|
| 42 |
|
|
|
|
| 248 |
def save_feedback(result, avaliacao, observacao, selected_model_label):
|
| 249 |
image_name = result["Imagem"]
|
| 250 |
image_base_name = image_name.rsplit(".", 1)[0]
|
| 251 |
+
storage_key = MODEL_STORAGE_KEY[selected_model_label]
|
| 252 |
|
| 253 |
+
# 1) Sheet - store the stable storage key (Model_2 / Model_6) rather than
|
| 254 |
+
# the user-visible label, so the spreadsheet stays clean across future
|
| 255 |
+
# label tweaks.
|
| 256 |
+
sheet.append_row([image_name, avaliacao, observacao, storage_key, APP_VERSION])
|
| 257 |
|
| 258 |
# 2) Drive curation
|
| 259 |
if avaliacao in ["Acceptable", "Bad", "No segmentation"]:
|
|
|
|
| 264 |
)
|
| 265 |
|
| 266 |
parent_folder = find_or_create_folder("Feedback Segmentacoes")
|
| 267 |
+
model_folder = find_or_create_folder(storage_key, parent_folder)
|
| 268 |
subfolder = find_or_create_folder(image_base_name, model_folder)
|
| 269 |
|
| 270 |
resized_original = resize_image(result["Exibir"])
|
| 271 |
buf = BytesIO()
|
| 272 |
resized_original.save(buf, format="PNG")
|
| 273 |
buf.seek(0)
|
| 274 |
+
upload_to_drive(buf, f"original_{storage_key}_v{APP_VERSION}_{sufixo}.png", subfolder)
|
| 275 |
|
| 276 |
if avaliacao != "No segmentation" and result.get("Segmentada") and result.get("Poligono"):
|
| 277 |
resized_segmented = resize_image(Image.open(BytesIO(result["Segmentada"].getvalue())))
|
|
|
|
| 283 |
buf.seek(0)
|
| 284 |
upload_to_drive(
|
| 285 |
buf,
|
| 286 |
+
f"{nome}_{storage_key}_v{APP_VERSION}_{sufixo}.png",
|
| 287 |
subfolder,
|
| 288 |
)
|
| 289 |
|
|
|
|
| 333 |
upload_option = st.radio("Choose upload type:", ["Single image", "Image folder"], horizontal=True)
|
| 334 |
|
| 335 |
with col_input_2:
|
| 336 |
+
selected_model_label = st.selectbox("Segmentation model", list(MODEL_OPTIONS.keys()), index=0)
|
| 337 |
|
| 338 |
model = load_model(MODEL_OPTIONS[selected_model_label])
|
| 339 |
|
| 340 |
+
st.caption(f"Selected model: {selected_model_label}")
|
| 341 |
|
| 342 |
with st.expander("⚙️ Advanced Settings", expanded=False):
|
| 343 |
model_confidence = st.slider("Model confidence (%)", 20, 100, 80)
|
|
|
|
| 369 |
with st.expander("About / Citation", expanded=False):
|
| 370 |
st.markdown(
|
| 371 |
"""
|
| 372 |
+
This tool was developed by the **Medical Physics Laboratory** of the Department of **Biophysics and Pharmacology – IBB, UNESP**.
|
| 373 |
+
**FAPESP Process:** 2024/01849-4.
|
| 374 |
+
**Coordination:** Prof. Allan Alves.
|
| 375 |
**Development:** Nycolas Mariotto.
|
| 376 |
+
|
| 377 |
+
Model nomenclature in this interface follows the companion manuscript
|
| 378 |
+
(Mariotto et al., *Cytometry Part A*, 2026):
|
| 379 |
+
- **Model 2**: Roboflow 3.0 Instance Segmentation Extra Large with black-edge padding (Roboflow project version 24).
|
| 380 |
+
- **Model 6**: YOLOv11 Instance Segmentation Accurate variant with white-edge padding (Roboflow project version 37).
|
| 381 |
+
|
| 382 |
+
Companion archive: Zenodo DOI [10.5281/zenodo.20298129](https://doi.org/10.5281/zenodo.20298129).
|
| 383 |
"""
|
| 384 |
)
|
| 385 |
|