The whole flow, from a photo to the dataset
Seven steps for every collection day. The Dashboard only changes after you press Sync from Roboflow, so press it after each step done in Roboflow.
- Take and namePhone, then Drive
- Log the dayCollection tab
- Uploadrf_upload.py
- Draw boxesRoboflow · pass 1
- LabelLabel tab · pass 2
- CheckReview tab · pass 3
- Add to datasetRoboflow · Final
1Take and name the photos
- One picture per level, from two angles, on each of the three phones. That is 8 pictures per phone per day.
- Put them in Drive as Device/Date/, for example Redmi/Oct 12/.
- Name each file by the level it shows, L1 to L4: L1_45.jpg, L1_90.jpg, and so on up to L4_90.jpg. The number after the level is the angle. It is only there to keep the two photos of a level apart.
| Level | Plant IDs | Split |
|---|---|---|
| L1 | 0–5, 10–15 | Test |
| L2 | 100–105, 110–115 | Validation |
| L3 | 200–205, 210–215 | Training |
| L4 | 300–305, 310–315 | Training |
The level in the name gives a photo its split, so that no plant is in two splits. A photo with no level in its name is uploaded with no split and no level tag. If the split was changed in Settings, the table there is the one that counts.
2Log the day
- Open the Collection tab and click the day.
- For each phone, set the status (Collected, then Stored once it is in Drive), the number of images, who handled it, and the Drive link.
- If a plant changed, click it in the grid: Healthy, Unhealthy, or Not pictured. The grid carries over to the next day, so you only click what changed.
- Press Save day.
3Upload to Roboflow
This is a script you run in PowerShell, in the scripts folder of the tracker. First give it four values. PowerShell forgets them when you close the window, so type them again in a new one. Use the private Roboflow key and your own passcode.
$env:ROBOFLOW_API_KEY="..."; $env:RF_PROJECT="lettucesee-dataset" $env:TRACKER_URL="https://lettucesee-tracker.pages.dev"; $env:TRACKER_PASSCODE="..."
Then, always with the same folder:
python rf_upload.py "G:/My Drive/LettuceSee Pictures/October" # dry run: shows the plan, sends nothing python rf_upload.py "G:/My Drive/LettuceSee Pictures/October" --apply # uploads
- Read the dry run first. For each photo it shows the device, the tags (OCT26, the date, the device, set:L1 to set:L4) and the split. It also lists what it skips and why.
- Photos already uploaded are not sent again. To upload one day only, add --only 2026-10-12.
- Press Sync on the Dashboard. The calendar on the Collection tab now shows ↑8 next to each phone whose photos are in Roboflow. Nobody logs this by hand.
4Draw the boxes in Roboflow pass 1
- Run Auto Label on the new photos with one class, lettuce. It draws one box per plant.
- Fix the boxes: one box per plant whose body is more than half visible, around the whole plant. Split boxes that swallowed two plants. Delete boxes on plants that are half hidden or less.
- Do not set healthy or unhealthy here. That is the next step.
- Press Sync on the Dashboard. The photos now show under Pass 2.
A photo with no boxes stays on pass 1 and is never labelled. Boxes come only from Roboflow.
5Label pass 2
- Open the Label tab. It shows how many photos wait and what has been spent.
- Press Label. Each plant is labelled healthy or unhealthy and given a risk. This costs a fraction of a cent per photo. Nothing changes in Roboflow yet. Stop after this image stops cleanly.
- Look at the result on the Review tab if you want to see it before it goes anywhere.
- Press Write to Roboflow. Each box gets its class, and each photo gets its tags: a risk tag, and the reasons it needs a look.
- Press Sync. The photos now show under Pass 3.
A plant that is mostly hidden, or that got no answer, keeps the class lettuce. A person decides those in the next step.
6Check pass 3
- Open the Review tab. Photos are listed riskiest first, each with the plants to look at first and why.
- Press Open in Roboflow and fix what is wrong there: change a class, fix a box, and give every remaining lettuce box a class or delete it.
- When the photo is right, tag it human-approved in Roboflow.
- Check every high and medium risk photo. Of the low risk ones, check a random one in ten. If more than about one in fifty of those labels is wrong, check more of them.
- The low risk photos you did not open are approved as they are: filter by risk:low in Roboflow and tag them human-approved.
An approved photo is never labelled or written again by the tracker.
7Add to the dataset
- In Roboflow, add the approved photos to the dataset, keeping the split they were uploaded with.
- Press Sync. They now count as Final, and Table 4.3 includes them.
- Then look at the Dashboard. Annotation passes should show nothing left on a pass you finished. If it says an approved image still has a box that is not healthy or unhealthy, fix that image. If Split balance says some of our photos are in another split than their level says, move them.
The first time through
These steps are tested against a stand-in for Roboflow, and have not yet run against the real project. Do each on one photo first, and look at the result in Roboflow before doing the rest.
- First upload. Upload one day with --only. In Roboflow, check the photos carry their four tags and the right split, and that you can filter by a tag with a colon in it, such as set:L1.
- First Auto Label. Check that it separates plants that overlap.
- First sync after Auto Label. Check that the photos show under Pass 2. If they do not, tell Philip.
- First write. On the Label tab, press Label, then Stop after this image, so one photo is labelled. Press Write. In Roboflow, check that its boxes did not move, that each has its class, and that the photo has its tags.
- Open in Roboflow. Check that the link on the Review tab opens the right photo.
At the end of the collection, before the first training run
- Rebalance. On the Dashboard, Split balance shows which online images should move so that the whole dataset is 70% training, 15% validation and 15% test. Save the moves as CSV and make them in Roboflow by hand. Our own photos are never moved. Do this once the October photos are all in, not before.
- Verify. The Dashboard must show no boxes left with the class lettuce, and no approved image with a box that is not healthy or unhealthy.
- Lock the split. In Settings, press Lock the split. After this the split by level cannot change.
- Generate the version in Roboflow. Use only approved photos and the online images, and remove the class lettuce.
- Table 4.3. On the Dashboard, copy it as LaTeX or CSV for the manuscript.
If something goes wrong
| What you see | What it means |
|---|---|
| The upload stops with "the split by level is not known" | TRACKER_URL or TRACKER_PASSCODE is not set in that PowerShell window. |
| The upload skips a file as "L0 is the old numbering" | Rename it. The levels are L1 to L4. |
| Label tab: "Labelling is not set up yet" | The labelling key is missing on the server. Tell Philip. |
| Label tab: "Stopped at the cap" | The spending cap was reached. Tell Philip. |
| Label log: "has no boxes yet" | The photo is still on pass 1. Draw its boxes in Roboflow. |
| Label log: "the boxes changed in Roboflow since it was labelled" | Someone edited its boxes after labelling. Label it again. |
| Sync says the numbers do not match | Press Sync again. Nothing was deleted. |
| "Someone saved this while you had it open" | Close the day, open it again and redo your change. |
Not built yet: how the March and June photos are split, so do not upload those yet; removing the workflow tags from approved photos; and picking the random one in ten of the low risk photos for you.