diff --git a/.DS_Store b/.DS_Store index 7ee8ac8..5a8002c 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/Dataset/.DS_Store b/Dataset/.DS_Store new file mode 100644 index 0000000..308107c Binary files /dev/null and b/Dataset/.DS_Store differ diff --git a/amelia.json b/amelia.json new file mode 100644 index 0000000..a35f057 --- /dev/null +++ b/amelia.json @@ -0,0 +1,200 @@ +{ + "name": "proj 1", + "fps": 30, + "annotation_path": "/Users/ameliayuan/Documents/ped-behavior-annotator/amelia.json", + "video_path": "https://www.youtube.com/watch?v=eu4QqwsfXFE", + "multiFrameAnnotations": [ + { + "frameStart": 5225, + "frameEnd": 5447, + "pedTags": [], + "egoTags": [ + "Distracted driving" + ], + "sceneTags": [ + "No traffic lights" + ], + "additionalNotes": "Vehicle stopped but started to pull forward right as pedestrian walked towards its path" + }, + { + "frameStart": 4980, + "frameEnd": 5128, + "pedTags": [ + "Jaywalking" + ], + "egoTags": [], + "sceneTags": [], + "additionalNotes": "Vehicle swerves to avoid person, person is hidden behind vehicle by curb as they begin crossing the street" + }, + { + "frameStart": 8518, + "frameEnd": 8778, + "pedTags": [ + "Flinch", + "No Looking" + ], + "egoTags": [], + "sceneTags": [], + "additionalNotes": "Pedestrian almost walked into path of incoming light rail train" + }, + { + "frameStart": 8901, + "frameEnd": 8923, + "pedTags": [ + "Jaywalking" + ], + "egoTags": [], + "sceneTags": [], + "additionalNotes": "Pedestrian in middle of road, very dark, vehicle swerved to avoid" + }, + { + "frameStart": 7571, + "frameEnd": 7727, + "pedTags": [ + "Flinch", + "Distracted" + ], + "egoTags": [ + "Speeding" + ], + "sceneTags": [ + "No stop signs", + "No traffic lights" + ], + "additionalNotes": "Vehicle did not stop at crosswalk for already crossing pedestrian, pedestrian jumped back to avoid getting hit" + }, + { + "frameStart": 5588, + "frameEnd": 5654, + "pedTags": [ + "Crash" + ], + "egoTags": [ + "Distracted driving" + ], + "sceneTags": [ + "No stop signs", + "No traffic lights" + ], + "additionalNotes": "The car did not stop at the crosswalk even though there were pedestrians clearly there" + }, + { + "frameStart": 4771, + "frameEnd": 4907, + "pedTags": [ + "Jaywalking", + "No Looking" + ], + "egoTags": [ + "Brake" + ], + "sceneTags": [ + "No stop signs", + "No traffic lights" + ], + "additionalNotes": "" + }, + { + "frameStart": 9002, + "frameEnd": 12480, + "pedTags": [ + "Flinch" + ], + "egoTags": [ + "Distracted driving", + "Speeding" + ], + "sceneTags": [], + "additionalNotes": "Vehicle did not stop at crosswalk, person flinched back to avoid" + }, + { + "frameStart": 5793, + "frameEnd": 5902, + "pedTags": [ + "Crash" + ], + "egoTags": [ + "Distracted driving" + ], + "sceneTags": [ + "No stop signs", + "No traffic lights" + ], + "additionalNotes": "Vehicle did not stop at crosswalk, pedestrian was already crossing" + }, + { + "frameStart": 6848, + "frameEnd": 7029, + "pedTags": [], + "egoTags": [], + "sceneTags": [ + "No traffic lights", + "No stop signs" + ], + "additionalNotes": "Pedestrian attempted to cross road, cars on half of the road did not stop for the pedestrian, so they retreated back to the sidewalk and waited" + }, + { + "frameStart": 6612, + "frameEnd": 6720, + "pedTags": [ + "Crash" + ], + "egoTags": [], + "sceneTags": [], + "additionalNotes": "vehicle did not stop at crosswalk, pedestrian was already walking" + }, + { + "frameStart": 6428, + "frameEnd": 6534, + "pedTags": [], + "egoTags": [ + "Speeding" + ], + "sceneTags": [], + "additionalNotes": "Vehicle hit from behind by a vehicle speeding that didn't brake for the crosswalk" + }, + { + "frameStart": 7303, + "frameEnd": 7427, + "pedTags": [], + "egoTags": [], + "sceneTags": [ + "No stop signs", + "No traffic lights" + ], + "additionalNotes": "Vehicle did not stop at crosswalk for already crossing pedestrians, pedestrians waited in the middle of the road to let vehicle through" + }, + { + "frameStart": 7895, + "frameEnd": 14408, + "pedTags": [ + "Flinch" + ], + "egoTags": [ + "Brake" + ], + "sceneTags": [ + "No stop signs", + "No traffic lights" + ], + "additionalNotes": "Cars braked last-minute at crosswalk, pedestrian retreated back onto sidewalk before crossing again" + }, + { + "frameStart": 8305, + "frameEnd": 8448, + "pedTags": [ + "Crash", + "Flinch" + ], + "egoTags": [ + "Brake" + ], + "sceneTags": [ + "No stop signs", + "No traffic lights" + ], + "additionalNotes": "Vehicle paused, then appeared to get lurch forward from behind perhaps from another car crashing, then hit the pedestrians" + } + ], + "singleFrameAnnotations": [] +} \ No newline at end of file diff --git a/app.py b/app.py index 1b2c44f..eaa2125 100644 --- a/app.py +++ b/app.py @@ -95,10 +95,13 @@ def makeEditor(self): # self.videoFrame.Text("Video") # self.leftFrame.Seperator() - self.annotationFrame = self.leftFrame.addLabelFrame("Annotation Edit View", padx=(0,0), pady=(10,0)) - self.annotationEditView = self.viewManager.getAnnotationEditView(self.recordingController) - #self.context["controllers"]["recording"]) - self.annotationEditView.render(self.annotationFrame) + # self.annotationFrame = self.leftFrame.addLabelFrame("Annotation Edit View", padx=(0,0), pady=(10,0)) + # self.annotationEditView = self.viewManager.getAnnotationEditView(self.recordingController) + # #self.context["controllers"]["recording"]) + # self.annotationEditView.render(self.annotationFrame) + self.behaviorTagFrame = self.leftFrame.addLabelFrame("Behavior Tag Frame", padx=(0,0), pady=(10,0)) + self.behaviorTagView = self.viewManager.getBehaviorTagView() + self.behaviorTagView.render(self.behaviorTagFrame) self.recordingFrame = self.rightFrame.addFrame("Recording", padx=(0,0), pady=(10,0)) self.recordingView = self.viewManager.getRecordingView(self.recordingController) diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000..a71a321 Binary files /dev/null and b/docs/.DS_Store differ diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/UI.pptx b/docs/UI.pptx deleted file mode 100644 index f99a794..0000000 Binary files a/docs/UI.pptx and /dev/null differ diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..dc1312a --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..19907e4 Binary files /dev/null and b/docs/requirements.txt differ diff --git a/docs/source/.DS_Store b/docs/source/.DS_Store new file mode 100644 index 0000000..e119492 Binary files /dev/null and b/docs/source/.DS_Store differ diff --git a/docs/source/_static/css/custom.css b/docs/source/_static/css/custom.css new file mode 100644 index 0000000..c900bf4 --- /dev/null +++ b/docs/source/_static/css/custom.css @@ -0,0 +1,18 @@ +@import 'theme.css'; + +ol { + list-style: decimal; +} + +ol.simple { + list-style: decimal; + margin-left: 2em; +} + +ul.simple { + margin-left: 1em; +} + +ol.simple > li { + list-style: decimal; +} \ No newline at end of file diff --git a/docs/source/additional-pedestrian-archetype-evidence.md b/docs/source/additional-pedestrian-archetype-evidence.md new file mode 100644 index 0000000..9ab105b --- /dev/null +++ b/docs/source/additional-pedestrian-archetype-evidence.md @@ -0,0 +1,57 @@ +# Additional Pedestrian Archetype Evidence + +We didn't have enough space in our paper to include many examples, so we've included them here for further evidence of our archetypes. + +## Wanderer +Wanderers show diverse behaviors. In [1], a pedestrian runs towards an oncoming vehicle, forcing it to stop, and climbs onto the hood. In [2], another dances on the highway, stopping traffic. When intoxicated, wanderers become even more dangerous, rapidly changing direction or speed [3]. + +[1] DDPAI Global, “Drunk Drivers and Pedestrians Compilation - DDPAI Dash Cam,” [Online]. Available https://youtu.be/YuofxA63faE?si=INYkx5uGrtoE-lQT&t=284, 2023, Youtube@DDPAI Global, Accessed: 2024-04-28. + +[2] ——, “Drunk Drivers and Pedestrians Compilation - DDPAI Dash Cam,” [Online]. Available https://youtu.be/YuofxA63faE?si=Kt-2aZNSuE5H-OY&t=440, 2023, Youtube@DDPAI Global, Accessed: 2024-04-28. + +[3] DriveStart, “Drunk Pedestrian Fail Compilation,” [Online]. Available https://youtu.be/qGs9KAwzneg?si=yTFDbcJeQ2WfQADk&t=35, 2023, youtube@DriveStartTV, Accessed: 2024-04-28. + +## Drunk + +In [2], another pedestrian stands outside the highway lanes and suddenly falls on their back, unintentionally stum- bling into the driving lane. With no intention or action to cross, the drunk still manages to risk colliding with high-speed vehicles. Like the wanderer, the drunk comes in many forms. In video [3], [4], the drunk crosses by crawling (using legs and hands). In video [5], the drunk walks blindly and crashes into the midsection of a moving bus. In [1], they wander along the driving lane. + +[1] DriveStart, “Drunk Pedestrian Fail Compilation,” [Online]. Available https://youtu.be/qGs9KAwzneg?si=yTFDbcJeQ2WfQADk&t=35, 2023, youtube@DriveStartTV, Accessed: 2024-04-28. + +[2] ——, “Drunk Pedestrian Fail Compilation,” [Online]. Available https://youtu.be/qGs9KAwzneg?si=LXuJeQorKb-D3RbZ, 2023, youtube@DriveStartTV, Accessed: 2024-04-28. + +[3] ——, “Drunk Pedestrian Fail Compilation,” [Online]. Available https://youtu.be/qGs9KAwzneg?si=yTFDbcJeQ2WfQADk&t=4, 2023, youtube@DriveStartTV, Accessed: 2024-04-28. + +[4] ——, “Drunk Pedestrian Fail Compilation,” [Online]. Available https://youtu.be/qGs9KAwzneg?si=yTFDbcJeQ2WfQADk&t=66, 2023, youtube@DriveStartTV, Accessed: 2024-04-28. + +[5] ——, “Drunk Pedestrian Fail Compilation,” [Online]. Available https://youtu.be/qGs9KAwzneg?si=yTFDbcJeQ2WfQADk&t=60, 2023, youtube@DriveStartTV, Accessed: 2024-04-28. + +## Blind +In [1], while crossing, the pedestrian listens to music and plays with their phone. The approaching vehicle honks at them, but they do not budge from their path. Without noticing the surroundings, they cross a four-lane road on a green signal. Such behavior is often common in rare scenarios [2], [3]. + +[1] ——, “Pedestrians on the road, on footpaths and beyond —— Cars Accidents,” [Online]. Available https://youtu.be/YuofxA63faE?si=nDT-2i9DCn1vVH-e&t=468, 2023, youtube@carsaccidentsTBl, Accessed: 2024-04-28. + +[2] ——, “Pedestrians on the road, on footpaths and beyond —— Cars Accidents,” [Online]. Available https://youtu.be/YuofxA63faE?si=PRxJAtYN97MNKX9T&t=47, 2023, youtube@carsaccidentsTBl, Accessed: 2024-04-28. + +[3] ——, “Pedestrians on the road, on footpaths and beyond —— Cars Accidents,” [Online]. Available https://youtu.be/YuofxA63faE?si=PRxJAtYN97MNKX9T&t=30, 2023, youtube@carsaccidentsTBl, Accessed: 2024-04-28. + +## Flock +In [1], one flock member leaves others behind, scared by the approaching vehicle. One wants to continue crossing in [2], but the other drags them and retreats off the road. In [3], one of the two pedestrians crosses the road, and the other retreats to the previous lane. Things get more complicated when the flock is on scooters and violates the signal on high-speed roads [4]. + +[1] RoyalJordanian, “The Ultimate Pedestrian Compilation,” [Online]. Available https://youtu.be/PHg3HDg9z3Y?si=8A4u4sYAxOBfba4R&t=57, 2023, youtube@royaljordanian, Accessed: 2024-04-28. + +[2] ——, “The Ultimate Pedestrian Compilation,” [Online]. Available https://youtu.be/PHg3HDg9z3Y?si=8A4u4sYAxOBfba4R&t=72, 2023, youtube@royaljordanian, Accessed: 2024-04-28. + +[3] ——, “The Ultimate Pedestrian Compilation,” [Online]. Available https://youtu.be/PHg3HDg9z3Y?si=SF5sWwZwCATPn7pb&t=92, 2021, youtube@royaljordanian, Accessed: 2024-04-28. + +[4] I haz Dashcam, “Dumb Pedestrians,” [Online]. Available https://youtu.be/KSfOL61HYoM?si=tfdtOzwPGydw1aik&t=229, 2023, youtube@ihazdashcam, Accessed: 2024-04-28. + +## Eventful +Pedestrians can also drop items on the road [1], [2]. In [2], a kid crossing with a group drops one of their sandals on the road and falls behind the group. Occluded pedestrians can unexpectedly appear anywhere on the road [3], [4]. While in more common scenarios, occluded pedestrians appear from around a stopped vehicle, in [4], we see an event when the occluded pedestrian appears from the front of a high-speed vehicle moving at over 40 mph! + +[1] Cars Accidents, “Pedestrians on the road, on footpaths and beyond —— Cars Accidents,” [Online]. Available https://youtu.be/YuofxA63faE?si=PRxJAtYN97MNKX9T&t=30, 2023, youtube@carsaccidentsTBl, Accessed: 2024-04-28. + +[2] RoyalJordanian, “The Ultimate Pedestrian Compilation,” [Online]. Available https://youtu.be/PHg3HDg9z3Y?si=61HickVTkx0LYTUy&t=473, 2021, youtube@royaljordanian, Accessed: 2024-04-28. + +[3] Cars Accidents, “Pedestrians on the road, on footpaths and beyond —— Cars Accidents,” [Online]. Available https://youtu.be/YuofxA63faE?si=BoWWlfozNJZKqGC&t=495, 2023, youtube@carsaccidentsTBl, Accessed: 2024-04-28. + +[4] I haz Dashcam, “Dumb Pedestrians,” [Online]. Available https://youtu.be/KSfOL61HYoM?si=NYw5Fr8ZnUbFeGwa&t=74, 2023, youtube@ihazdashcam, Accessed: 2024-04-28. \ No newline at end of file diff --git a/docs/source/advanced-user-guide.md b/docs/source/advanced-user-guide.md new file mode 100644 index 0000000..c264103 --- /dev/null +++ b/docs/source/advanced-user-guide.md @@ -0,0 +1,8 @@ +# Advanced User Guide + +## Editing annoations + +## Merging annotations + +## Adding a new Behavior Tag + diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..b088190 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,76 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'PedAnalyze' +copyright = '2024, Taorui Huang, Golam Md Muktadir, Srishti Sripada, Rishi Saravanan, Amelia Yuan, Jim Whitehead' +author = 'Taorui Huang, Golam Md Muktadir, Srishti Sripada, Rishi Saravanan, Amelia Yuan, Jim Whitehead' +release = '1.0.0' + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. + +extensions = [ + 'myst_parser', + 'sphinx.ext.autosectionlabel', + 'sphinx_rtd_theme', + 'sphinx.ext.autodoc', + 'sphinx.ext.coverage', + 'sphinx.ext.napoleon' + ] +autosectionlabel_prefix_document = True + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] +# html_css_files = [ +# 'css/custom.css', +# ] +html_style = 'css/custom.css' + +myst_enable_extensions = [ + "amsmath", + "colon_fence", + "deflist", + "dollarmath", + "html_admonition", + "html_image", + "linkify", + "replacements", + "smartquotes", + "substitution", + "tasklist", +] + + + +language = "en" +myst_html_meta = { + "description lang=en": "PedAnalyze", + "keywords": "Pedestrian Behavior Annotation", + "property=og:locale": "en_US" +} diff --git a/docs/source/dev-guide.md b/docs/source/dev-guide.md new file mode 100644 index 0000000..b4e44bd --- /dev/null +++ b/docs/source/dev-guide.md @@ -0,0 +1,7 @@ +# Developer Guide + + \ No newline at end of file diff --git a/docs/source/environment-condition-tags.md b/docs/source/environment-condition-tags.md new file mode 100644 index 0000000..0394d0d --- /dev/null +++ b/docs/source/environment-condition-tags.md @@ -0,0 +1,10 @@ +# Environment Condition Tags + +| Condition | Explanation | +| ----------- | ----------- | +| **Time & weather** | Day, night, sunny, foggy, cloudy, snowy, etc | +| **Traffic lights** | None, green, yellow, blinking yellow, red | +| **Road signs** | Stop signs, crossing signs, etc | +| **Location** | Crosswalk, no crosswalk | +| **Traffic** | Light, moderate, heavy, one-way, two-way | +| **Visibility** | Occluded pedestrian, glare on windshield, rainy or foggy | \ No newline at end of file diff --git a/docs/source/getting-started.md b/docs/source/getting-started.md new file mode 100644 index 0000000..4b50028 --- /dev/null +++ b/docs/source/getting-started.md @@ -0,0 +1,11 @@ +# Getting Started + +We have moved our PedAnalyze (pedestrian behavior annotation) from our Python Tkinter-based software to the web for easier access and operations. Please access the new annotator here: https://pedanalyze.glitch.me/ + +Ignore the previous instructions below: +1. Install +2. Run the application +3. Load a youtube video +4. Create a single frame annotation +5. Create a multiframe annotation +6. Save the data \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..7f3719a --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,31 @@ +.. PedAnalyze documentation master file, created by + sphinx-quickstart on Sun Apr 7 10:24:26 2024. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to PedAnalyze's documentation! +====================================== + +.. toctree:: + :numbered: + :maxdepth: 2 + :caption: Contents: + + getting-started.md + installation.md + additional-pedestrian-archetype-evidence.md + pedestrian-archetype-optional-behaviors.md + pedestrian-behavior-tags.md + vehicle-behavior-tags.md + environment-condition-tags.md + pedestrian-demographics.md + key-concepts.md + advanced-user-guide.md + dev-guide.md + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/installation.md b/docs/source/installation.md new file mode 100644 index 0000000..5471d9d --- /dev/null +++ b/docs/source/installation.md @@ -0,0 +1,12 @@ +# Installation Guide + +## Install Dependencies via environment.yaml + +Run in terminal: +``` +conda env create -f environment.yml + +conda env update --file conda.yaml --prune + +conda activate pedanno +``` \ No newline at end of file diff --git a/docs/source/key-concepts.md b/docs/source/key-concepts.md new file mode 100644 index 0000000..2c30009 --- /dev/null +++ b/docs/source/key-concepts.md @@ -0,0 +1,18 @@ +# User Guide - Main Features + +## Pre-defined tags +Pre-defined behavior tags are split into four categories: pedestrian behavior, vehicle behavior, environment conditions, and pedestrian demographics. They are accessible in the AnnotationEditView, in the form of check boxes, to annotate the behaviors and conditions in each frame or group of frames. Using pre-defined tags allows for unity across annotations and resulting data sets and makes it easier to identify patterns or common pedestrian-vehicle interaction scenarios. + +## Multi-frame annotation +![Data Model of a Video Recording](multiframe-annotation.png) +Multi-frame annotation describes pedestrian behavior seen across a sequence of frames. + +## Public video annotation +PedAnalyze makes it possible to annotate public videos of pedestrian-vehicle accidents or near-miss scenarios stored on the internet, generally posted on platforms such as YouTube or Instagram. On these platforms, there exists an abundance of footage that the public has already organized into compilations. By directly supporting YouTube links, and direct access to videos on other social media platforms coming in the future, PedAnalyze is able to access this useful yet untapped set of pre-compiled interactions and provide a tool to easily identify and annotate behaviors. + +## Structure of the dataset +![Data Model of a Video Recording](data-model.png) + +The behavior tags for pedestrian decision-making are inspired by YouTube video observations, PSI Dataset annotations, and various factors influencing pedestrian crossing decisions. The tags are categorized into four main types: Pedestrian Behaviors, Vehicle Behaviors, Environment Conditions, and Pedestrian Demographics. These categories help describe key interactions and context factors in multi-frame scenes. + +Pedestrian behavior tags are further divided into subsets like Instant Reaction, Collision, Interaction, Mental State, and Intention. Vehicle behavior tags include subsets like Collision, Interaction, and Irregular phenomena. The tagging system is designed to be intuitive and scalable, incorporating ideas from existing literature to enhance pedestrian behavior analysis. \ No newline at end of file diff --git a/docs/source/pedestrian-archetype-optional-behaviors.md b/docs/source/pedestrian-archetype-optional-behaviors.md new file mode 100644 index 0000000..8cc5b7a --- /dev/null +++ b/docs/source/pedestrian-archetype-optional-behaviors.md @@ -0,0 +1,66 @@ +# Pedestrian Archetype Optional Behaviors + +## Wanderer +Not-sure-cross + +## Drunk +Crawling\ +Dancing\ +Crosswalk detour\ +Fall\ +Trip + +## Distracted +Gesturing\ +Back turned + +## Flash +Fixated not at incoming vehicle\ +Flinch-in\ +Flinch-out\ +Brisk-walking\ +Not looking/glancing + +## Indecisive +Near-miss\ +Not-sure-cross\ +Pause-start + +## Blind +Preoccupied\ +Not looking/glancing + +## Flock +Group-disperse\ +Re-group\ +Cross\ +Not-sure-cross\ +Not-cross + +## Jaywalker +Crosswalk-detour\ +Make-stop (can be observed when cars suddenly stop in front of driver)\ +Near-miss (can be observed when cars suddenly stop in front of driver)\ +Collision + +## Elderly +Cautious + +## Kid +Ignore traffic\ +Not-sure-cross\ +Make-stop\ +Fixated not at incoming vehicle + +## Eventful +Near-miss\ +Make-stop\ +Flinch-in\ +Flinch-out\ +Retreat + +## Parked +Fixated not at incoming vehicle\ +Preoccupied\ +Trip\ +Fall \ No newline at end of file diff --git a/docs/source/pedestrian-behavior-tags.md b/docs/source/pedestrian-behavior-tags.md new file mode 100644 index 0000000..0e632af --- /dev/null +++ b/docs/source/pedestrian-behavior-tags.md @@ -0,0 +1,57 @@ +# Pedestrian Behavior Tags + +| Behavior | Explanation | +| ----------- | ----------- | +| Trip | onto driving lane | +| Fall | onto driving lane | +| Along lane | along a lane instead of crossing | +| Zig-zag | abrupt alternating left or right turns | +| Brisk-walk | walk fast | +| Group-walk | walk in a group | +| Group-disperse | initially together and disperse due to traffic, can mean part of the group crosses and part of the group chooses not to | +| Re-group | the group moves back together | +| Dog-walk | with a dog | +| Retreat | walk backwards | +| Speed-up | sudden change | +| Slow-down | sudden change | +| Pause-start | stop momentarily and proceed afterward | +| Cross-without-crosswalk | not crossing at marked crosswalk, whether that be at a mid-block or over anything | +| Cross-on-red | crossing on red light | +| Drop object | onto driving lane | +| Pickup object | onto driving lane | +| Pop-out occlusion | appears suddenly behind another object | +| Crawling | moving slowly, often on hands and knees | +| Dancing | moving rhythmically or performing dance-like motions | +| Crosswalk-detour | initially on the crosswalk but leaves to take a shortcut | +| Gesturing | using hand or body movements to signal or communicate with anything except incoming vehicle (waving at someone across the street) | +| Back turned | against incoming vehicle | +| Ignore-traffic | ​crossing or walking in front of moving vehicles, ignoring them | +| **Instant Reaction** | | +| Swerve | abrupt change in direction | +| Break | abrupt stop at the lane boundary and yield | +| Flinch out | jump out of ego’s lane | +| Flinch in | jump into the ego’s lane | +| Frozen | stop in the middle of a lane | +| **Collision** | | +| Collision | leading to injury | +| Near-miss | nearly missing a collision | +| Run into traffic | creating near-miss/collision with vehicles | +| Thrown back | thrown backward by vehicle collision | +| **Interaction** | | +| Make stop | gesturing to vehicle to stop | +| Make go | gesturing to vehicle to go | +| Aggression | aggressive gestures to vehicle | +| Assault | assault the vehicle | +| Observing | standing still and observing vehicle’s behavior | +| **Mental State** | | +| Looking | at the oncoming traffic (>1s) | +| Glancing | at the oncoming traffic (<1s) | +| Not looking/glancing | at the oncoming traffic | +| Fixated not at incoming vehicle | Fixating attention at any object except incoming vehicle | +| Preoccupied | performing a task such that attention isn't given to the incoming vehicle | +| Agitated | showing agitation | +| Cautious | showing careful deliberation | +| **Intention** | | +| Cross | intends to cross | +| Not-cross | doesn’t intend to cross | +| Not-sure-cross | not sure if intends to cross | diff --git a/docs/source/pedestrian-demographics.md b/docs/source/pedestrian-demographics.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/source/vehicle-behavior-tags.md b/docs/source/vehicle-behavior-tags.md new file mode 100644 index 0000000..dfa6531 --- /dev/null +++ b/docs/source/vehicle-behavior-tags.md @@ -0,0 +1,21 @@ +# Vehicle Tags + +| Behavior | Explanation | +| ----------- | ----------- | +| Aggressive acceleration | A sudden and forceful increase in speed, often in response to traffic conditions | +| Aggressive brake | A sudden and forceful application of the brakes, often to avoid a collision or to respond to a sudden hazard | +| Gradual acceleration | A smooth and steady increase in speed over a period of time, showing controlled and balanced driving | +| Gradual brake | A controlled and gradual application of the brakes, showing careful and balanced deceleration | +| Slow-reverse | Moving backward slowly, typically when parking or maneuvering in a confined space | +| Quick-reverse | Moving backward quickly, often in response to a sudden need to retreat or change direction | +| Lane change | Changing lanes in a manner that poses a risk to pedestrians who may be hidden from view, such as those behind other vehicles or obstacles | +| Speeding | Driving at a speed that exceeds the posted speed limit or is too fast for the road conditions, increasing the risk of accidents | +| Halt | Coming to a complete stop, often at a stop sign or traffic light | +| **Collision**| | +| Induced collision | Colliding with another object or vehicle to avoid hitting a pedestrian, which can be risky | +| Run-stop | Continuing to drive through a stop sign or red light without stopping, potentially leading to a collision or near-miss | +| Swerve | Making a sudden and sharp change in direction to avoid colliding with a pedestrian or other obstacle | +| **Interaction** | | +| Make go | Allowing a pedestrian to proceed by signaling or yielding the right of way | +| **Irregular** | | +| Sidewalk | Driving on or partially on the sidewalk, which poses a danger to pedestrians | \ No newline at end of file diff --git a/docs/source/visuals/.DS_Store b/docs/source/visuals/.DS_Store new file mode 100644 index 0000000..dd64f1a Binary files /dev/null and b/docs/source/visuals/.DS_Store differ diff --git a/docs/source/visuals/PedGridTutorial1.gif b/docs/source/visuals/PedGridTutorial1.gif new file mode 100644 index 0000000..0d85e25 Binary files /dev/null and b/docs/source/visuals/PedGridTutorial1.gif differ diff --git a/docs/source/visuals/PedGridTutorial1.mov b/docs/source/visuals/PedGridTutorial1.mov new file mode 100644 index 0000000..53ccbf7 Binary files /dev/null and b/docs/source/visuals/PedGridTutorial1.mov differ diff --git a/docs/source/visuals/PedGridTutorial2.gif b/docs/source/visuals/PedGridTutorial2.gif new file mode 100644 index 0000000..f2afa99 Binary files /dev/null and b/docs/source/visuals/PedGridTutorial2.gif differ diff --git a/docs/source/visuals/PedGridTutorial2.mov b/docs/source/visuals/PedGridTutorial2.mov new file mode 100644 index 0000000..593a23a Binary files /dev/null and b/docs/source/visuals/PedGridTutorial2.mov differ diff --git a/docs/source/visuals/PedestrianEnv.png b/docs/source/visuals/PedestrianEnv.png new file mode 100644 index 0000000..71e9159 Binary files /dev/null and b/docs/source/visuals/PedestrianEnv.png differ diff --git a/docs/source/visuals/TwoLaneRoadEnv.png b/docs/source/visuals/TwoLaneRoadEnv.png new file mode 100644 index 0000000..75427e1 Binary files /dev/null and b/docs/source/visuals/TwoLaneRoadEnv.png differ diff --git a/docs/source/visuals/action-space.png b/docs/source/visuals/action-space.png new file mode 100644 index 0000000..e439ada Binary files /dev/null and b/docs/source/visuals/action-space.png differ diff --git a/docs/images/data-model.PNG b/docs/source/visuals/data-model.PNG similarity index 100% rename from docs/images/data-model.PNG rename to docs/source/visuals/data-model.PNG diff --git a/docs/source/visuals/multiframe-annotation.PNG b/docs/source/visuals/multiframe-annotation.PNG new file mode 100644 index 0000000..f9c79d5 Binary files /dev/null and b/docs/source/visuals/multiframe-annotation.PNG differ diff --git a/info-docs/.DS_Store b/info-docs/.DS_Store new file mode 100644 index 0000000..2766186 Binary files /dev/null and b/info-docs/.DS_Store differ diff --git a/info-docs/UI.pptx b/info-docs/UI.pptx new file mode 100644 index 0000000..c79ca85 Binary files /dev/null and b/info-docs/UI.pptx differ diff --git a/info-docs/images/data-model.PNG b/info-docs/images/data-model.PNG new file mode 100644 index 0000000..4359195 Binary files /dev/null and b/info-docs/images/data-model.PNG differ diff --git a/docs/images/youtube-1.png b/info-docs/images/youtube-1.png similarity index 100% rename from docs/images/youtube-1.png rename to info-docs/images/youtube-1.png diff --git a/docs/images/youtube-1.psd b/info-docs/images/youtube-1.psd similarity index 100% rename from docs/images/youtube-1.psd rename to info-docs/images/youtube-1.psd diff --git a/docs/paper-graphics.pptx b/info-docs/paper-graphics.pptx similarity index 100% rename from docs/paper-graphics.pptx rename to info-docs/paper-graphics.pptx diff --git a/docs/~$UI.pptx b/info-docs/~$UI.pptx similarity index 100% rename from docs/~$UI.pptx rename to info-docs/~$UI.pptx diff --git a/managers/ViewManager.py b/managers/ViewManager.py index b498cd7..24923d7 100644 --- a/managers/ViewManager.py +++ b/managers/ViewManager.py @@ -8,6 +8,7 @@ from view.AnnotationEditView import AnnotationEditView from view.VideoView import VideoView from view.TitleView import TitleView +from view.BehaviorTagView import BehaviorTagView from library.AppEvent import * #from view import * class ViewManager: @@ -33,3 +34,8 @@ def getVideoView(self): def getTitleView(self, recordingController: RecordingController): return TitleView(recordingController, self.eventManager, self.viewEventManager) + + def getBehaviorTagView(self): + view = BehaviorTagView(self.eventManager, self.viewEventManager) + #self.eventManager.subscribe(AppEventType.BehaviorTagView, view.handleEvent) + return view diff --git a/readthedocs.yaml b/readthedocs.yaml new file mode 100644 index 0000000..d38594d --- /dev/null +++ b/readthedocs.yaml @@ -0,0 +1,32 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.8" + # You can also specify other tool versions: + # nodejs: "19" + # rust: "1.64" + # golang: "1.19" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/source/conf.py + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: +# - pdf +# - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: docs/requirements.txt \ No newline at end of file diff --git a/tests/.DS_Store b/tests/.DS_Store new file mode 100644 index 0000000..dc4eeee Binary files /dev/null and b/tests/.DS_Store differ diff --git a/theme/.DS_Store b/theme/.DS_Store new file mode 100644 index 0000000..921eb40 Binary files /dev/null and b/theme/.DS_Store differ diff --git a/view/BehaviorTagView.py b/view/BehaviorTagView.py index f6f7e0e..58eb3b6 100644 --- a/view/BehaviorTagView.py +++ b/view/BehaviorTagView.py @@ -25,18 +25,363 @@ def __init__(self, eventManager: EventManager, viewEventManager: ViewEventManage super().__init__() self.eventManager = eventManager self.viewEventManager = viewEventManager - # self.currentAnnotationStartFrame = tk.IntVar(value=0) - # self.currentAnnotationEndFrame = tk.IntVar(value=0) - # self.annotationTypeRadioVar = tk.StringVar(value='Multi') + self.currentAnnotationStartFrame = tk.IntVar(value=0) + self.currentAnnotationEndFrame = tk.IntVar(value=0) + self.annotationTypeRadioVar = tk.StringVar(value='Multi') def handleEvent(self, appEvent: AppEvent): - # if "updateStartFrame" in appEvent.data: - # self.currentAnnotationStartFrame.set(appEvent.data["updateStartFrame"]) - # print(f"updated start frame in the edit view with {appEvent.data['updateStartFrame']} == {self.currentAnnotationStartFrame.get()}") - # if "updateEndFrame" in appEvent.data: - # self.currentAnnotationEndFrame.set(appEvent.data["updateEndFrame"]) - # print("updated end frame in the edit view") - pass + if "updateStartFrame" in appEvent.data: + self.currentAnnotationStartFrame.set(appEvent.data["updateStartFrame"]) + print(f"updated start frame in the edit view with {appEvent.data['updateStartFrame']} == {self.currentAnnotationStartFrame.get()}") + if "updateEndFrame" in appEvent.data: + self.currentAnnotationEndFrame.set(appEvent.data["updateEndFrame"]) + print("updated end frame in the edit view") def render(self, parent: TKMT.WidgetFrame): - pass \ No newline at end of file + # frame information + # self.pedTags: List[PedestrianTag] = [] + # self.egoTags: List[VehicleTag] = [] + # self.sceneTags: List[SceneTag] = [] + self._renderView(parent) + self.resetAnnotation() + + def renderSingleEdit(self, parent: TKMT.WidgetFrame, existingAnnotation: SingleFrameAnnotation): + # you do the same thing, but read information from the existingAnnotation object + self.currentAnnotation = existingAnnotation + self._renderView(parent) + + def _renderView(self, parent: TKMT.WidgetFrame): + # parent.Text("Frame # " + str(self.currentAnnotation.frame)) + # parent.setActiveCol(0) + # self._renderMeta(parent) + + # parent.setActiveCol(0) + # self._renderAnnotationTypeSelector(parent) + + # parent.setActiveCol(0) + # self.pedBehaviorFrame = parent.addLabelFrame("Pedestrian Behavior", padx=(10,10), pady=(10, 0)) + # self._renderPedOptions(self.pedBehaviorFrame) + + # parent.setActiveCol(0) + # self.vehBehaviorFrame = parent.addLabelFrame("Vehicle Behavior", padx=(10,10), pady=(10, 0)) + # self._renderVehicleOptions(self.vehBehaviorFrame) + + # parent.setActiveCol(0) + # self.envBehaviorFrame = parent.addLabelFrame("Environment Behavior", padx=(10,10), pady=(10, 0)) + # self._renderSceneOptions(self.envBehaviorFrame) + + # parent.setActiveCol(0) + # self._renderNotesField(parent) + # self._renderSaveButton(parent) + + self.notebook = parent.Notebook("Behavior Tag View") + + self.tabPedestrianBehavior = self.notebook.addTab("Pedestrian Behavior") + + # Create a canvas + self.canvasPedestrianBehavior = tk.Canvas(self.tabPedestrianBehavior.master) + self.canvasPedestrianBehavior.pack(side="left", fill="both", expand=True) + # Create a vertical scrollbar + scrollbarPedestrianBehavior = ttk.Scrollbar(self.canvasPedestrianBehavior, orient="vertical", command=self.canvasPedestrianBehavior.yview) + scrollbarPedestrianBehavior.pack(side="right", fill="y") + self.canvasPedestrianBehavior.configure(yscrollcommand=scrollbarPedestrianBehavior.set) + # Create a frame to hold widgets + self.innerFramePedestrianBehavior = ttk.Frame(self.canvasPedestrianBehavior) + self.framePedestrianBehavior = TKMT.WidgetFrame(self.innerFramePedestrianBehavior, "Pedestrian Behaviors") + innerFrameIDPedestrianBehavior = self.canvasPedestrianBehavior.create_window((0, 0), window=self.innerFramePedestrianBehavior, anchor="nw") + + # Bind function to configure + self.canvasPedestrianBehavior.bind("", self.on_configure_pedestrian_behavior) + # Call on_configure once to set up the initial scrolling region + self.on_configure_pedestrian_behavior(None) + + # Render checkboxes + self._renderPedOptions(self.framePedestrianBehavior) + + self.tabVehicleBehavior = self.notebook.addTab("Vehicle Behavior") + + # Create a canvas + self.canvasVehicleBehavior = tk.Canvas(self.tabVehicleBehavior.master) + self.canvasVehicleBehavior.pack(side="left", fill="both", expand=True) + # Create a vertical scrollbar + scrollbarVehicleBehavior = ttk.Scrollbar(self.canvasVehicleBehavior, orient="vertical", command=self.canvasVehicleBehavior.yview) + scrollbarVehicleBehavior.pack(side="right", fill="y") + self.canvasVehicleBehavior.configure(yscrollcommand=scrollbarVehicleBehavior.set) + # Create a frame to hold widgets + self.innerFrameVehicleBehavior = ttk.Frame(self.canvasVehicleBehavior) + self.frameVehicleBehavior = TKMT.WidgetFrame(self.innerFrameVehicleBehavior, "Vehicle Behaviors") + innerFrameIDVehicleBehavior = self.canvasVehicleBehavior.create_window((0, 0), window=self.innerFrameVehicleBehavior, anchor="nw") + + # Bind function to configure + self.canvasVehicleBehavior.bind("", self.on_configure_vehicle_behavior) + # Call on_configure once to set up the initial scrolling region + self.on_configure_vehicle_behavior(None) + + # Render checkboxes + self._renderVehicleOptions(self.frameVehicleBehavior) + + self.tabEnvironmentConditions = self.notebook.addTab("Environment Conditions") + + # Create a canvas + self.canvasEnvironmentConditions = tk.Canvas(self.tabEnvironmentConditions.master) + self.canvasEnvironmentConditions.pack(side="left", fill="both", expand=True) + # Create a vertical scrollbar + scrollbarEnvironmentConditions = ttk.Scrollbar(self.canvasEnvironmentConditions, orient="vertical", command=self.canvasEnvironmentConditions.yview) + scrollbarEnvironmentConditions.pack(side="right", fill="y") + self.canvasEnvironmentConditions.configure(yscrollcommand=scrollbarEnvironmentConditions.set) + # Create a frame to hold widgets + self.innerFrameEnvironmentConditions = ttk.Frame(self.canvasEnvironmentConditions) + self.frameEnvironmentConditions = TKMT.WidgetFrame(self.innerFrameEnvironmentConditions, "Vehicle Behaviors") + innerFrameIDEnvironmentConditions = self.canvasEnvironmentConditions.create_window((0, 0), window=self.innerFrameEnvironmentConditions, anchor="nw") + + # Bind function to configure + self.canvasEnvironmentConditions.bind("", self.on_configure_environment_conditions) + # Call on_configure once to set up the initial scrolling region + self.on_configure_environment_conditions(None) + + self._renderSceneOptions(self.frameEnvironmentConditions) + + def on_mousewheel_pedestrian_behavior(event): + self.canvasPedestrianBehavior.yview_scroll(int(-1 * (event.delta / 120)), "units") + def on_mousewheel_vehicle_behavior(event): + self.canvasVehicleBehavior.yview_scroll(int(-1 * (event.delta / 120)), "units") + def on_mousewheel_environment_conditions(event): + self.canvasEnvironmentConditions.yview_scroll(int(-1 * (event.delta / 120)), "units") + + # Bind the mouse wheel event to the canvas + self.canvasPedestrianBehavior.bind("", on_mousewheel_pedestrian_behavior) + self.canvasVehicleBehavior.bind("", on_mousewheel_vehicle_behavior) + self.canvasEnvironmentConditions.bind("", on_mousewheel_environment_conditions) + + # add radio button for single/multi + # frame # being annotated + + # Function to update the canvas scrolling region + def on_configure_pedestrian_behavior(self, event): + self.canvasPedestrianBehavior.configure(scrollregion=self.canvasPedestrianBehavior.bbox("all")) + def on_configure_vehicle_behavior(self, event): + self.canvasVehicleBehavior.configure(scrollregion=self.canvasVehicleBehavior.bbox("all")) + def on_configure_environment_conditions(self, event): + self.canvasEnvironmentConditions.configure(scrollregion=self.canvasEnvironmentConditions.bbox("all")) + + def _renderMeta(self, parent: TKMT.WidgetFrame): + self.metaFrame = parent.addLabelFrame("Frame Info", padx=(10,10), pady=(10, 0)) + sticky=tk.W + + self.metaFrame.Text("Start Frame:", row=0, col=0, sticky=tk.E) + self.metaFrame.Text(text="0", widgetkwargs={"textvariable":self.currentAnnotationStartFrame}, row=0, col=1, sticky=tk.W) + self.metaFrame.Text("End Frame:", row=0, col=2, sticky=tk.E) + self.metaFrame.Text(text="0", widgetkwargs={"textvariable":self.currentAnnotationEndFrame}, row=0, col=3, sticky=tk.W) + + + + def _renderAnnotationTypeSelector(self, parent: TKMT.WidgetFrame): + self.annotationTypeFrame = parent.addLabelFrame("Annotation Type", padx=(10,10), pady=(10, 0)) + self.annotationTypeFrame.Radiobutton("Multi", self.annotationTypeRadioVar, value="Multi", row=0, col=0) + self.annotationTypeFrame.Radiobutton("Single", self.annotationTypeRadioVar, value="Single", row=0, col=1) + + + def _renderPedOptions(self, parent: TKMT.WidgetFrame): + options = [ + PedestrianTag.Trip, + PedestrianTag.AloneLane, + PedestrianTag.BriskWalk, + PedestrianTag.GroupWalk, + PedestrianTag.GroupDisperse, + PedestrianTag.DogWalk, + PedestrianTag.Retreat, + PedestrianTag.SpeedUp, + PedestrianTag.SlowDown, + PedestrianTag.Wander, + PedestrianTag.PauseStart, + PedestrianTag.Jaywalking, + PedestrianTag.CrossOnRed, + PedestrianTag.Swerve, + PedestrianTag.Break, + PedestrianTag.FlinchOut, + PedestrianTag.FlinchIn, + PedestrianTag.Frozen, + PedestrianTag.Collision, + PedestrianTag.NearMiss, + PedestrianTag.RunIntoTraffic, + PedestrianTag.ThrownBack, + PedestrianTag.MakeStop, + PedestrianTag.MakeGo, + PedestrianTag.Aggression, + PedestrianTag.Observing, + PedestrianTag.Looking, + PedestrianTag.Glancing, + PedestrianTag.NotLookingGlancing, + PedestrianTag.Distracted, + PedestrianTag.Agitated, + PedestrianTag.Cautious, + PedestrianTag.Indecisive, + PedestrianTag.Cross, + PedestrianTag.NotCross, + PedestrianTag.NotSureCross + ] + + self.behaviorCheckVars = [tk.BooleanVar(name=option.value) for option in options] + row = 0 + col = 0 + self.pedCheckbuttons = [] + for option, var in zip(options, self.behaviorCheckVars): + parent.Checkbutton(option.value, var, self.behaviorChangeHandler, (option, var), row=row, col=col) + self.pedCheckbuttons.append(var) + col += 1 + if col == 5: + row += 1 + col = 0 + # the behaviorChangeHandler is called whenever a checkbox is pressed with the associated option and var + return row, col + + def _renderVehicleOptions(self, parent: TKMT.WidgetFrame): + options = [ + VehicleTag.SpeedUp, + VehicleTag.SlowDown, + VehicleTag.GradualSpeedUp, + VehicleTag.GradualSlowDown, + VehicleTag.SlowReverse, + VehicleTag.QuickReverse, + VehicleTag.LaneChange, + VehicleTag.Speeding, + VehicleTag.Halt, + VehicleTag.InducedCollision, + VehicleTag.RunStop, + VehicleTag.Swerve, + VehicleTag.MakeGo, + VehicleTag.Sidewalk + ] + + self.behaviorCheckVars = [tk.BooleanVar(name=option.value) for option in options] + row = 0 + col = 0 + self.vehicleCheckbuttons = [] + for option, var in zip(options, self.behaviorCheckVars): + parent.Checkbutton(option.value, var, self.egoBehaviorChangeHandler, (option, var), row=row, col=col) + self.vehicleCheckbuttons.append(var) + col += 1 + if col == 5: + row += 1 + col = 0 + + def _renderSceneOptions(self, parent: TKMT.WidgetFrame): + options = [ + SceneTag.Day, + SceneTag.Night, + SceneTag.Sunny, + SceneTag.Foggy, + SceneTag.Cloudy, + SceneTag.Snowy, + SceneTag.NoTrafficLight, + SceneTag.GreenTrafficLight, + SceneTag.YellowTrafficLight, + SceneTag.BlinkingYellowTrafficLight, + SceneTag.RedTrafficLight, + SceneTag.StopSign, + SceneTag.Crosswalk, + SceneTag.NoCrosswalk, + SceneTag.Roundabout, + SceneTag.LightTraffic, + SceneTag.ModerateTraffic, + SceneTag.HeavyTraffic, + SceneTag.OneWayTraffic, + SceneTag.TwoWayTraffic, + SceneTag.OccludedPedestrian, + SceneTag.GlareOnWindshield + ] + + self.behaviorCheckVars = [tk.BooleanVar(name=option.value) for option in options] + row = 0 + col = 0 + self.sceneCheckbuttons = [] + for option, var in zip(options, self.behaviorCheckVars): + parent.Checkbutton(option.value, var, self.envBehaviorChangeHandler, (option, var), row = row, col=col) + self.sceneCheckbuttons.append(var) + col += 1 + if col == 5: + row += 1 + col = 0 + + def _renderNotesField(self, parent: TKMT.WidgetFrame): + + parent.Text("Additional Notes:", col=1, row=0) + # parent.nextCol() + + self.notesVar = tk.StringVar() + parent.Entry( + self.notesVar, + col=1, + row=1, + rowspan=3 + ) + + def _renderSaveButton(self, parent: TKMT.WidgetFrame): + self.togglebuttonvar = tk.BooleanVar() + parent.Button("Save Annotation", self.handleSave) + + + def behaviorChangeHandler(self, option: PedestrianTag, var: tk.BooleanVar): + # print("Checkbox number:", option, "was pressed") + # print("Checkboxes: ", var.get()) + if var.get(): + self.pedTags.append(option) + #update the currentAnnotation object's tags + else: + self.pedTags.remove(option) + + def egoBehaviorChangeHandler(self, option: VehicleTag, var: tk.BooleanVar): + # print("Checkbox number:", option, "was pressed") + # print("Checkboxes: ", var.get()) + if var.get(): + self.egoTags.append(option) + else: + self.egoTags.remove(option) + + def envBehaviorChangeHandler(self, option: SceneTag, var: tk.BooleanVar): + # print("Checkbox number:", option, "was pressed") + # print("Checkboxes: ", var.get()) + if var.get(): + self.sceneTags.append(option) + else: + self.sceneTags.remove(option) + + def handleSave(self): + print("Button clicked. Current toggle button state: ", self.togglebuttonvar.get()) + + # self.eventManager.onEvent(AppEvent(type=AppEventType.requestAnnotation, data={})) + + if self.annotationTypeRadioVar.get() == "Single": + newAnnotation = SingleFrameAnnotation(self.currentAnnotationStartFrame.get(), + self.pedTags, + self.egoTags, + self.sceneTags, + self.notesVar.get()) + self.recordingController.addSingleFrameAnnotation(newAnnotation) # must be an event + else: + newAnnotation = MultiFrameAnnotation(self.currentAnnotationStartFrame.get(), + self.currentAnnotationEndFrame.get(), + self.pedTags, + self.egoTags, + self.sceneTags, + self.notesVar.get()) + self.recordingController.addMultiFrameAnnotation(newAnnotation) # TODO, this is anti pattern. + + self.viewEventManager.publishNewAnnotation(newAnnotation) + self.resetAnnotation() + + def resetAnnotation(self): + self.pedTags = [] + self.egoTags = [] + self.sceneTags = [] + + for var in self.pedCheckbuttons: + var.set(False) + for var in self.vehicleCheckbuttons: + var.set(False) + for var in self.sceneCheckbuttons: + var.set(False) + + #self.notesVar.set("") + + print("annotation reset") \ No newline at end of file