{"id":13574661,"url":"https://github.com/visipedia/annotation_tools","last_synced_at":"2025-04-04T18:31:50.085Z","repository":{"id":54423778,"uuid":"105591163","full_name":"visipedia/annotation_tools","owner":"visipedia","description":"Visipedia Annotation Tools","archived":false,"fork":false,"pushed_at":"2022-11-16T01:10:36.000Z","size":7564,"stargazers_count":281,"open_issues_count":19,"forks_count":87,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-11-05T10:44:26.113Z","etag":null,"topics":["annotations","computer-vision","datasets"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/visipedia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-02T22:21:41.000Z","updated_at":"2024-10-15T05:43:37.000Z","dependencies_parsed_at":"2023-01-22T07:00:23.657Z","dependency_job_id":null,"html_url":"https://github.com/visipedia/annotation_tools","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visipedia%2Fannotation_tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visipedia%2Fannotation_tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visipedia%2Fannotation_tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visipedia%2Fannotation_tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/visipedia","download_url":"https://codeload.github.com/visipedia/annotation_tools/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247229531,"owners_count":20905069,"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":["annotations","computer-vision","datasets"],"created_at":"2024-08-01T15:00:53.487Z","updated_at":"2025-04-04T18:31:49.004Z","avatar_url":"https://github.com/visipedia.png","language":"JavaScript","readme":"![coco example](tutorials/assets/coco_example.png?raw=true)\n\n# Visipedia Annotation Toolkit\n\nThis repository contains a collection of tools for editing and creating [COCO style datasets](http://cocodataset.org/#download).\n\nThese web based annotation tools are built on top of [Leaflet.js](http://leafletjs.com/) and [Leaflet.draw](https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html).\n\n## Capabilities:\n* Load and visualize a COCO style dataset\n* Edit Class Labels\n* Edit Bounding Boxes\n* Edit Keypoints\n* Export a COCO style dataet\n* Bounding Box Tasks for Amazon Mechanical Turk\n\n## Not Implemented:\n* Edit Segmentations\n* Keypoint tasks for Amazon Mechanical Turk\n* Class label tasks for Amazon Mechanical Turk\n* Segmentation tasks for Amazon Mechanical Turk\n\n# Requirements and Environments\nThis code base is developed using Python 2.7.10 on Ubuntu 16.04 and MacOSX 10.11. You need to have [MongoDB](https://www.mongodb.com/) [installed](https://docs.mongodb.com/manual/installation/#tutorials) and [running](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/#run-mongodb).\n\nThe tools are primarily tested using the [Chrome web browser](https://www.google.com/chrome/browser/desktop/index.html).\n\n# Quick Start\nMake sure that MongoDB is installed and running (e.g. for Ubuntu 16.04 see [here](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/#import-the-public-key-used-by-the-package-management-system)).\n\nClone the repo:\n```\n$ git clone https://github.com/visipedia/annotation_tools.git\n$ cd annotation_tools\n```\n\nInstall the python dependencies:\n```\n$ pip install -r requirements.txt\n```\n\nStart the annotation tool web server\n```\n$ python run.py --port 8008\n```\n\nDownload the COCO Dataset annotation file:\n```\ncd ~/Downloads\nwget http://images.cocodataset.org/annotations/annotations_trainval2017.zip\nunzip annotations_trainval2017.zip\n```\n\nImport the validation annotations into the annotation tool:\n```\n# From the annotation_tools repo\n$ python -m annotation_tools.db_dataset_utils --action load \\\n--dataset ~/Downloads/annotations/person_keypoints_val2017.json \\\n--normalize\n```\nIf you get an error here, then please make sure MongoDB is installed and running.\n\nGo to `http://localhost:8008/edit_image/100238` to edit the annotations for the validation image with `id=100238`.\n\nGo to `http://localhost:8008/edit_task/?start=0\u0026end=100` to edit the first 100 images, where the images have been sorted by their ids.\n\nGo to `http://localhost:8008/edit_task/?category_id=1` to edit all images that have annotations whose `category_id=1`.\n\nExport the modified dataset:\n```\n$ python -m annotation_tools.db_dataset_utils --action export \\\n--output ~/Downloads/annotations/updated_person_keypoints_val2017.json \\\n--denormalize\n```\n\nClear the annotation tool database:\n```\n$ python -m annotation_tools.db_dataset_utils --action drop\n```\n\n# Development Setup\nTo modify and develop this code base you will need to have [node](https://nodejs.org/en/) and [npm](https://www.npmjs.com/) installed.\n\nClone the repo:\n```\n$ git clone https://github.com/visipedia/annotation_tools.git\n$ cd annotation_tools\n```\n\nInstall python packages:\n```\n$ pip install -r requirements.txt\n```\n\nInstall node modules (both production and development):\n```\n$ npm install\n```\n\nWatch for javascript changes and recompile the app (this generates `app.bundle.js` in `annotation_tools/static`):\n```\n$ npm run watch\n```\n\nStart the web server:\n```\n$ python run.py \\\n--port 8008 \\\n--debug\n```\n\n# Dataset Format\nWe use a slightly modified COCO dataset format:\n```\n{\n\"images\" : [image],\n\"annotations\" : [annotation],\n\"categories\" : [category],\n\"licenses\" : [license]\n}\n\nimage{\n  \"id\" : str,\n  \"width\" : int,\n  \"height\" : int,\n  \"file_name\" : str,\n  \"license\" : str,\n  \"rights_holder\" : str,\n  \"url\" : str,\n  \"date_captured\" : datetime (str)\n}\n\nannotation{\n  \"id\" : str,\n  \"image_id\" : str,\n  \"category_id\" : str,\n  \"segmentation\" : RLE or [polygon],\n  \"area\" : float,\n  \"bbox\" : [x,y,width,height],\n  \"iscrowd\" : 0 or 1,\n  \"keypoints\" : [x, y, v, ...],\n  \"num_keypoints\" : int\n}\n\ncategory{\n  \"id\" : str,\n  \"name\" : str,\n  \"supercategory\" : str,\n  \"keypoints\" : [str, ...],\n  \"keypoints_style\" : [str, ...],\n}\n\nlicense{\n  \"id\" : str,\n  \"name\" : str,\n  \"url\" : str,\n}\n\n```\n\nThe biggest change that we have made is storing the annotations in normalized coordinates (each x value is divided by the width of the image, and each y value is divided by the height of the image). This is more convenient for rendering the annotations on resized images. We also use strings to store the ids rather than integers.\n\n`coco_url` \u0026 `flickr_url` have been remapped to `url`.\n\n`rights_holder` is a string that can hold the photographer's name.\n\n`keypoints_style` is an array of css color values for the different keypoints of the class (e.g. `'#46f0f0'`).\n\n# Dataset Loading and Exporting\n\nWe use the modified COCO dataset format as the \"schema\" for the the MongoDB database. Loading a dataset will create 4 collections: `category`, `image`, `annotation`, and `license`.\n\nWe can load the original COCO dataset out of the box. However, we need to tell the code to normalize the annotations by passing the `--normalize` command line argument. Further, the code will check to see if `coco_url` is present and will create a `url` field with the same value.\n\nLoad a dataset:\n```\npython -m annotation_tools.db_dataset_utils --action load \\\n--dataset ~/Downloads/annotations/person_keypoints_val2017.json \\\n--normalize\n```\n\nAfter we have edited the dataset, we can export it. This will produce a json file that can be used as a datatset file to train a computer vision model. By default, the code will export *noramalized* annotations, we can export denomalized coordinates by passing the `--denormalize` command line argument.\n\nExport a dataset:\n```\npython -m annotation_tools.db_dataset_utils --action export \\\n--output ~/Downloads/annotations/updated_person_keypoints_val2017.json \\\n--denormalize\n```\n\nWe provide a convenience function to clear the collections that have been created when loading a dataset:\n```\npython -m annotation_tools.db_dataset_utils --action drop\n```\n\n# Hosting Images Locally\n\nIt might be the case that the images you want to edit are on your local machine and not accessible via a url. In this case, you can use python's SimpleHTTPServer to start a local webserver to serve the images directly from your machine. If the images are located in `/home/gvanhorn/images` then you can:\n```\ncd /home/gvanhorn\npython -m SimpleHTTPServer 8007\n```\nThis starts a webserver on port 8007 that can serve files from the `/home/gvanhorn` directory. You can now access images via the browser by going to `localhost:8007/images/397133.jpg`, where `397133.jpg` is an image file in `/home/gvanhorn/images`. Now you can create a json dataset file that has `localhost:8007/images/397133.jpg` in the `url` field for the image with id `397133`. As this technique makes all files in the directory `/home/gvanhorn` accessible, this should be used with caution.\n\n# Editing an Image\n\nThe edit tool is meant to be used by a \"super user.\" It is a convenient tool to visualize and edit all annotations on an image. All changes will overwrite the annotations in the database. To edit a specific image, use the image id (which you specified in the dataset file that you loaded in the previous section) and go to the url `localhost:8008/edit_image/397133`, where the image id is `397133` in this case. Make any modificaiton to the image that you need to and save the annotations. Note that when saving the annotations you directly overwrite the previous version of the annotations.\n\nWe currently support editing the class labels, bounding boxes, and keypoints. Editing segmentations is not currently supported.\n\n# Editing an Image Sequence\n\nYou can use a url constucted like `localhost:8008/edit_task/?start=0\u0026end=100` to edit the first 100 images in the dataset, where the images are sorted by their ids. You can additionally specify a category id to edit only images that have labels with that category `localhost:8008/edit_task/?start=0\u0026end=100\u0026category_id=1`.\n\n# Collecting Bounding Boxes\n\nWe support creating bounding box tasks, where each task is composed of a group of images that needed to be annotated with bounding boxes for a *single* category. Each task has a specific `id` and is accessible via `localhost:8008/bbox_task/0a95f07a`, where `0a95f07a` is the task id. Similar to datasets, you'll need to create a json file that specifies the bounding box tasks and then load that file into the tool.\n\nData format:\n```\n{\n  'instructions' : [bbox_task_instructions],\n  'tasks' : [bbox_task]\n}\n\nbbox_task_instructions{\n  id : str\n  title : str\n  description : str\n  instructions: url\n  examples: [url]\n}\n\nbbox_task{\n  id : str\n  image_ids : [str]\n  instructions_id : str,\n  category_id : str\n}\n```\nThe `bbox_task_instructions` contains fields that hold instruction information to show to the worker.  The `examples` list should contain urls to example images. These images should have a height of 500px and will be rendered on the task start screen. `instructions` should point to an external page that contains detailed information for your task. For example you can use Google Slides to describe the task in detail and have more examples.\n\n`bbox_task` contains a list of image ids (`image_ids`) that should be annotated with bounding boxes. The `instruction_id` field should be a valid bbox_task_instructions `id`. The `category_id` should be valid category that was created when loading a dataset. The workers will be asked to draw boxes around that category for each image in the task.\n\nOnce you have created a json file you can load it:\n```\npython -m annotation_tools.db_bbox_utils --action load \\\n--tasks ~/Desktop/bbox_tasks.json\n```\n\nThe task can be accessed by going to the url `localhost:8008/bbox_task/0a95f07a`, where `0a95f07a` is a `bbox_task` `id` that you specified in the json file that was loaded.\n\nWhen a worker finishes a task, the following result structure will be saved in the database:\n```\nbbox_task_result{\n  time : float\n  task_id : str\n  date : str\n  worker_id : str\n  results : [bbox_result]\n}\n\nbbox_result{\n  time : float\n  annotations : [annotation]\n  image : image\n}\n```\nWhere `annotation` is defined above.\n\nThese results can be exported to a json file with:\n```\npython -m annotation_tools.db_bbox_utils --action export \\\n--output ~/Desktop/bbox_task_results.json \\\n--denormalize\n```\nIf you only want to export a specific set of results, you can pass in the bounding box task file that contains the tasks you want results for:\n```\npython -m annotation_tools.db_bbox_utils --action export \\\n--tasks ~/Desktop/bbox_tasks.json \\\n--output ~/Desktop/bbox_task_results.json \\\n--denormalize\n```\n\nTo merge these redundant box annotations together to produce a final dataset you can use the [Crowdsourcing](https://github.com/gvanhorn38/crowdsourcing) repo. See [here](https://github.com/gvanhorn38/crowdsourcing#merging-bounding-boxes-example) for an example.  \n\nWe provide a convenience function to clear all collections associated with the bounding boxes tasks:\n```\npython -m annotation_tools.db_bbox_utils --action drop\n```\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvisipedia%2Fannotation_tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvisipedia%2Fannotation_tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvisipedia%2Fannotation_tools/lists"}