Spaces:
Sleeping
Sleeping
File size: 5,112 Bytes
3426645 ad83752 3426645 ad83752 3426645 ad83752 3426645 ad83752 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | ---
title: Crop vs No Crop Segmentation
emoji: πΎ
colorFrom: green
colorTo: yellow
sdk: docker
app_port: 8501
pinned: false
---
# πΎ Crop vs No-Crop Segmentation
A production-ready **Streamlit** app that performs **binary semantic
segmentation** with a fine-tuned **NVIDIA SegFormer-B2** model, deployed on
**Hugging Face Spaces** using the **Docker SDK**.
| Class | Meaning | Mask color |
|:-----:|---------|------------|
| 0 | Background / No Crop | Dark gray |
| 1 | Crop | Bright yellow |
Inference is CPU-optimized, so it runs on free Hugging Face Spaces.
---
## β¨ Features
- Upload `jpg` / `jpeg` / `png` images.
- One-click **Run Segmentation** with a progress spinner.
- **Three-panel output:** Original Β· Predicted Mask Β· Crop Overlay
(semi-transparent magenta over crop regions), all at identical size.
- **Download Result** β exports all three panels combined horizontally as
`prediction_result.png`.
- Model is loaded **once** via `@st.cache_resource`.
- Weights load from a **local `best.pt`** or directly from the
**Hugging Face Hub**.
- Automatic **GPU/CPU** device selection; inference under `torch.no_grad()`.
- Friendly error handling for invalid/corrupted uploads, missing weights, and
inference failures.
---
## π§ How the model is built
The architecture is rebuilt from the `nvidia/mit-b2` backbone config with
`num_labels=2`, and the fine-tuned weights are loaded on top:
```python
MODEL_NAME = "nvidia/mit-b2"
config = SegformerConfig.from_pretrained(MODEL_NAME, num_labels=2)
model = SegformerForSemanticSegmentation(config)
model.load_state_dict(torch.load("best.pt", map_location="cpu"), strict=False)
```
The checkpoint is expected to be a plain state dict:
```python
torch.save(model.state_dict(), "best.pt")
```
---
## π Folder structure
```
crop-segmentation/
βββ app.py # Streamlit UI + workflow
βββ predictor.py # Model build (mit-b2) + best.pt loading + inference
βββ utils.py # Image loading, mask/overlay/combine, PNG export
βββ requirements.txt # Python dependencies
βββ Dockerfile # HF Spaces Docker build (Python 3.10, CPU torch)
βββ README.md # This file (with HF Spaces front matter)
βββ .gitignore
βββ .dockerignore
βββ best.pt # Fine-tuned weights (provide your own)
βββ assets/ # Screenshots / static assets
```
---
## π» Local installation
```bash
git clone <your-repo-url>
cd crop-segmentation
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
# CPU torch (optional but recommended for parity with deployment)
pip install torch==2.11.0 torchvision==0.26.0 \
--index-url https://download.pytorch.org/whl/cpu
pip install -r requirements.txt
# Make sure best.pt is present, or set HF_REPO_ID (see below)
streamlit run app.py
```
Open http://localhost:8501.
### Loading weights
Two options, controlled by environment variables:
| Variable | Purpose |
|----------|---------|
| *(none)* | Use a local `best.pt` next to the app. |
| `HF_REPO_ID` | Download `best.pt` from this HF **model** repo, e.g. `your-username/crop-segformer-b2`. |
| `HF_TOKEN` | Token for a private weights repo (optional). |
| `INPUT_SIZE` | Square inference size (default `512`). |
```bash
export HF_REPO_ID="your-username/crop-segformer-b2"
streamlit run app.py
```
---
## π Hugging Face Spaces deployment (Docker SDK)
1. Create a new Space β **SDK: Docker**.
2. Push these files to the Space repository.
3. Provide the weights using **one** of:
- **Commit `best.pt` to the Space** (use Git LFS for large files):
```bash
git lfs install
git lfs track "*.pt"
git add .gitattributes best.pt
git commit -m "Add weights"
git push
```
- **Load from a model repo** β in the Space **Settings β Variables**, set
`HF_REPO_ID` (and `HF_TOKEN` if private). No `best.pt` in the Space needed.
4. The `README.md` front matter pins `sdk: docker` and `app_port: 8501`, so the
Space serves the Streamlit app on port 8501 automatically.
The Space will build the Docker image, install dependencies (CPU torch), and
launch:
```bash
streamlit run app.py --server.port=8501 --server.address=0.0.0.0
```
---
## πΌοΈ Example screenshots
> Replace these placeholders with real screenshots in `assets/`.
| Upload | Results (3 panels) |
|--------|--------------------|
| `assets/screenshot_upload.png` | `assets/screenshot_results.png` |
---
## βοΈ Notes & assumptions
- Preprocessing: convert to RGB β resize to `INPUT_SIZE` β `ToTensor` β
ImageNet normalization (`mean=[0.485,0.456,0.406]`, `std=[0.229,0.224,0.225]`).
If your fine-tuning used different stats or size, set `INPUT_SIZE` and adjust
`IMAGENET_MEAN`/`IMAGENET_STD` in `predictor.py` to match.
- Postprocessing: argmax over upsampled logits, resized back to the original
image resolution.
- Weights are loaded with `strict=False` so minor key mismatches log a warning
rather than crash; verify the warnings are empty for a correct checkpoint.
|