{"id":25144508,"url":"https://github.com/christiansassi/computer-vision-project","last_synced_at":"2025-07-08T23:05:18.626Z","repository":{"id":232544923,"uuid":"784598129","full_name":"christiansassi/computer-vision-project","owner":"christiansassi","description":"Project developed by Pietro Bologna (@bolognapietro) and Christian Sassi for the Computer Vision course.","archived":false,"fork":false,"pushed_at":"2025-07-05T11:35:30.000Z","size":226867,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-05T12:35:53.095Z","etag":null,"topics":["computer-vision","detection","stitching","tracking","volleyball"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/christiansassi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-04-10T07:00:55.000Z","updated_at":"2025-07-05T11:35:34.000Z","dependencies_parsed_at":"2024-04-10T08:24:28.492Z","dependency_job_id":"060b7e1c-aa9c-448d-a7da-283756331566","html_url":"https://github.com/christiansassi/computer-vision-project","commit_stats":null,"previous_names":["christiansassi/computer-vision","christiansassi/computer-vision-project"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/christiansassi/computer-vision-project","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christiansassi%2Fcomputer-vision-project","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christiansassi%2Fcomputer-vision-project/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christiansassi%2Fcomputer-vision-project/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christiansassi%2Fcomputer-vision-project/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/christiansassi","download_url":"https://codeload.github.com/christiansassi/computer-vision-project/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christiansassi%2Fcomputer-vision-project/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264363747,"owners_count":23596502,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["computer-vision","detection","stitching","tracking","volleyball"],"created_at":"2025-02-08T19:46:35.928Z","updated_at":"2025-07-08T23:05:13.616Z","avatar_url":"https://github.com/christiansassi.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Top view stitching and tracking (tracking and geometry)\n\n\u003cdiv\u003e\n    \u003cimg src=\"https://img.shields.io/badge/python-3670A0?style=flat\u0026logo=python\u0026logoColor=ffdd54\" alt=\"Python\"/\u003e\n    \u003cimg src=\"https://tinyurl.com/cvyolo11\" alt=\"Yolo 11\"/\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Numpy-013243?style=flat\u0026logo=numpy\u0026logoColor=white\" alt=\"NumPy\"/\u003e\n    \u003cimg src=\"https://img.shields.io/badge/OpenCV-5C3EE8?style=flat\u0026logo=opencv\u0026logoColor=white\" alt=\"OpenCV\"/\u003e\n\u003c/div\u003e\n\n# Table of contents\n\n-   [Project Overview](#project-overview)\n-   [Code Overview](#code-overview)\n    - [Top-View Court Stitching](#top-view-court-stitching)\n    - [Object Detection on Top-View Images](#object-detection-on-top-view-images)\n    - [Object Tracking](#object-tracking)\n    - [Ball Detection and Tracking](#ball-detection-and-tracking)\n    - [Color-based team identification](#color-based-team-identification)\n-   [Project structure](#project-structure)\n-   [Getting Started](#getting-started)\n-   [Contacts](#contacts)\n\n# Project Overview\n\nThis project focuses on processing video footage captured at the Sanbapolis facility in Trento. The main objectives are:\n\n- **Top-View Court Stitching**: The facility has three distinct camera views—top, center, and bottom—each captured by four cameras. Initially, the images from cameras within the same view are stitched together. Then, these stitched views (top, center, and bottom) are merged to create a cohesive top-down view of the entire volleyball court.\n- **Object Detection on Top-View Images**: Various object detection algorithms were applied to the stitched top-view images, including frame subtraction, background subtraction, adaptive background subtraction, and Gaussian averaging. After evaluating these methods, background subtraction was selected as the most effective for detecting objects on the court.\n- **Object Tracking**: Particle filtering was implemented for tracking detected objects (bounding boxes). Given its performance, no further methods were explored.\n- **Ball Detection and Tracking**: YOLO (You Only Look Once) was used for ball detection and tracking. YOLO's efficiency proved to be particularly effective due to the ball's high velocity and potential distortion in certain frames.\n- **Color-based Team Identification**: This project processes volleyball videos, and the net was used to separate the two teams. The color-based identification method faces challenges, as players from both teams wear uniforms of similar colors, complicating the identification process.\n\n# Code Overview\n\n## Top-View Court Stitching\n\nIn the stitching phase, the images from each view (top, center, bottom) are stitched together. This process involves initially stitching the images from cameras within the same view, followed by combining the views to create a seamless top-down representation of the entire court. Due to the complexity of this task, a filtering algorithm was developed to discard low-quality matches based on the inclination of the line connecting two features.\n\nThe final result of the stitching process is shown below:\n\n\u003cp align=\"center\" text-align=\"center\"\u003e \n    \u003cimg width=\"75%\" src=\"assets/stitching/stitching_1.png\"\u003e \n    \u003cbr\u003e \n    \u003cspan\u003e\u003ci\u003eStitched image\u003c/i\u003e\u003c/span\u003e \n\u003c/p\u003e\n\nOne key consideration is that objects positioned higher in the frame are more likely to be cut off at the stitching seams due to the camera angles. For example:\n\n\u003cp align=\"center\" text-align=\"center\"\u003e \n    \u003cimg width=\"33%\" src=\"assets/stitching/stitching_3.png\"\u003e \n    \u003cimg width=\"65%\" src=\"assets/stitching/stitching_2.png\"\u003e \n    \u003cbr\u003e \n    \u003cspan\u003e\u003ci\u003eExample of a player being cut off due to stitching artifacts\u003c/i\u003e\u003c/span\u003e \n\u003c/p\u003e\n\nTo improve performance, stitching parameters were cached to avoid recalculating them for each iteration.\n\n## Object Detection on Top-View Images\n\nVarious object detection algorithms were tested on the stitched top-view images. The methods considered include frame subtraction, background subtraction, adaptive background subtraction, and Gaussian averaging. Background subtraction was found to be the most effective.\n\nThe detection process begins with thresholding the image to highlight the most relevant areas, followed by dilation to account for any stitching errors. Small areas are discarded to focus on significant objects:\n\n\u003cp align=\"center\" text-align=\"center\"\u003e \n    \u003cimg width=\"75%\" src=\"assets/motion_detection/motion_detection_1.png\"\u003e \n    \u003cbr\u003e \n    \u003cspan\u003e\u003ci\u003eThresholded and dilated image\u003c/i\u003e\u003c/span\u003e \n\u003c/p\u003e\n\nNext, contours are filtered based on the volleyball court's boundaries, with objects that intersect the court area by 25% or more being retained:\n\n\u003cp align=\"center\" text-align=\"center\"\u003e \n    \u003cimg width=\"75%\" src=\"assets/motion_detection/motion_detection_2.png\"\u003e \n    \u003cbr\u003e \n    \u003cspan\u003e\u003ci\u003eVolleyball field mask\u003c/i\u003e\u003c/span\u003e \n\u003c/p\u003e\n\nCombining these methods results in the following motion detection output:\n\n\u003cp align=\"center\" text-align=\"center\"\u003e \n    \u003cimg width=\"75%\" src=\"assets/motion_detection/motion_detection_3.png\"\u003e \n    \u003cbr\u003e \n    \u003cspan\u003e\u003ci\u003eMotion detection\u003c/i\u003e\u003c/span\u003e \n\u003c/p\u003e\n\n## Object Tracking\n\nParticle filtering was chosen for object tracking, which initializes a new particle system for each detected bounding box. Over several iterations, the particle system refines its position. Initially, the particles exhibit chaotic behavior:\n\n\u003cp align=\"center\" text-align=\"center\"\u003e \n    \u003cimg width=\"75%\" src=\"assets/motion_tracking/motion_tracking_1.png\"\u003e \n    \u003cbr\u003e \n    \u003cspan\u003e\u003ci\u003eInitial particle system\u003c/i\u003e\u003c/span\u003e \n\u003c/p\u003e\n\nAs iterations proceed, the particle system becomes more accurate:\n\n\u003cp align=\"center\" text-align=\"center\"\u003e \n    \u003cimg width=\"75%\" src=\"assets/motion_tracking/motion_tracking_2.png\"\u003e \n    \u003cbr\u003e \n    \u003cspan\u003e\u003ci\u003eParticle system after some iterations\u003c/i\u003e\u003c/span\u003e \n\u003c/p\u003e\n\nFinally, the particle system is used to predict the direction of the moving object. While the particle system performs well overall, it struggles with sudden, fast movements, requiring several iterations to adjust:\n\n\u003cp align=\"center\" text-align=\"center\"\u003e \n    \u003cimg width=\"75%\" src=\"assets/motion_tracking/motion_tracking_3.png\"\u003e \n    \u003cbr\u003e \n    \u003cspan\u003e\u003ci\u003eMotion tracking\u003c/i\u003e\u003c/span\u003e \n\u003c/p\u003e\n\n\u003e [!NOTE]\n\u003e While particle systems may not be the best option for all tracking scenarios, they performed well for this project. Other methods might be more appropriate for rapid changes in object movement.\n\n## Ball Detection and Tracking\n\nFor ball detection and tracking, YOLO (You Only Look Once) was used. Given the high velocity of the ball, traditional methods often resulted in distortion, making it difficult to detect. To overcome this, a custom dataset was created by manually extracting 1,000 images from the video, each with a labeled bounding box around the ball.\n\nYOLO v11 was then applied to the dataset, enabling accurate detection. The same particle system technique used for player tracking was applied to track the ball's movement:\n\n\u003cp align=\"center\" text-align=\"center\"\u003e\n  \u003cimg width=\"100%\" src=\"assets/ball_detection_and_tracking/ball.gif\"\u003e\n  \u003cbr\u003e\n  \u003cspan\u003e\u003ci\u003eBall detection and tracking\u003c/i\u003e\u003c/span\u003e\n\u003c/p\u003e\n\nAs with player tracking, the particle system may require a few iterations to adapt to rapid movements, potentially leading to inaccurate predictions during those iterations.\n\n\u003e [!NOTE]\n\u003e Although particle systems can face challenges in tracking fast-moving objects, the ball's movement is more predictable, making the technique more effective in this case.\n\n## Color-based Team Identification\n\nGiven that this project processes volleyball videos, the optimal method for team identification was to use the net to separate the two teams. This approach is particularly effective since players from different teams in volleyball are generally positioned on opposite sides of the net.\n\nHowever, color-based team identification faced challenges due to the similarity in uniform colors between the two teams.\n\n\u003cp align=\"center\" text-align=\"center\"\u003e\n  \u003cimg width=\"100%\" src=\"assets/histograms/histograms.png\"\u003e\n  \u003cbr\u003e\n  \u003cspan\u003e\u003ci\u003eColor-based team identification applied to distinct colors\u003c/i\u003e\u003c/span\u003e\n\u003c/p\u003e\n\nAs shown in the histograms, the uniform colors of the two teams were highly similar, making it difficult to distinguish between them based solely on color. However, if the uniforms differed more significantly, color-based identification would be much more effective.\n\nWhile this method is fast and efficient, it has some limitations. For instance, when players from both teams are near the net, they may be merged into a single bounding box, leading to misclassification of one team. Using YOLO for more precise detection could mitigate this issue.\n\n\u003cp align=\"center\" text-align=\"center\"\u003e\n  \u003cimg width=\"49%\" src=\"assets/team_identification/team_identification_3.png\"\u003e\n  \u003cimg width=\"49%\" src=\"assets/team_identification/team_identification_4.png\"\u003e\n  \u003cbr\u003e\n  \u003cspan\u003e\u003ci\u003eTwo bounding boxes near the net merged into a single bounding box, resulting in misclassification\u003c/i\u003e\u003c/span\u003e\n\u003c/p\u003e\n\n\n# Project structure\n\n```text\n.\n├── assets          # Images\n├── models          # YOLO11 model\n├── libs            # Source files\n└── videos\n    ├── cut         # Cut videos (private)\n    ├── original    # Original videos (private)\n    └── processed   # Processed videos (private)\n```\n\n# Getting Started\n\n1. Set up the workspace:\n\n    ```bash\n    git clone https://github.com/christiansassi/computer-vision-project\n    cd computer-vision-project\n    pip install -r requirements.txt\n    ```\n\n2. Run [main.py](main.py) script:\n\n    ```bash\n    python3 main.py\n    python3 main.py -live # Run in live mode\n    ```\n\n\u003e [!WARNING]\n\u003e Due to privacy reasons, the video files cannot be shared.\n\n\u003cp align=\"center\" text-align=\"center\"\u003e\n  \u003cimg width=\"75%\" src=\"assets/demo/demo.gif\"\u003e\n  \u003cbr\u003e\n  \u003cspan\u003e\u003ci\u003eDemo\u003c/i\u003e\u003c/span\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\" text-align=\"center\"\u003e\n  \u003cimg width=\"75%\" src=\"assets/demo/plot_tracking_demo.gif\"\u003e\n  \u003cbr\u003e\n  \u003cspan\u003e\u003ci\u003eTracking plot\u003c/i\u003e\u003c/span\u003e\n\u003c/p\u003e\n\n# Resources\n\n[Report](https://github.com/christiansassi/computer-vision-project/blob/d302cc1fa7fd1fcb81e19c02c43ca008ac82afa0/report/Top_view_stitching_and_tracking__tracking_and_geometry_.pdf)\n\n[Presentation](https://www.canva.com/design/DAGXGWPdaG0/6xN45w81QcofHTlDwvXiJA/edit?utm_content=DAGXGWPdaG0\u0026utm_campaign=designshare\u0026utm_medium=link2\u0026utm_source=sharebutton)\n\n[Video](https://www.youtube.com/watch?v=kBeKlCkUAaY)\n\n# Contacts\n\nPietro Bologna - [pietro.bologna@studenti.unitn.it](mailto:pietro.bologna@studenti.unitn.it)\n\nChristian Sassi - [christian.sassi@studenti.unitn.it](mailto:christian.sassi@studenti.unitn.it)\n\n\u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"assets/extras/dark.png\"\u003e\n    \u003cimg alt=\"https://www.unitn.it/\" src=\"assets/extras/light.png\" width=\"300px\"\u003e\n\u003c/picture\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristiansassi%2Fcomputer-vision-project","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchristiansassi%2Fcomputer-vision-project","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristiansassi%2Fcomputer-vision-project/lists"}