100 lines
3.0 KiB
Markdown
100 lines
3.0 KiB
Markdown
|
|
## Fish Body Segmentation (YOLOv8-seg)
|
||
|
|
|
||
|
|
This folder provides a quick pipeline to train a **body-only** fish segmentation model using **Labelme polygon annotations**.
|
||
|
|
|
||
|
|
The goal is to produce a mask that **excludes fins and tail** (as much as possible), so the depth->pointcloud becomes cleaner for weight estimation.
|
||
|
|
|
||
|
|
### 1) Labeling in Labelme
|
||
|
|
|
||
|
|
- Use `Labelme` polygon tool.
|
||
|
|
- Recommended class name: `body` (you can use other names; see `--classes` below).
|
||
|
|
- Each image produces a `.json` annotation file.
|
||
|
|
|
||
|
|
### 2) Convert Labelme JSON -> YOLOv8-seg dataset
|
||
|
|
|
||
|
|
This will create a YOLO dataset folder:
|
||
|
|
|
||
|
|
```
|
||
|
|
<out_dir>/
|
||
|
|
images/train, images/val, images/test
|
||
|
|
labels/train, labels/val, labels/test
|
||
|
|
dataset.yaml
|
||
|
|
```
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
python3 segmentation/prepare_yolo_seg_dataset.py \
|
||
|
|
--source_dir /path/to/labelme_export \
|
||
|
|
--out_dir ./datasets/fish_body_seg \
|
||
|
|
--classes body \
|
||
|
|
--train_ratio 0.8 --val_ratio 0.1 --test_ratio 0.1 \
|
||
|
|
--seed 42 \
|
||
|
|
--copy
|
||
|
|
```
|
||
|
|
|
||
|
|
Notes:
|
||
|
|
- YOLOv8-seg label format is: `<class_id> x1 y1 x2 y2 ... xn yn` (all normalized to [0,1]).
|
||
|
|
- If an image has no valid polygons, an empty label file will be written (you can change this later if desired).
|
||
|
|
|
||
|
|
### 2b) Filter existing prepared dataset (if only some images are labeled)
|
||
|
|
|
||
|
|
If you already have a prepared YOLO-seg dataset but only some images have labels, use this mode to filter and keep only labeled images:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
python3 segmentation/prepare_yolo_seg_dataset.py \
|
||
|
|
--prepared_dataset /home/ubuntu/data/fish/fish_measure_intermediates/yolo_seg \
|
||
|
|
--out_dir ./datasets/fish_body_seg_filtered \
|
||
|
|
--classes body \
|
||
|
|
--copy
|
||
|
|
```
|
||
|
|
|
||
|
|
This will:
|
||
|
|
- Scan `images/train/`, `images/val/`, `images/test/` for images
|
||
|
|
- Check for corresponding `.txt` label files in `labels/train/`, `labels/val/`, `labels/test/`
|
||
|
|
- Only copy/symlink images that have labels
|
||
|
|
- Generate a clean `dataset.yaml` for training
|
||
|
|
|
||
|
|
### 3) Visualize labels (optional - verify conversion correctness)
|
||
|
|
|
||
|
|
Before training, you can visualize the converted labels to verify they're correct:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
python3 segmentation/visualize_yolo_seg_labels.py \
|
||
|
|
--dataset ./datasets/fish_body_seg_filtered \
|
||
|
|
--output ./visualizations/yolo_seg_labels \
|
||
|
|
--split train \
|
||
|
|
--max_images 50 \
|
||
|
|
--classes fishbody \
|
||
|
|
--alpha 0.5
|
||
|
|
```
|
||
|
|
|
||
|
|
This will:
|
||
|
|
- Load images and their corresponding `.txt` label files
|
||
|
|
- Draw polygon masks (semi-transparent overlay) on images
|
||
|
|
- Save visualized images to the output directory
|
||
|
|
- Useful for checking that Labelme → YOLO conversion preserved polygon shapes correctly
|
||
|
|
|
||
|
|
### 4) Train YOLOv8 segmentation
|
||
|
|
|
||
|
|
```bash
|
||
|
|
python3 segmentation/train_yolo_seg.py \
|
||
|
|
--data ./datasets/fish_body_seg/dataset.yaml \
|
||
|
|
--model yolov8s-seg.pt \
|
||
|
|
--epochs 200 \
|
||
|
|
--batch 16 \
|
||
|
|
--imgsz 640 \
|
||
|
|
--project runs/seg \
|
||
|
|
--name fish_body_seg_$(date +%Y%m%d_%H%M%S)
|
||
|
|
```
|
||
|
|
|
||
|
|
Outputs:
|
||
|
|
- `runs/seg/<name>/weights/best.pt`
|
||
|
|
|
||
|
|
### 5) Next step (pipeline integration)
|
||
|
|
|
||
|
|
After training, you can run segmentation on:
|
||
|
|
- full image, or
|
||
|
|
- **cropped image from detector bbox** (often better when fish is small in the frame).
|
||
|
|
|