From e8b2c4033022902a7be856583fe98b5fe7e0cb4b Mon Sep 17 00:00:00 2001 From: Nikita Manovich Date: Fri, 6 Jul 2018 19:11:15 +0300 Subject: [PATCH] Release 0.1.1 * video from share hotfix & dump hotfix * Added contributors * Added screenshot, documentation, screencasts into README.md * Fixed GitHub documentation --- CONTRIBUTORS.md | 22 +++ README.md | 13 ++ .../templates/documentation/base_page.html | 4 + cvat/apps/documentation/user_guide.md | 126 +++++++++--------- cvat/apps/engine/annotation.py | 27 ++-- cvat/apps/engine/task.py | 5 +- 6 files changed, 123 insertions(+), 74 deletions(-) create mode 100644 CONTRIBUTORS.md diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 000000000000..787a65e9bbdb --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,22 @@ +# Core support team +- **[Nikita Manovich](https://github.com/nmanovic)** + + * Project lead + * Developer + * Author and maintainer + +- **[Boris Sekachev](https://github.com/bsekachev)** + + * Primary developer + * Author and maintainer + +- **[Andrey Zhavoronkov]()** + + * Developer + * Author and maintainer + +# Contributors + +- **[Victor Salimonov](https://github.com/VikTorSalimonov)** + + * Documentation, screencasts diff --git a/README.md b/README.md index 539622755fab..57234fff115c 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,19 @@ CVAT is completely re-designed and re-implemented version of [Video Annotation Tool from Irvine, California](http://carlvondrick.com/vatic/) tool. It is free, online, interactive video and image annotation tool for computer vision. It is being used by our team to annotate million of objects with different properties. Many UI and UX decisions are based on feedbacks from professional data annotation team. +![CVAT screenshot](cvat/apps/documentation/static/documentation/images/gif003.gif) + +## Documentation + +- [User's guide](cvat/apps/documentation/user_guide.md) +- [XML annotation format](cvat/apps/documentation/xml_format.md) + +## Screencasts + +- [Annotation mode](https://www.youtube.com/watch?v=uSqaQENdyJE) +- [Interpolation mode](https://www.youtube.com/watch?v=sc5X5hvxNfA) +- [Attribute mode](https://www.youtube.com/watch?v=5yXaG0V7X0Q) + ## LICENSE Code released under the [MIT License](https://opensource.org/licenses/MIT). diff --git a/cvat/apps/documentation/templates/documentation/base_page.html b/cvat/apps/documentation/templates/documentation/base_page.html index 84f605643506..a356ea5a4b47 100644 --- a/cvat/apps/documentation/templates/documentation/base_page.html +++ b/cvat/apps/documentation/templates/documentation/base_page.html @@ -23,6 +23,10 @@ var converter = new showdown.Converter({extensions: ['toc']}); converter.setFlavor('github'); var user_guide = document.getElementById("content").innerHTML; + // For GitHub documentation we need to have relative links without + // leading slash. Let's just add the leading slash here to have correct + // links inside online documentation. + user_guide = user_guide.replace(/!\[\]\(static/g, "![](/static") document.body.innerHTML = converter.makeHtml(user_guide); diff --git a/cvat/apps/documentation/user_guide.md b/cvat/apps/documentation/user_guide.md index 7829e860eba2..33deb812e7de 100644 --- a/cvat/apps/documentation/user_guide.md +++ b/cvat/apps/documentation/user_guide.md @@ -9,13 +9,13 @@ Computer Vision Annotation Tool (CVAT) is a web-based tool which helps to annota ### Authorization - First of all you have to log in to CVAT tool. - ![](/static/documentation/images/image001.jpg) + ![](static/documentation/images/image001.jpg) - ![](/static/documentation/images/image002.jpg) + ![](static/documentation/images/image002.jpg) - If you don't have an account you have to create it using the link below the login page. - ![](/static/documentation/images/image003.jpg) + ![](static/documentation/images/image003.jpg) ### Administration panel Type ``/admin`` in URL to go to the administration panel. @@ -28,11 +28,11 @@ There you can: 1. Create an annotation task by pressing ``Create New Task`` button on the main page. - ![](/static/documentation/images/image004.jpg) + ![](static/documentation/images/image004.jpg) 2. Specify mandatory parameters of the task. You have to fill ``Name``, ``Labels`` and ``Select Files`` at least. - ![](/static/documentation/images/image005.jpg) + ![](static/documentation/images/image005.jpg) __Labels__. Use the following schema to create labels: ``label_name input_type=attribute_name:attribute_value1,attribute_value2`` @@ -67,17 +67,17 @@ There you can: Push ``Submit`` button and it will be added into the list of annotation tasks. Finally you should see something similar to the figure below: - ![](/static/documentation/images/image006.jpg) + ![](static/documentation/images/image006.jpg) 3. Follow a link inside ``Jobs`` section to start annotation process. In some cases you can have several links. It depends on size of your task and ``Overlap Size`` and ``Segment Size`` parameters. To improve UX only several first frames will be loaded and you will be able to annotate first images. Other frames will be loaded in background. - ![](/static/documentation/images/image007.jpg) + ![](static/documentation/images/image007.jpg) ### Basic navigation 1. Use arrows below to move on next/previous frame. Mostly every button is covered by a shortcut. To get a hint about the shortcut just put your mouse pointer over an UI element. - ![](/static/documentation/images/image008.jpg) + ![](static/documentation/images/image008.jpg) 2. An image can be zoom in/out using mouse's wheel. The image will be zoomed relatively your current cursor position. Thus if you point on an object it will be under your mouse during zooming process. @@ -90,24 +90,24 @@ Usage examples: 1. Before start need to be sure that ``Annotation`` is selected. - ![](/static/documentation/images/image009.jpg) + ![](static/documentation/images/image009.jpg) 2. Create a new annotation: - Choose an object's ``label``. When you created an annotation task you had to specify one or several labels with attributes. - ![](/static/documentation/images/image010.jpg) + ![](static/documentation/images/image010.jpg) - Create a bounding box by clicking on ``Create Track`` button or ``N`` shortcut. Choose left top and right bottom points. Your first bounding box is ready! It is possible to adjust boundaries and location of the bounding box using mouse. - ![](/static/documentation/images/image011.jpg) + ![](static/documentation/images/image011.jpg) 3. In the list of objects you can see the labeled car. In the side panel you can perform basic operations under the object. - ![](/static/documentation/images/image012.jpg) + ![](static/documentation/images/image012.jpg) 4. An example of fully annotated frame in ``Annotation`` mode can look like on the figure below. - ![](/static/documentation/images/image013.jpg) + ![](static/documentation/images/image013.jpg) ### Interpolation mode (basics) Usage examples: @@ -117,55 +117,55 @@ Usage examples: 1. Before start need to be sure that ``Interpolation`` is selected. - ![](/static/documentation/images/image014.jpg) + ![](static/documentation/images/image014.jpg) 2. Create a track for an object (look at the selected car as an example): - Annotate a bounding box on first frame for the object. - In ``Interpolation`` mode the bounding box will be interpolated on next frames automatically. - ![](/static/documentation/images/image015.jpg) + ![](static/documentation/images/image015.jpg) 3. If the object starts to change its position you need to modify bounding boxes where it happens. Changing of bounding boxes on each frame isn't necessary. It is enough to update several key frames and frames between them will be interpolated automatically. See an example below: - The car starts moving on frame #70. Let's mark the frame as a key frame. - ![](/static/documentation/images/image016.jpg) + ![](static/documentation/images/image016.jpg) - Let's jump 30 frames forward and adjust boundaries of the object. - ![](/static/documentation/images/image017.jpg) + ![](static/documentation/images/image017.jpg) - After that bounding boxes of the object between 70 and 100 frames will be changed automatically. For example, frame #85 looks like on the figure below: - ![](/static/documentation/images/image018.jpg) + ![](static/documentation/images/image018.jpg) 4. When the annotated object disappears or becomes too small, you need to finish the track. To do that you need to choose ``Outsided Property``. - ![](/static/documentation/images/image019.jpg) + ![](static/documentation/images/image019.jpg) 5. If the object isn't visible on a couple of frames and after that it appears again it is possible to use ``Merge Tracks`` functionality to merge several separated tracks into one. - ![](/static/documentation/images/image020.jpg) + ![](static/documentation/images/image020.jpg) - Let's create a track for the bus. - ![](/static/documentation/images/gif001.gif) + ![](static/documentation/images/gif001.gif) - After that create a track when it appears again on the sequence of frames. - ![](/static/documentation/images/gif002.gif) + ![](static/documentation/images/gif002.gif) - Press ``Merge Tracks`` button and click on any bounding box of first track and on any bounding box of second track. - ![](/static/documentation/images/image021.jpg) + ![](static/documentation/images/image021.jpg) - Press ``Apply Merge`` button to apply changes. - ![](/static/documentation/images/image022.jpg) + ![](static/documentation/images/image022.jpg) - The final annotated sequence of frames in ``Interpolation`` mode can look like the clip below: - ![](/static/documentation/images/gif003.gif) + ![](static/documentation/images/gif003.gif) ### Attribute Annotation mode (basics) Usage examples: @@ -173,23 +173,23 @@ Usage examples: 1. To enter into ``Attribute Annotation`` mode press ``Shift+Enter`` shortcut. After that it is possible to change attributes using keyboard. - ![](/static/documentation/images/image023.jpg) + ![](static/documentation/images/image023.jpg) 2. The active attribute will be red. In this case it is ``Age``. - ![](/static/documentation/images/image024.jpg) + ![](static/documentation/images/image024.jpg) 3. Look at the bottom side panel to see all possible shortcuts to change the attribute. Press ``4`` key on your keyboard to assign ``adult`` value for the attribute. - ![](/static/documentation/images/image025.jpg) + ![](static/documentation/images/image025.jpg) 4. Press ``Up Arrow``/``Down Arrow`` keys on your keyboard to go to next attribute . - ![](/static/documentation/images/image026.jpg) + ![](static/documentation/images/image026.jpg) 5. In this case after pressing ``Down Arrow`` you will be able to edit ``Gender`` attribute. - ![](/static/documentation/images/image027.jpg) + ![](static/documentation/images/image027.jpg) 6. Use ``Right Arrow``/``Left Arrow`` keys to move on previous/next image. @@ -199,7 +199,7 @@ Usage examples: 2. After that press ``Open Menu`` and then ``Dump Annotation`` button. - ![](/static/documentation/images/image028.jpg) + ![](static/documentation/images/image028.jpg) 3. The annotation will be written into **.xml** file. To find the annotation file go to the directory where your browser saves downloaded files by default. For more information visit [XML annotation format](/documentation/xml_format.html) description. @@ -212,12 +212,12 @@ Usage examples: | Bounding box |Tight bounding box| | ------------ |:----------------:| -| ![](/static/documentation/images/image030.jpg) | ![](/static/documentation/images/image031.jpg)| +| ![](static/documentation/images/image030.jpg) | ![](static/documentation/images/image031.jpg)| --- **Label** is a type of an annotated object (e.g. person, car, face, etc) -![](/static/documentation/images/image032.jpg) +![](static/documentation/images/image032.jpg) --- @@ -226,12 +226,12 @@ Usage examples: - __Unique__: immutable and isn't changed from frame to frame (e.g age, gender, color, etc) - __Temporary__: mutable and can be changed on any frame (e.g. quality, pose, truncated, etc) - ![](/static/documentation/images/image033.jpg) + ![](static/documentation/images/image033.jpg) --- **Track** is a set of bounding boxes on different frames which corresponds to one object. Tracks are created in ``Interpolation`` mode. -![](/static/documentation/images/gif004.gif) +![](static/documentation/images/gif004.gif) --- **Annotation** is a set of bounding boxes and tracks. There are several types of annotations: @@ -241,51 +241,51 @@ Usage examples: ## Interface of the annotation tool -![](/static/documentation/images/image034.jpg) +![](static/documentation/images/image034.jpg) --- ### Navigation by frames/images -![](/static/documentation/images/image035.jpg) +![](static/documentation/images/image035.jpg) --- Go to the first and latest frames. -![](/static/documentation/images/image036.jpg) +![](static/documentation/images/image036.jpg) --- Go to the next/previous frame with a predefined step. Shortcuts: ``v`` — step backward, ``c`` — step forward. By default the step is ``10``. -![](/static/documentation/images/image037.jpg) +![](static/documentation/images/image037.jpg) To change the predefined step go to settings (``Open Menu`` —> ``Settings``) and modify ``Player Step`` property. -![](/static/documentation/images/image038.jpg) +![](static/documentation/images/image038.jpg) -![](/static/documentation/images/image039.jpg) +![](static/documentation/images/image039.jpg) --- Go to the next/previous frame with step equals to 1. Shortcuts: ``d`` — previous, ``f`` — next. -![](/static/documentation/images/image040.jpg) +![](static/documentation/images/image040.jpg) --- Play the sequence of frames or the set of images. Shortcut: ``Space``. -![](/static/documentation/images/image041.jpg) +![](static/documentation/images/image041.jpg) To adjust player speed go to settings (``Open Menu`` —> ``Settings``) and modify a value of ``Player Speed`` property. -![](/static/documentation/images/image042.jpg) +![](static/documentation/images/image042.jpg) Go to specified frame. -![](/static/documentation/images/image060.jpg) +![](static/documentation/images/image060.jpg) ### Bottom side panel -![](/static/documentation/images/image043.jpg) +![](static/documentation/images/image043.jpg) ### Side panel (list of objects) @@ -293,43 +293,43 @@ In the side panel you can see the list of available objects on the current frame |Annotation mode|Interpolation mode| |--|--| -|![](/static/documentation/images/image044.jpg)|![](/static/documentation/images/image045.jpg)| +|![](static/documentation/images/image044.jpg)|![](static/documentation/images/image045.jpg)| --- A bounding box can be locked to prevent its modification or moving by an accident. Shortcut to lock an object: ``l``. -![](/static/documentation/images/image046.jpg) +![](static/documentation/images/image046.jpg) --- A bounding box can be removed. Shortcut: ``Delete``. A locked bounding box can be deleted using ``Shift+Delete`` shortcut. -![](/static/documentation/images/image047.jpg) +![](static/documentation/images/image047.jpg) --- A bounding box can be **Occluded**. Shortcut: ``q``. Such bounding boxes have dashed boundaries. -![](/static/documentation/images/image048.jpg) +![](static/documentation/images/image048.jpg) -![](/static/documentation/images/image049.jpg) +![](static/documentation/images/image049.jpg) --- The type of a bounding box can be changed by selecting __Label__ property. For instance, it can look like on the figure below: -![](/static/documentation/images/image050.jpg) +![](static/documentation/images/image050.jpg) To change a type of a bounding box using keyboard you need to press ``Shift+``. ### Open Menu It is the main menu for the annotation tool. It can be used to download, upload and remove annotations. As well it shows statistics about the current annotation task. -![](/static/documentation/images/image051.jpg) +![](static/documentation/images/image051.jpg) ### Settings The menu contains different parameters which can be adjust by the user needs. For example, ``Auto Saving Internal``, ``Player Step``, ``Player Speed``. -![](/static/documentation/images/image052.jpg) +![](static/documentation/images/image052.jpg) - ``Brightness`` makes it appear that there is more or less light within the image. - ``Contrast`` controls the difference between dark and light parts of the image @@ -341,15 +341,15 @@ Basic operations in the mode was described above. __occluded__ attribute is used if an object is occluded by another object or it isn't fully visible on the frame. Use ``q`` shortcut to set the property quickly. -![](/static/documentation/images/image053.jpg) +![](static/documentation/images/image053.jpg) Example: both cars on the figure below should be labeled as __occluded__. -![](/static/documentation/images/image054.jpg) +![](static/documentation/images/image054.jpg) If a frame contains too many objects and it is difficult to annotate them due to many bounding boxes are placed mostly in the same place when it makes sense to lock them. Bounding boxes for locked objects are transparent and it is easy to annotate new objects. Also it will not be possible to change previously annotated objects by an accident. Shortcut: ``l``. -![](/static/documentation/images/image055.jpg) +![](static/documentation/images/image055.jpg) ## Interpolation mode (advanced) @@ -358,11 +358,11 @@ Basic operations in the mode was described above. Bounding boxes created in the mode have extra navigation buttons. - These buttons help to jump to previous/next key frame. - ![](/static/documentation/images/image056.jpg) + ![](static/documentation/images/image056.jpg) - The button helps to jump to initial frame for the object (first bounding box for the track). - ![](/static/documentation/images/image057.jpg) + ![](static/documentation/images/image057.jpg) ## Attribute Annotation mode (advanced) @@ -371,7 +371,7 @@ Basic operations in the mode was described above. It is possible to handle many objects on the same frame in the mode. -![](/static/documentation/images/image058.jpg) +![](static/documentation/images/image058.jpg) It is more convenient to annotate objects of the same type. For the purpose it is possible to specify a corresponding filter. For example, the following filter will hide all objects except pedestrians: ``//pedestrian``. @@ -385,7 +385,7 @@ By default other objects are hidden. To change the behaviour uncheck the corresp ## Filter -![](/static/documentation/images/image059.jpg) +![](static/documentation/images/image059.jpg) There are several reasons to use the feature: @@ -440,9 +440,9 @@ Example | Description Many UI elements have shortcut hints. Put your pointer to an interesting element to see it. -![](/static/documentation/images/image061.jpg) +![](static/documentation/images/image061.jpg) -![](/static/documentation/images/image062.jpg) +![](static/documentation/images/image062.jpg) | Shortcut | Common | -----------------------|------------------------------ diff --git a/cvat/apps/engine/annotation.py b/cvat/apps/engine/annotation.py index 83fd7271908a..a996d1ae39cd 100644 --- a/cvat/apps/engine/annotation.py +++ b/cvat/apps/engine/annotation.py @@ -742,6 +742,13 @@ def _add_meta(self, meta): self._add_meta(v) self._indent() self.xmlgen.endElement(k) + elif type(v) == list: + self._indent() + self.xmlgen.startElement(k, {}) + for tup in v: + self._add_meta(OrderedDict([tup])) + self._indent() + self.xmlgen.endElement(k) else: self._indent() self.xmlgen.startElement(k, {}) @@ -972,23 +979,23 @@ def dump(self, data_format, db_task, scheme, host): ("created", str(timezone.localtime(db_task.created_date))), ("updated", str(timezone.localtime(db_task.updated_date))), - ("labels", OrderedDict( - [("label", OrderedDict([ + ("labels", [ + ("label", OrderedDict([ ("name", db_label.name), - ("attributes", OrderedDict([("attribute", db_attr.text) - for db_attr in db_label.attributespec_set.all()])) - ])) for db_label in db_labels] - )), + ("attributes", [("attribute", db_attr.text) + for db_attr in db_label.attributespec_set.all()]) + ])) for db_label in db_labels + ]), - ("segments", OrderedDict( - [("segment", OrderedDict([ + ("segments", [ + ("segment", OrderedDict([ ("id", str(db_segment.id)), ("start", str(db_segment.start_frame)), ("stop", str(db_segment.stop_frame)), ("url", "{0}://{1}/?id={2}".format( scheme, host, db_segment.job_set.all()[0].id)) - ])) for db_segment in db_segments] - )), + ])) for db_segment in db_segments + ]), ("owner", OrderedDict([ ("username", db_task.owner.username), diff --git a/cvat/apps/engine/task.py b/cvat/apps/engine/task.py index 4eda47fe8aa8..eb364814ad69 100644 --- a/cvat/apps/engine/task.py +++ b/cvat/apps/engine/task.py @@ -319,6 +319,7 @@ def _parse_db_labels(db_labels): @transaction.atomic def _create_thread(tid, params): + # TODO: Improve a function logic. Need filter paths from a share storage before their copy to the server db_task = db_task = models.Task.objects.select_for_update().get(pk=tid) upload_dir = db_task.get_upload_dirname() @@ -361,7 +362,9 @@ def _create_thread(tid, params): compress_quality = int(params.get('compress_quality', 50)) if mode == 'interpolation': - extractor = _FrameExtractor(params['TARGET_PATHS'][0], compress_quality, flip_flag) + # Last element in params['TARGET_PATHS'] must contain video due to a sort by path len above + # Early elements (if exist) contain parent dirs for video + extractor = _FrameExtractor(params['TARGET_PATHS'][-1], compress_quality, flip_flag) for frame, image_orig_path in enumerate(extractor): image_dest_path = _get_frame_path(frame, output_dir) db_task.size += 1