Spaces:
Sleeping
Sleeping
alrichardbollans
commited on
Commit
·
11dbff2
1
Parent(s):
50baaf9
Improve explanations. Fix NMS default
Browse files- app.py +21 -11
- python_utils/get_model.py +1 -1
- styles.css +1 -0
app.py
CHANGED
|
@@ -44,7 +44,7 @@ main_app = ui.page_fluid(
|
|
| 44 |
accept=[".png", ".jpg", ".jpeg"]),
|
| 45 |
|
| 46 |
ui.input_slider("threshold", "Threshold for Discarding Overlapping Segmentations"
|
| 47 |
-
" (ADD a more descriptive label, and explain in text above).", 0, 1.0, 0.
|
| 48 |
|
| 49 |
ui.tags.style("""
|
| 50 |
.irs.irs--shiny .irs-single { /* square with number */
|
|
@@ -119,15 +119,23 @@ app_ui = ui.page_fluid(
|
|
| 119 |
),
|
| 120 |
|
| 121 |
ui.div(
|
|
|
|
| 122 |
ui.p(
|
| 123 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
ui.a("GitHub", href=protocol_url, target="_blank"),
|
| 125 |
-
". The protocol is available in English, Indonesian, Thai, French, Spanish, Portuguese, Arabic, Mandarin, Malagasy and Japanese.",
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
"
|
| 129 |
-
|
| 130 |
-
|
|
|
|
|
|
|
|
|
|
| 131 |
class_="body-bar"
|
| 132 |
),
|
| 133 |
main_app,
|
|
@@ -138,6 +146,7 @@ app_ui = ui.page_fluid(
|
|
| 138 |
# id="page",
|
| 139 |
# ),
|
| 140 |
ui.div(
|
|
|
|
| 141 |
ui.p(
|
| 142 |
acknowledgement_text
|
| 143 |
),
|
|
@@ -264,14 +273,14 @@ def server(input, output, session: Session):
|
|
| 264 |
"viable": classes.count(0),
|
| 265 |
"non-viable": classes.count(1),
|
| 266 |
"empty": classes.count(2),
|
| 267 |
-
"total": len(classes)
|
|
|
|
| 268 |
})
|
| 269 |
|
| 270 |
# Update reactive value
|
| 271 |
analysis_results.set(results)
|
| 272 |
is_analyzing.set(False) # Set analyzing flag to False when done
|
| 273 |
|
| 274 |
-
@output
|
| 275 |
@render.ui
|
| 276 |
def results_container():
|
| 277 |
results = analysis_results.get()
|
|
@@ -321,7 +330,8 @@ def server(input, output, session: Session):
|
|
| 321 |
"Viable": r.get("viable", ""),
|
| 322 |
"Non-Viable": r.get("non-viable", ""),
|
| 323 |
"Empty": r.get("empty", ""),
|
| 324 |
-
"Total": r.get("total", "")
|
|
|
|
| 325 |
} for r in results])
|
| 326 |
|
| 327 |
# Create in-memory CSV file
|
|
|
|
| 44 |
accept=[".png", ".jpg", ".jpeg"]),
|
| 45 |
|
| 46 |
ui.input_slider("threshold", "Threshold for Discarding Overlapping Segmentations"
|
| 47 |
+
" (ADD a more descriptive label, and explain in text above).", 0, 1.0, 0.7),
|
| 48 |
|
| 49 |
ui.tags.style("""
|
| 50 |
.irs.irs--shiny .irs-single { /* square with number */
|
|
|
|
| 119 |
),
|
| 120 |
|
| 121 |
ui.div(
|
| 122 |
+
ui.h4("Using this App"),
|
| 123 |
ui.p(
|
| 124 |
+
"This app is built to use a computer vision model to analyse images of orchid TZ tests and count the number of viable, non-viable and empty seeds."
|
| 125 |
+
" To use this app, upload images and click 'Analyse'."
|
| 126 |
+
" Segmented images will be displayed in the right-hand panel and results can be downloaded."),
|
| 127 |
+
ui.p(
|
| 128 |
+
"This app is built for use with specific types of images -- the protocol for taking images compatible with this model is available on ",
|
| 129 |
ui.a("GitHub", href=protocol_url, target="_blank"),
|
| 130 |
+
". The protocol is available in English, Indonesian, Thai, French, Spanish, Portuguese, Arabic, Mandarin, Malagasy and Japanese."),
|
| 131 |
+
ui.p(
|
| 132 |
+
"NMS set to 0.7 as this was found to be optimal for our data, but you can adjust this value in the slider and lower values may be useful for images"
|
| 133 |
+
"with more overlapping seeds."),
|
| 134 |
+
ui.p(" If you have any feedback on the app, please start a discussion on ",
|
| 135 |
+
ui.a("the HuggingFace space", href=discussion_url, target="_blank")
|
| 136 |
+
),
|
| 137 |
+
ui.h4("Model Details and Accuracy"),
|
| 138 |
+
ui.p(),
|
| 139 |
class_="body-bar"
|
| 140 |
),
|
| 141 |
main_app,
|
|
|
|
| 146 |
# id="page",
|
| 147 |
# ),
|
| 148 |
ui.div(
|
| 149 |
+
ui.h4("Acknowledgements"),
|
| 150 |
ui.p(
|
| 151 |
acknowledgement_text
|
| 152 |
),
|
|
|
|
| 273 |
"viable": classes.count(0),
|
| 274 |
"non-viable": classes.count(1),
|
| 275 |
"empty": classes.count(2),
|
| 276 |
+
"total": len(classes),
|
| 277 |
+
'NMS threshold': input.threshold()
|
| 278 |
})
|
| 279 |
|
| 280 |
# Update reactive value
|
| 281 |
analysis_results.set(results)
|
| 282 |
is_analyzing.set(False) # Set analyzing flag to False when done
|
| 283 |
|
|
|
|
| 284 |
@render.ui
|
| 285 |
def results_container():
|
| 286 |
results = analysis_results.get()
|
|
|
|
| 330 |
"Viable": r.get("viable", ""),
|
| 331 |
"Non-Viable": r.get("non-viable", ""),
|
| 332 |
"Empty": r.get("empty", ""),
|
| 333 |
+
"Total": r.get("total", ""),
|
| 334 |
+
'NMS Threshold': r.get('NMS threshold', ''),
|
| 335 |
} for r in results])
|
| 336 |
|
| 337 |
# Create in-memory CSV file
|
python_utils/get_model.py
CHANGED
|
@@ -68,7 +68,7 @@ def mask_nms(masks, scores, nms_threshold=0.5):
|
|
| 68 |
order.remove(j)
|
| 69 |
return masks_kept
|
| 70 |
|
| 71 |
-
def apply_nms(prediction, mask=False, cls_agnostic_nms=0.
|
| 72 |
from torchvision.ops import nms
|
| 73 |
from detectron2.structures import Instances
|
| 74 |
|
|
|
|
| 68 |
order.remove(j)
|
| 69 |
return masks_kept
|
| 70 |
|
| 71 |
+
def apply_nms(prediction, mask=False, cls_agnostic_nms=0.7):
|
| 72 |
from torchvision.ops import nms
|
| 73 |
from detectron2.structures import Instances
|
| 74 |
|
styles.css
CHANGED
|
@@ -41,6 +41,7 @@ body {
|
|
| 41 |
top: 0px;
|
| 42 |
background: white;
|
| 43 |
font-size: 1.1rem;
|
|
|
|
| 44 |
|
| 45 |
z-index: 10;
|
| 46 |
margin-bottom: 10px;
|
|
|
|
| 41 |
top: 0px;
|
| 42 |
background: white;
|
| 43 |
font-size: 1.1rem;
|
| 44 |
+
border-bottom: 2px solid #ddd;
|
| 45 |
|
| 46 |
z-index: 10;
|
| 47 |
margin-bottom: 10px;
|