MichaWehrli commited on
Commit
fab61ba
Β·
verified Β·
1 Parent(s): f135996

Sync from GitHub bb0e5d5

Browse files
Files changed (3) hide show
  1. CHANGELOG.md +9 -0
  2. README.md +3 -2
  3. gradio_app.py +31 -9
CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
  # CollemBot β€” changelog
2
 
 
 
 
 
 
 
 
 
 
3
  ## v0.2.1 (2026-10-28) β€” interface text only
4
  Changes AI-assisted (Claude Opus 5.5); maintainer review pending.
5
 
 
1
  # CollemBot β€” changelog
2
 
3
+ ## v0.2.2 (2026-10-28) β€” desktop version
4
+ Changes AI-assisted (Claude Opus 5.5); maintainer review pending.
5
+
6
+ - New **desktop version** (`desktop/` folder of the repository): the same `gradio_app.py` runs on the user's own computer (double-click launchers `start_collembot.bat` for Windows and `start_collembot.command` for macOS 13+; Docker alternative), with length measurement, hand correction, calibration and ZIP export. See `desktop/README.md`.
7
+ - `launch_app` has two new options: `title_page` (default: shown; off with `title_page=False` or environment variable `COLLEMBOT_TITLE_PAGE=0`) and `inbrowser`. Without them the Space behaves as in v0.2.1.
8
+ - `run_settings.json` now also records `runtime` (`huggingface-space`, `desktop` or `local`) and `device` (e.g. `cuda:0`, `cpu`).
9
+ - Title page, reminder and README now point to the desktop version for large or routine analyses.
10
+ - Detection, tiling, merging, threshold and CSV contents are unchanged.
11
+
12
  ## v0.2.1 (2026-10-28) β€” interface text only
13
  Changes AI-assisted (Claude Opus 5.5); maintainer review pending.
14
 
README.md CHANGED
@@ -11,10 +11,11 @@ pinned: false
11
  # πŸͺ² COLLEMBOT β€” AI-based Collembola Counting for OECD 232
12
 
13
  **⚠️ Beta β€” validate counts before use in publications.**
14
- Version 0.2.1 (2026-10-28): title page with a usage notice; counts unchanged from 0.2.0.
 
15
  Version 0.2.0 (2026-10-20): overlapping detections are now merged exactly as in the published pipeline (base repository `scripts/run_inference.py`). Counts differ from 0.1.x β€” see CHANGELOG.md.
16
 
17
- > **πŸ’Έ Please use this Space considerately.** It runs on a paid cloud GPU that the developers fund themselves and offer free of charge; every hour it runs costs us money, and usage has recently increased sharply. Run only what you need, test settings on 2–3 images before a full batch, and download your results straight away. The Space goes to sleep after 15 minutes without use; the next visitor wakes it up (this may take a few minutes), and results that were not downloaded may be lost. For large or routine analyses, please run CollemBot on your own computer: [github.com/waldstrom/collembot](https://github.com/waldstrom/collembot). Questions or problems: [micha.wehrli@eawag.ch](mailto:micha.wehrli@eawag.ch).
18
 
19
  COLLEMBOT is a free, open-source tool for automated counting and body-size measurement of *Folsomia candida* in OECD 232 soil reproduction toxicity tests. It uses a YOLOv11x-seg instance segmentation model trained on images from six European laboratories.
20
 
 
11
  # πŸͺ² COLLEMBOT β€” AI-based Collembola Counting for OECD 232
12
 
13
  **⚠️ Beta β€” validate counts before use in publications.**
14
+ Version 0.2.2 (2026-10-28): desktop version (same app, runs on your own computer); counts unchanged from 0.2.0.
15
+ Version 0.2.1 (2026-10-28): title page with a usage notice.
16
  Version 0.2.0 (2026-10-20): overlapping detections are now merged exactly as in the published pipeline (base repository `scripts/run_inference.py`). Counts differ from 0.1.x β€” see CHANGELOG.md.
17
 
18
+ > **πŸ’Έ Please use this Space considerately.** It runs on a paid cloud GPU that the developers fund themselves and offer free of charge; every hour it runs costs us money, and usage has recently increased sharply. Run only what you need, test settings on 2–3 images before a full batch, and download your results straight away. The Space goes to sleep after 15 minutes without use; the next visitor wakes it up (this may take a few minutes), and results that were not downloaded may be lost. For large or routine analyses, please use the free **desktop version** (the same app on your own computer; images stay local): [download and instructions](https://github.com/MichaWehrli/collembot_huggingface/tree/main/desktop). Questions or problems: [micha.wehrli@eawag.ch](mailto:micha.wehrli@eawag.ch).
19
 
20
  COLLEMBOT is a free, open-source tool for automated counting and body-size measurement of *Folsomia candida* in OECD 232 soil reproduction toxicity tests. It uses a YOLOv11x-seg instance segmentation model trained on images from six European laboratories.
21
 
gradio_app.py CHANGED
@@ -1922,7 +1922,7 @@ def _make_batch_thumbnail(
1922
  # AI-assisted (Claude Opus 5.5, 2026-10-20); reviewed by: <pending>.
1923
  # Nothing in this block changes detection, fusion or counting.
1924
 
1925
- APP_VERSION = "0.2.1"
1926
 
1927
  # v0.2.1: title page shown before the app (interface text only).
1928
  USAGE_NOTICE_MD = """
@@ -1942,9 +1942,9 @@ up, which may take a few minutes, and results that were not downloaded may be lo
1942
  - **Test first.** Check threshold and px/mm scale on 2–3 images before you run a whole batch.
1943
  - **Download your results straight away** (ZIP or CSV), so you do not have to run them again
1944
  and they are safe when the app goes to sleep.
1945
- - **Large or routine analyses:** please run CollemBot on your own computer.
1946
- It is open source, with installation instructions on
1947
- [GitHub (waldstrom/collembot)](https://github.com/waldstrom/collembot).
1948
 
1949
  **Questions or problems?** Contact [micha.wehrli@eawag.ch](mailto:micha.wehrli@eawag.ch).
1950
 
@@ -1955,8 +1955,8 @@ If CollemBot is useful for your work, please cite
1955
  USAGE_REMINDER_MD = (
1956
  "πŸ’‘ *Free to use, but we pay for every GPU hour: please run only what you need and "
1957
  "download results straight away (the app sleeps after 15 min without use). "
1958
- "Large or routine analyses: run CollemBot locally "
1959
- "([GitHub](https://github.com/waldstrom/collembot)). "
1960
  "Help: [micha.wehrli@eawag.ch](mailto:micha.wehrli@eawag.ch)*"
1961
  )
1962
 
@@ -1973,6 +1973,21 @@ def _title_image_kwargs():
1973
  return {"buttons": ["fullscreen"]}
1974
  return {k: False for k in ("show_download_button", "show_share_button") if k in params}
1975
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1976
  SCALE_HELP = (
1977
  "Measure once per camera setup in ImageJ/Fiji: draw a straight line between "
1978
  "two ruler marks a known distance apart, Analyze > Measure, then "
@@ -2109,6 +2124,8 @@ def _run_settings(conf_threshold: float, scale: Optional[float],
2109
  return {
2110
  "collembot_app_version": APP_VERSION,
2111
  "model_version": MODEL_VERSION_STR,
 
 
2112
  "created_utc": datetime.now(timezone.utc).isoformat(),
2113
  "confidence_threshold": round(float(conf_threshold), 3),
2114
  "fusion_iou_threshold": BEST_IOU,
@@ -2151,6 +2168,8 @@ def launch_app(
2151
  preferred_device: str = DEFAULT_DEVICE,
2152
  predict_batch_size: int = PREDICT_BATCH,
2153
  use_half: Optional[bool] = None,
 
 
2154
  ):
2155
  if share:
2156
  share = False
@@ -2158,6 +2177,9 @@ def launch_app(
2158
  model_path, fuse=fuse,
2159
  preferred_device=preferred_device, use_half=use_half,
2160
  )
 
 
 
2161
 
2162
  default_img = None
2163
  examples: List[List[str]] = []
@@ -2540,7 +2562,7 @@ def launch_app(
2540
  gr.Markdown(f"# πŸͺ² CollemBot v{APP_VERSION} β€” Collembola counting & size analysis")
2541
 
2542
  # v0.2.1: title page; the tabs are shown only after "continue"
2543
- with gr.Column(visible=True) as notice_col:
2544
  with gr.Row(equal_height=False):
2545
  if TITLE_IMAGE.exists():
2546
  with gr.Column(scale=2, min_width=280):
@@ -2552,7 +2574,7 @@ def launch_app(
2552
  "I understand β€” continue to CollemBot", variant="primary")
2553
  usage_reminder = gr.Markdown(USAGE_REMINDER_MD, visible=False)
2554
 
2555
- with gr.Column(visible=False) as app_col, gr.Tabs():
2556
 
2557
  # ── Tab 2: multi-image comparison ─────────────────────────────────
2558
  with gr.Tab("Compare groups"):
@@ -3127,7 +3149,7 @@ def launch_app(
3127
  queue=False,
3128
  )
3129
 
3130
- demo.launch(share=share, debug=True, allowed_paths=["/tmp"])
3131
  return demo
3132
 
3133
 
 
1922
  # AI-assisted (Claude Opus 5.5, 2026-10-20); reviewed by: <pending>.
1923
  # Nothing in this block changes detection, fusion or counting.
1924
 
1925
+ APP_VERSION = "0.2.2"
1926
 
1927
  # v0.2.1: title page shown before the app (interface text only).
1928
  USAGE_NOTICE_MD = """
 
1942
  - **Test first.** Check threshold and px/mm scale on 2–3 images before you run a whole batch.
1943
  - **Download your results straight away** (ZIP or CSV), so you do not have to run them again
1944
  and they are safe when the app goes to sleep.
1945
+ - **Large or routine analyses:** please use the free **desktop version** on your own computer.
1946
+ It is this same app; your images stay on your computer.
1947
+ [Download and instructions](https://github.com/MichaWehrli/collembot_huggingface/tree/main/desktop).
1948
 
1949
  **Questions or problems?** Contact [micha.wehrli@eawag.ch](mailto:micha.wehrli@eawag.ch).
1950
 
 
1955
  USAGE_REMINDER_MD = (
1956
  "πŸ’‘ *Free to use, but we pay for every GPU hour: please run only what you need and "
1957
  "download results straight away (the app sleeps after 15 min without use). "
1958
+ "Large or routine analyses: use the desktop version "
1959
+ "([download](https://github.com/MichaWehrli/collembot_huggingface/tree/main/desktop)). "
1960
  "Help: [micha.wehrli@eawag.ch](mailto:micha.wehrli@eawag.ch)*"
1961
  )
1962
 
 
1973
  return {"buttons": ["fullscreen"]}
1974
  return {k: False for k in ("show_download_button", "show_share_button") if k in params}
1975
 
1976
+
1977
+ # v0.2.2: where the app runs (recorded in run_settings.json). Hugging Face sets SPACE_ID
1978
+ # inside a Space; the desktop launcher sets COLLEMBOT_RUNTIME=desktop.
1979
+ RUNTIME_INFO = {
1980
+ "runtime": ("huggingface-space" if os.environ.get("SPACE_ID")
1981
+ else os.environ.get("COLLEMBOT_RUNTIME", "local")),
1982
+ "device": None,
1983
+ }
1984
+
1985
+
1986
+ def _title_page_default() -> bool:
1987
+ """Title page is shown unless COLLEMBOT_TITLE_PAGE is 0/false/no/off."""
1988
+ value = os.environ.get("COLLEMBOT_TITLE_PAGE", "1").strip().lower()
1989
+ return value not in ("0", "false", "no", "off")
1990
+
1991
  SCALE_HELP = (
1992
  "Measure once per camera setup in ImageJ/Fiji: draw a straight line between "
1993
  "two ruler marks a known distance apart, Analyze > Measure, then "
 
2124
  return {
2125
  "collembot_app_version": APP_VERSION,
2126
  "model_version": MODEL_VERSION_STR,
2127
+ "runtime": RUNTIME_INFO.get("runtime"),
2128
+ "device": RUNTIME_INFO.get("device"),
2129
  "created_utc": datetime.now(timezone.utc).isoformat(),
2130
  "confidence_threshold": round(float(conf_threshold), 3),
2131
  "fusion_iou_threshold": BEST_IOU,
 
2168
  preferred_device: str = DEFAULT_DEVICE,
2169
  predict_batch_size: int = PREDICT_BATCH,
2170
  use_half: Optional[bool] = None,
2171
+ title_page: Optional[bool] = None,
2172
+ inbrowser: bool = False,
2173
  ):
2174
  if share:
2175
  share = False
 
2177
  model_path, fuse=fuse,
2178
  preferred_device=preferred_device, use_half=use_half,
2179
  )
2180
+ RUNTIME_INFO["device"] = str(device)
2181
+ if title_page is None:
2182
+ title_page = _title_page_default()
2183
 
2184
  default_img = None
2185
  examples: List[List[str]] = []
 
2562
  gr.Markdown(f"# πŸͺ² CollemBot v{APP_VERSION} β€” Collembola counting & size analysis")
2563
 
2564
  # v0.2.1: title page; the tabs are shown only after "continue"
2565
+ with gr.Column(visible=title_page) as notice_col:
2566
  with gr.Row(equal_height=False):
2567
  if TITLE_IMAGE.exists():
2568
  with gr.Column(scale=2, min_width=280):
 
2574
  "I understand β€” continue to CollemBot", variant="primary")
2575
  usage_reminder = gr.Markdown(USAGE_REMINDER_MD, visible=False)
2576
 
2577
+ with gr.Column(visible=not title_page) as app_col, gr.Tabs():
2578
 
2579
  # ── Tab 2: multi-image comparison ─────────────────────────────────
2580
  with gr.Tab("Compare groups"):
 
3149
  queue=False,
3150
  )
3151
 
3152
+ demo.launch(share=share, debug=True, allowed_paths=["/tmp"], inbrowser=inbrowser)
3153
  return demo
3154
 
3155