Annotations & video¶
Three smaller CSV formats: detections on still imagery, the video navigation log, and per-frame video annotations.
Image annotation CSV¶
HabCam.imageannotation — the detector output overlaid on the imagery by the
Image Browser and edited by the
annotation editor.
The file is read positionally, not by header name. GroundTruther skips any leading blank or comment lines, drops a header row if there is one, and then assigns its own names to the eleven columns, in order:
| # | GroundTruther's name | Meaning |
|---|---|---|
| 1 | Detection |
Detection id. |
| 2 | Imagename |
Image the detection belongs to. A trailing .jpg is stripped, so the value joins against the metadata table's Imagename either way. |
| 3 | Frame_Identifier |
Frame counter from the detector. |
| 4 | TL_x |
Bounding box, top-left x, in image pixels. |
| 5 | TL_y |
Bounding box, top-left y. |
| 6 | BR_x |
Bounding box, bottom-right x. |
| 7 | BR_y |
Bounding box, bottom-right y. |
| 8 | detection_Confidence |
A second confidence value from the detector. Not used for filtering. |
| 9 | Target_Length |
Measured target length. Not read by the plugin. |
| 10 | Species |
The label string shown on the box and tallied in the metadata panel. |
| 11 | Confidence |
The value the confidence threshold filters on. |
Columns 4–7 and 11 are coerced to numbers; unparseable values become NaN.
Rows are then grouped by Imagename, so one image carries parallel lists of
boxes, species and confidences. The box itself is stored as a closed
four-corner ring — (TL_x, BR_y) → (BR_x, BR_y) → (BR_x, TL_y) → (TL_x, TL_y).
A file from the sample dataset looks like this — note that the header names differ from GroundTruther's internal names but the order matches:
id,Imagename,frame_id,TL_x,TL_y,BR_x,BR_y,detection_length_confidence,target_length,species,detection_confidence
9,201503.20150619.181142496.204638.jpg,8,123.0,306.0,182.0,374.0,0.231257,0,fish,0.231257
15,201503.20150619.181143331.204643.jpg,12,422.875,325.125,584.375,567.375,0.335472,0,fish,0.335472
The preamble is detected, not assumed
GroundTruther accepts the file however it arrives: with a header row or
without, and with any number of blank or #-commented banner lines in front
of it. A header is recognised by its bounding-box columns failing to parse as
numbers, so a detection with one damaged coordinate is still read as a
detection. Every row is kept — the sample dataset's
test_detector_output.csv loads all 7 278 detections. Which shape was
detected is logged to the GroundTruther message-log tab.
The reader used to be fixed at skiprows=[0, 1], which lost the first
detection of a single-header file and turned the header of GroundTruther's own
save into a phantom annotation
(#28). Files written by
that older version — two blank lines, then the header — still load correctly.
The confidence threshold spin box in the Image Browser hides any box whose
Confidence is below the value; the filter is inclusive (>=) and is shared
with the annotation editor.
Video metadata CSV¶
Video.videometadata — the navigation log that geo-links the
Video Player to the map.
GroundTruther reads the cruise-survey export format: degrees-plus-decimal- minutes with hemisphere letters, one row per logged observation. Column names are matched by name (surrounding whitespace is stripped first, because the instrument software pads them), and any column that is absent simply comes through empty.
| Source column | Meaning |
|---|---|
Cruise, Superstation, Station |
Survey identifiers. |
Videoseqence |
The sequence number that becomes frame_index. (Spelled exactly like that.) |
Date, Time |
Parsed together with the format %d.%m.%Y %H:%M:%S — e.g. 19.06.2015 18:11:40. A value in any other format becomes NaT. |
LatDeg, LatMin, NorthSouth |
Vessel latitude in DDM + hemisphere (N/S). |
LonDeg, LonMin, EastWest |
Vessel longitude in DDM + hemisphere (E/W). |
Depth |
Water depth, metres. |
Bottom, Biology, Comments |
Free-text observations. |
CP_LatDeg, CP_LatMin, CP_NorthSouth |
Camera-platform latitude in DDM. |
CP_LonDeg, CP_LonMin, CP_EastWest |
Camera-platform longitude in DDM. |
CP_Altitude, CP_Depth, CP_MeanAlt |
Camera-platform altitude, depth and mean altitude. |
After loading, the plugin works with this normalised frame, indexed by
frame_index:
frame_index, timestamp, latitude, longitude, depth, bottom,
biology, comments, cruise, superstation, station, cp_latitude,
cp_longitude, cp_altitude, cp_depth, cp_mean_alt
latitude / longitude are signed decimal degrees, converted from DDM on load
(S and W become negative). They are what the KD-tree is built on and what the
map marker and GPS-track layer use.
The player's metadata panel shows: Sequence (frame_index), Date/Time
(timestamp), Latitude, Longitude, Depth (m), Altitude
(cp_mean_alt), Bottom, Biology, Cruise, Station, Comments.
frame_index is a sequence number, not a video frame number
Videoseqence counts logged observations, not decoded video frames. A helper
(compute_frame_indices) can estimate the true video frame from elapsed time
× FPS when the two do not line up; it adds a derived video_frame column and
does not change anything in your file.
Video annotation CSV¶
Video.videoannotation — per-frame bounding boxes for the video player. This one
is read by header name, and it is the format the annotation editor writes
back, so it round-trips.
| Column | Type | Meaning |
|---|---|---|
frame_index |
int | Must match a frame_index in the video metadata. |
bboxes |
JSON string | List of [x0, y0, x1, y1] pixel boxes. |
species |
JSON string | List of label strings — same length as bboxes. |
confidences |
JSON string | List of floats — same length as bboxes. |
frame_index,bboxes,species,confidences
1204,"[[10,20,100,80],[200,150,320,280]]","[""Porifera"",""Echinodermata""]","[0.95,0.87]"
A row whose JSON does not parse, or which is missing one of the three columns, is
skipped silently — check the row count in the message log
(Video annotations loaded: N frames) if boxes are missing.
Saving from the editor rewrites the whole file, sorted by frame_index, with
exactly these four columns.