From 6d623cf1ed08b0d4e4c96211a85f47fb4e0c498c Mon Sep 17 00:00:00 2001 From: Kai Chen Date: Sat, 6 Oct 2018 14:44:27 +0800 Subject: [PATCH] add some documentation --- docs/image.md | 110 +++++++++++++++++++++++++++++----------- docs/intro.md | 4 +- docs/io.md | 85 ++++++++++++++++++++++++------- docs/utils.md | 2 +- mmcv/runner/priority.py | 28 ++++++++-- 5 files changed, 174 insertions(+), 55 deletions(-) diff --git a/docs/image.md b/docs/image.md index cf56a61c3..6b83b04fb 100644 --- a/docs/image.md +++ b/docs/image.md @@ -1,6 +1,7 @@ ## Image -This module provides some image processing methods. +This module provides some image processing methods, which requires `opencv` to +to be installed. ### Read/Write/Show To read or write images files, use `imread` or `imwrite`. @@ -26,32 +27,13 @@ To show an image file or a loaded image ```python mmcv.imshow('tests/data/color.jpg') +# this is equivalent to for i in range(10): img = np.random.randint(256, size=(100, 100, 3), dtype=np.uint8) mmcv.imshow(img, win_name='test image', wait_time=200) ``` -### Resize -There are three resize methods. All `imresize_*` methods have a parameter `return_scale`, -if this param is `False`, then the return value is merely the resized image, otherwise -is a tuple (resized_img, scale). - -```python -# resize to a given size -mmcv.imresize(img, (1000, 600), return_scale=True) - -# resize to the same size of another image -mmcv.imresize_like(img, dst_img, return_scale=False) - -# resize by a ratio -mmcv.imrescale(img, 0.5) - -# resize so that the max edge no longer than 1000, short edge no longer than 800 -# without changing the aspect ratio -mmcv.imrescale(img, (1000, 800)) -``` - ### Color space conversion Supported conversion methods: - bgr2gray @@ -68,31 +50,99 @@ img2 = mmcv.rgb2gray(img1) img3 = mmcv.bgr2hsv(img) ``` +### Resize +There are three resize methods. All `imresize_*` methods have an argument `return_scale`, +if this argument is `False`, then the return value is merely the resized image, otherwise +is a tuple `(resized_img, scale)`. + +```python +# resize to a given size +mmcv.imresize(img, (1000, 600), return_scale=True) + +# resize to the same size of another image +mmcv.imresize_like(img, dst_img, return_scale=False) + +# resize by a ratio +mmcv.imrescale(img, 0.5) + +# resize so that the max edge no longer than 1000, short edge no longer than 800 +# without changing the aspect ratio +mmcv.imrescale(img, (1000, 800)) +``` + +### Rotate +To rotate an image by some angle, use `imrotate`. The center can be specified, +which is the center of original image by default. There are two modes of rotating, +one is to keep the image size unchanged so that some parts of the image will be +cropped after rotating, the other is to extend the image size to fit the rotated +image. + +```python +img = mmcv.imread('tests/data/color.jpg') + +# rotate the image clockwise by 30 degrees. +img_ = mmcv.imrotate(img, 30) + +# rotate the image counterclockwise by 90 degrees. +img_ = mmcv.imrotate(img, -90) + +# rotate the image clockwise by 30 degrees, and rescale it by 1.5x at the same time. +img_ = mmcv.imrotate(img, 30, scale=1.5) + +# rotate the image clockwise by 30 degrees, with (100, 100) as the center. +img_ = mmcv.imrotate(img, 30, center=(100, 100)) + +# rotate the image clockwise by 30 degrees, and extend the image size. +img_ = mmcv.imrotate(img, 30, auto_bound=True) +``` + +### Flip +To flip an image, use `imflip`. + +```python +img = mmcv.imread('tests/data/color.jpg') + +# flip the image horizontally +mmcv.imflip(img) + +# flip the image vertically +mmcv.imflip(img, direction='vertical') +``` + ### Crop -Support single/multiple crop. +`imcrop` can crop the image with one or some regions, represented as (x1, y1, x2, y2). ```python import mmcv import numpy as np img = mmcv.read_img('tests/data/color.jpg') -bboxes = np.array([10, 10, 100, 120]) # x1, y1, x2, y2 + +# crop the region (10, 10, 100, 120) +bboxes = np.array([10, 10, 100, 120]) patch = mmcv.crop_img(img, bboxes) + +# crop two regions (10, 10, 100, 120) and (0, 0, 50, 50) bboxes = np.array([[10, 10, 100, 120], [0, 0, 50, 50]]) patches = mmcv.crop_img(img, bboxes) -``` -Resizing cropped patches. -```python -# upsample patches by 1.2x +# crop two regions, and rescale the patches by 1.2x patches = mmcv.crop_img(img, bboxes, scale_ratio=1.2) ``` ### Padding -Pad an image to specific size with given values. +There are two methods `impad` and `impad_to_multiple` to pad an image to the +specific size with given values. ```python img = mmcv.read_img('tests/data/color.jpg') -img = mmcv.pad_img(img, (1000, 1200), pad_val=0) -img = mmcv.pad_img(img, (1000, 1200), pad_val=[100, 50, 200]) + +# pad the image to (1000, 1200) with all zeros +img_ = mmcv.pad_img(img, (1000, 1200), pad_val=0) + +# pad the image to (1000, 1200) with different values for three channels. +img_ = mmcv.pad_img(img, (1000, 1200), pad_val=[100, 50, 200]) + +# pad an image so that each edge is a multiple of some value. +img_ = mmcv.impad_to_multiple(img, 32) ``` \ No newline at end of file diff --git a/docs/intro.md b/docs/intro.md index 9e65c54d8..1da8bc950 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -1,4 +1,4 @@ -# Introduction +## Introduction `mmcv` is a foundational python library for computer vision research and supports many research projects in MMLAB, such as [mmdetection](https://github.com/open-mmlab/mmdetection). @@ -16,7 +16,7 @@ It provides the following functionalities. See the [documentation](http://mmcv.readthedocs.io/en/latest) for more features and usage. -## Installation +### Installation Try and start with diff --git a/docs/io.md b/docs/io.md index a9465d182..63f81f5c3 100644 --- a/docs/io.md +++ b/docs/io.md @@ -12,20 +12,73 @@ import mmcv # load data from a file data = mmcv.load('test.json') data = mmcv.load('test.yaml') -data = mmcv.load('test.pickle') +data = mmcv.load('test.pkl') # load data from a file-like object with open('test.json', 'r') as f: data = mmcv.load(f) # dump data to a string json_str = mmcv.dump(data, format='json') + # dump data to a file with a filename (infer format from file extension) -mmcv.dump(data, 'out.pickle') +mmcv.dump(data, 'out.pkl') + # dump data to a file with a file-like object with open('test.yaml', 'w') as f: data = mmcv.dump(data, f, format='yaml') ``` +It is also very convenient to extend the api to support more file formats. +All you need to do is to write a file handler inherited from `BaseFileHandler` +and register it with one or several file formats. + +You need to implement at least 3 methods. + +```python +import mmcv + +# To register multiple file formats, a list can be used as the argument. +# @mmcv.register_handler(['txt', 'log']) +@mmcv.register_handler('txt') +class TxtHandler1(mmcv.BaseFileHandler): + + def load_from_fileobj(self, file): + return file.read() + + def dump_to_fileobj(self, obj, file): + file.write(str(obj)) + + def dump_to_str(self, obj, **kwargs): + return str(obj) +``` + +Here is an example of `PickleHandler`. + +```python +from six.moves import cPickle as pickle + +class PickleHandler(mmcv.BaseFileHandler): + + def load_from_fileobj(self, file, **kwargs): + return pickle.load(file, **kwargs) + + def load_from_path(self, filepath, **kwargs): + return super(PickleHandler, self).load_from_path( + filepath, mode='rb', **kwargs) + + def dump_to_str(self, obj, **kwargs): + kwargs.setdefault('protocol', 2) + return pickle.dumps(obj, **kwargs) + + def dump_to_fileobj(self, obj, file, **kwargs): + kwargs.setdefault('protocol', 2) + pickle.dump(obj, file, **kwargs) + + def dump_to_path(self, obj, filepath, **kwargs): + super(PickleHandler, self).dump_to_path( + obj, filepath, mode='wb', **kwargs) +``` + ### Load a text file as a list or dict For example `a.txt` is a text file with 5 lines. @@ -40,16 +93,14 @@ e Then use `list_from_file` to load the list from a.txt. ```python -import mmcv - -mmcv.list_from_file('a.txt') -# output ['a', 'b', 'c', 'd', 'e'] -mmcv.list_from_file('a.txt', offset=2) -# output ['c', 'd', 'e'] -mmcv.list_from_file('a.txt', max_num=2) -# output ['a', 'b'] -mmcv.list_from_file('a.txt', prefix='/mnt/') -# output ['/mnt/a', '/mnt/b', '/mnt/c', '/mnt/d', '/mnt/e'] +>>> mmcv.list_from_file('a.txt') +['a', 'b', 'c', 'd', 'e'] +>>> mmcv.list_from_file('a.txt', offset=2) +['c', 'd', 'e'] +>>> mmcv.list_from_file('a.txt', max_num=2) +['a', 'b'] +>>> mmcv.list_from_file('a.txt', prefix='/mnt/') +['/mnt/a', '/mnt/b', '/mnt/c', '/mnt/d', '/mnt/e'] ``` For example `b.txt` is a text file with 5 lines. @@ -62,10 +113,8 @@ For example `b.txt` is a text file with 5 lines. Then use `dict_from_file` to load the list from a.txt. ```python -import mmcv - -mmcv.dict_from_file('b.txt') -# output {'1': 'cat', '2': ['dog', 'cow'], '3': 'panda'} -mmcv.dict_from_file('b.txt', key_type=int) -# output {1: 'cat', 2: ['dog', 'cow'], 3: 'panda'} +>>> mmcv.dict_from_file('b.txt') +{'1': 'cat', '2': ['dog', 'cow'], '3': 'panda'} +>>> mmcv.dict_from_file('b.txt', key_type=int) +{1: 'cat', 2: ['dog', 'cow'], 3: 'panda'} ``` diff --git a/docs/utils.md b/docs/utils.md index 6e4999d40..180dd4388 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -3,7 +3,7 @@ ### Config `Config` class is used for manipulating config and config files. It supports -loading configs from multiple file formats including python scripts, json file and yaml file. +loading configs from multiple file formats including **python**, **json** and **yaml**. It provides dict-like apis to get and set values. Here is an example of the config file `test.py`. diff --git a/mmcv/runner/priority.py b/mmcv/runner/priority.py index cbfedf160..caf14395c 100644 --- a/mmcv/runner/priority.py +++ b/mmcv/runner/priority.py @@ -2,13 +2,33 @@ from enum import Enum class Priority(Enum): + """Hook priority levels. + + +------------+------------+ + | Level | Value | + +============+============+ + | HIGHEST | 0 | + +------------+------------+ + | VERY_HIGH | 10 | + +------------+------------+ + | HIGH | 30 | + +------------+------------+ + | NORMAL | 50 | + +------------+------------+ + | LOW | 70 | + +------------+------------+ + | VERY_LOW | 90 | + +------------+------------+ + | LOWEST | 100 | + +------------+------------+ + """ HIGHEST = 0 - VERY_HIGH = 20 - HIGH = 40 + VERY_HIGH = 10 + HIGH = 30 NORMAL = 50 - LOW = 60 - VERY_LOW = 80 + LOW = 70 + VERY_LOW = 90 LOWEST = 100