This dashboard visualizes a 15-second classroom video, coded second-by-second by Gemini 3.1 Pro into eight observable student behaviors. The video comes from a paper which created and annotated a classroom video dataset for group engagement recognition and demonstrated how existing computer vision models perform on it.
Instead of tagging every second, the model reports when each activity starts and stops - emitting one row per contiguous event, along with how many students were involved and a short note on the visual evidence. It uses the same eight activity types on the same clip, so the totals below are directly comparable to the per-second Overview tab.
Gemini's event output (see the "Event-Triggered Data" tab) was checked by hand against the 15-second source video, one event at a time. For each of the 11 events, two things were verified: its timing - whether the start and end second matched what's visible - and its participation - whether the students-at-start, minimum, maximum, and participation-pattern fields matched what's visible.
Each event was marked Correct when every field matched, Partially Correct when some fields were off (e.g. the participant count was slightly over- or under-stated), or Incorrect when the timing or participant count was substantially wrong, or when the reviewer determined the event never actually happened. One correction came with a note instead of a field change - visible in the "Event-Triggered Validation Data" tab - explaining a nuance the raw fields couldn't capture.
One limitation applies to the student-level totals shown throughout this dashboard: only the aggregate participant counts were re-verified per event, not the specific roster of student IDs. So when a count was corrected downward (e.g. Event 9's Smiling), the duration correction is still applied to everyone originally listed on that event, since there's no way to know from the counts alone which specific student(s) the correction refers to.
{
"type": "object",
"properties": {
"events": {
"type": "array",
"description": "Distinct observable activity events ordered by start_second and then by event_id. This must not be a second-by-second timeline.",
"items": {
"type": "object",
"properties": {
"event_id": { "type": "integer", "description": "Sequential event number beginning with 1." },
"activity": {
"type": "string",
"enum": ["Listening_to_Lecture","Note_Taking","One_to_One_Discussion","Group_Discussion","Using_Phone","Looking_Away","Handling_Materials","Hand_Raised","Answering_Question","Standing","Away_From_Desk","Smiling","Other","Unknown"]
},
"start_second": { "type": "integer", "description": "First whole second at which the event is clearly observable." },
"end_second": { "type": "integer", "description": "Final whole second at which the event remains clearly observable." },
"start_timestamp": { "type": "string", "description": "Event start time in MM format." },
"end_timestamp": { "type": "string", "description": "Event end time in MM format." },
"duration_seconds": { "type": "integer", "description": "Inclusive duration calculated as end_second minus start_second plus 1." },
"students_at_start": { "type": "integer", "description": "Number of students visibly participating when the event begins." },
"minimum_students": { "type": "integer", "description": "Smallest number of visibly participating students during the event." },
"maximum_students": { "type": "integer", "description": "Largest number of visibly participating students during the event." },
"participation_pattern": {
"type": "string",
"enum": ["stable","increased","decreased","varied"],
"description": "How the number of participating students changed during the event."
},
"student_ids": {
"type": "array",
"description": "Anonymous identifiers for students who participated in the event when reliable tracking was possible. Return an empty array when reliable identification was not possible.",
"items": { "type": "string" }
},
"confidence": {
"type": "string",
"enum": ["high","medium","low"],
"description": "Confidence in the activity classification, timestamps, and student count."
},
"evidence": { "type": "string", "description": "Brief, objective description of the visible or audible evidence supporting the event classification." },
"event_limitations": { "type": "string", "description": "Event-specific uncertainty caused by occlusion, image quality, camera angle, uncertain counts, or similar limitations. Use an empty string when no specific limitation applies." }
},
"required": ["event_id","activity","start_second","end_second","start_timestamp","end_timestamp","duration_seconds","students_at_start","minimum_students","maximum_students","participation_pattern","student_ids","confidence","evidence","event_limitations"]
}
},
"activity_summaries": {
"type": "array",
"description": "One summary record for every defined activity, including activities with zero detected events.",
"items": {
"type": "object",
"properties": {
"activity": {
"type": "string",
"enum": ["Listening_to_Lecture","Note_Taking","One_to_One_Discussion","Group_Discussion","Using_Phone","Looking_Away","Handling_Materials","Hand_Raised","Answering_Question","Standing","Away_From_Desk","Smiling","Other","Unknown"]
},
"event_count": { "type": "integer", "description": "Number of distinct events detected for this activity." },
"total_duration_seconds": { "type": "integer", "description": "Sum of duration_seconds across all events of this activity. Overlapping events may cause totals across activities to exceed the video duration." },
"average_event_duration_seconds": { "type": "number", "description": "Average duration of events of this activity. Return 0 when event_count is 0." },
"minimum_event_duration_seconds": { "type": "integer", "description": "Duration of the shortest event of this activity. Return 0 when event_count is 0." },
"maximum_event_duration_seconds": { "type": "integer", "description": "Duration of the longest event of this activity. Return 0 when event_count is 0." },
"largest_student_count": { "type": "integer", "description": "Largest maximum_students value among events of this activity. Return 0 when event_count is 0." },
"total_student_event_participations": { "type": "integer", "description": "Sum of maximum_students across events of this activity. This is not a count of unique students." }
},
"required": ["activity","event_count","total_duration_seconds","average_event_duration_seconds","minimum_event_duration_seconds","maximum_event_duration_seconds","largest_student_count","total_student_event_participations"]
}
},
"student_summaries": {
"type": "array",
"description": "Student-level summaries included only for students who could be tracked with sufficient reliability.",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "description": "Anonymous student identifier." },
"activities": {
"type": "array",
"items": {
"type": "object",
"properties": {
"activity": {
"type": "string",
"enum": ["Listening_to_Lecture","Note_Taking","One_to_One_Discussion","Group_Discussion","Using_Phone","Looking_Away","Handling_Materials","Hand_Raised","Answering_Question","Standing","Away_From_Desk","Smiling","Other","Unknown"]
},
"event_count": { "type": "integer", "description": "Number of distinct events of this activity in which the student participated." },
"total_event_duration_seconds": { "type": "integer", "description": "Sum of the full durations of events of this activity in which the student participated." }
},
"required": ["activity","event_count","total_event_duration_seconds"]
}
}
},
"required": ["id","activities"]
}
},
"metadata": {
"type": "object",
"properties": {
"video_duration_seconds": { "type": "integer", "description": "Approximate total duration of the analyzed video in whole seconds." },
"average_students_visible": { "type": "number", "description": "Average number of visible students estimated through internal sampling at approximately one-second intervals." },
"maximum_students_visible": { "type": "integer", "description": "Largest number of students visible at one time." },
"reliable_tracking": { "type": "boolean", "description": "Whether students could be assigned consistent anonymous identifiers throughout most of the video." },
"tracking_notes": { "type": "string", "description": "Explanation of student-tracking reliability, including use of temporary identifiers." },
"event_gap_rule_seconds": { "type": "integer", "description": "Maximum interruption that was merged into the same event. This should normally equal 1." },
"limitations": { "type": "array", "description": "Video-level limitations affecting interpretation, counting, timing, or tracking.", "items": { "type": "string" } }
},
"required": ["video_duration_seconds","average_students_visible","maximum_students_visible","reliable_tracking","tracking_notes","event_gap_rule_seconds","limitations"]
}
},
"required": ["events","activity_summaries","student_summaries","metadata"]
}
Gemini's per-second, per-student output (see the "Data" tab) was checked by hand against the 15-second source video, one observation at a time. For every one of the 90 (second, student) rows in the timeline, two things were verified: whether the model's Students Present count matched what's actually visible on screen, and whether each activity label assigned to that student matched what they were actually doing.
Each row was marked Correct when it matched the video exactly, Partially Correct when the model got part of it right but missed or added a label (e.g. caught the group discussion but missed that the student was also smiling), Incorrect when a label or headcount didn't match what's visible, or Other for edge cases that didn't fit those buckets (e.g. a student moving quickly through frame). Many corrections include a short note explaining the specific discrepancy - those are visible in the "Validation Data" tab, color-coded green / yellow / red / gray to match this scheme.
One general limitation applies across the whole clip: Gemini counted 8 total students, while there are only 7 total students in the video. The model got confused by students coming on and off screen, and double-counted one of those students.
{
"type": "object",
"properties": {
"timeline": {
"type": "array",
"items": {
"type": "object",
"properties": {
"second": { "type": "integer" },
"students_present": { "type": "integer" },
"students": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"activities": {
"type": "array",
"items": {
"type": "string",
"enum": ["Listening_to_Lecture","Note_Taking","One_to_One_Discussion","Group_Discussion","Using_Phone","Looking_Away","Handling_Materials","Hand_Raised","Answering_Question","Standing","Away_From_Desk","Smiling","Other","Unknown"]
}
}
},
"required": ["id","activities"]
}
}
},
"required": ["second","students_present","students"]
}
},
"activity_totals": {
"type": "array",
"items": {
"type": "object",
"properties": {
"activity": {
"type": "string",
"enum": ["Listening_to_Lecture","Note_Taking","One_to_One_Discussion","Group_Discussion","Using_Phone","Looking_Away","Handling_Materials","Hand_Raised","Answering_Question","Standing","Away_From_Desk","Smiling","Other","Unknown"]
},
"seconds": { "type": "integer" }
},
"required": ["activity","seconds"]
}
},
"student_summaries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"activities": {
"type": "array",
"items": {
"type": "object",
"properties": {
"activity": {
"type": "string",
"enum": ["Listening_to_Lecture","Note_Taking","One_to_One_Discussion","Group_Discussion","Using_Phone","Looking_Away","Handling_Materials","Hand_Raised","Answering_Question","Standing","Away_From_Desk","Smiling","Other","Unknown"]
},
"seconds": { "type": "integer" }
},
"required": ["activity","seconds"]
}
}
},
"required": ["id","activities"]
}
},
"metadata": {
"type": "object",
"properties": {
"average_students_visible": { "type": "number" },
"reliable_tracking": { "type": "boolean" },
"limitations": { "type": "string" }
},
"required": ["average_students_visible","reliable_tracking","limitations"]
}
},
"required": ["timeline","activity_totals","student_summaries","metadata"]
}