mmcv庫的中文文檔


之前自己實現了一遍mmcv這個庫,現在把API文檔翻譯一遍。
項目github地址:https://github.com/open-mmlab/mmcv
發現這個庫的安裝的時候常常很麻煩,因為太經常更新了,但其實核心部分也就下面這些功能嗷。
 
一、File IO
(1)這個模塊提供常用的各種文件的加載和復制:比如json/yaml/pkl文件。
import mmcv #從文件中加載數據
data = mmcv.load('test.json') data = mmcv.load('test.yaml') data = mmcv.load('test.pkl') #從類文件對象加載數據
with open('test.json', 'r') as f: data = mmcv.load(f) #復制數據到字符串文件
json_str = mmcv.dump(data, file_formate='json') mmcv.dump(data, 'out.pkl') #使用類文件對象將數據轉儲到文件中 
with open('test.yaml', 'w') as f: data = mmcv.dump(data, f, file_format='yaml')
擴展api以支持更多的文件格式也非常方便。您所需要做的就是編寫一個繼承自BaseFileHandler的文件處理程序,並用一種或幾種文件格式注冊它。
您需要實現至少3個方法。
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)
下面是PickleHandler的一個示例。
import 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)
 
(2)以列表或字典的形式加載文本文件
例如,a.txt是一個5行文本文件。
a b c d e
然后使用list_from_file從a.txt加載列表。
>>> 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']
例如,b.txt是一個有3行文本文件。
1 cat 2 dog cow 3 panda
然后使用dict_from_file從b.txt加載列表。
>>> 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'}
 
二、Imgae
這個模塊提供了一些圖像處理方法,需要安裝opencv。
(1)讀/寫/顯示圖像
要讀取或寫入圖像文件,請使用imread或imwrite。
import mmcv
img = mmcv.imread('test.jpg')
img = mmcv.imread('test.jpg', flag='grayscale')
img_ = mmcv.imread(img) # nothing will happen, img_ = img
mmcv.imwrite(img, 'out.jpg')
從字節中讀取圖像
with open('test.jpg', 'rb') as f:
    data = f.read()
img = mmcv.imfrombytes(data)
顯示一個圖像文件或加載的圖像
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)
(2)顏色空間變換
提供下列的方法
bgr2gray
gray2bgr
bgr2rgb
rgb2bgr
bgr2hsv
hsv2bgr
img = mmcv.imread('tests/data/color.jpg')
img1 = mmcv.bgr2rgb(img)
img2 = mmcv.rgb2gray(img1)
img3 = mmcv.bgr2hsv(img)
(3)縮放
有三個調整大小的方法。所有的imresize_*方法都有一個參數return_scale,如果這個參數是假的,那么返回值僅僅是調整大小的圖像,否則是一個元組(resized_img, scale)。
# 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))
(4)旋轉
使用imrotate旋轉圖像以一定角度旋轉。可以指定中心,默認為原始圖像的中心。旋轉有兩種方式,一種是保持圖像大小不變,這樣旋轉后圖像的某些部分會被裁剪,另一種是擴展圖像大小以適應旋轉后的圖像。
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)
(5)翻轉
要翻轉圖像,請使用imflip。
img = mmcv.imread('tests/data/color.jpg')

# flip the image horizontally
mmcv.imflip(img)

# flip the image vertically
mmcv.imflip(img, direction='vertical')
(6)剪裁
imcrop可以用一個或一些區域來裁剪圖像,表示為(x1, y1, x2, y2)。
import mmcv
import numpy as np

img = mmcv.imread('tests/data/color.jpg')

# crop the region (10, 10, 100, 120)
bboxes = np.array([10, 10, 100, 120])
patch = mmcv.imcrop(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.imcrop(img, bboxes)

# crop two regions, and rescale the patches by 1.2x
patches = mmcv.imcrop(img, bboxes, scale_ratio=1.2)
(7)填充
有兩個方法impad和impad_to_multiple可以用給定的值將圖像填充到特定大小。
img = mmcv.imread('tests/data/color.jpg')

# pad the image to (1000, 1200) with all zeros
img_ = mmcv.impad(img, shape=(1000, 1200), pad_val=0)

# pad the image to (1000, 1200) with different values for three channels.
img_ = mmcv.impad(img, shape=(1000, 1200), pad_val=[100, 50, 200])

# pad the image on left, right, top, bottom borders with all zeros
img_ = mmcv.impad(img, padding=(10, 20, 30, 40), pad_val=0)

# pad the image on left, right, top, bottom borders with different values
# for three channels.
img_ = mmcv.impad(img, padding=(10, 20, 30, 40), 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)
 
三、Video
此模塊提供以下功能。
1、一個VideoReader類,具有友好的api來讀取和轉換視頻。
2、剪輯(剪切,concat,調整大小)視頻的一些方法。
3、光流讀/寫/變形。
(1)視頻讀取
VideoReader類提供了類似api的序列來訪問視頻幀。它將在內部緩存已訪問的幀
video = mmcv.VideoReader('test.mp4')

# obtain basic information
print(len(video))
print(video.width, video.height, video.resolution, video.fps)

# iterate over all frames
for frame in video:
    print(frame.shape)

# read the next frame
img = video.read()

# read a frame by index
img = video[100]

# read some frames
img = video[5:10]
將視頻轉換為圖像或從圖像目錄生成視頻。
# split a video into frames and save to a folder
video = mmcv.VideoReader('test.mp4')
video.cvt2frames('out_dir')

# generate video from frames
mmcv.frames2video('out_dir', 'test.avi')
(2)操作視頻
還有一些用於編輯視頻的方法,它們包裝了ffmpeg的命令。
# cut a video clip
mmcv.cut_video('test.mp4', 'clip1.mp4', start=3, end=10, vcodec='h264')

# join a list of video clips
mmcv.concat_video(['clip1.mp4', 'clip2.mp4'], 'joined.mp4', log_level='quiet')

# resize a video with the specified size
mmcv.resize_video('test.mp4', 'resized1.mp4', (360, 240))

# resize a video with a scaling ratio of 2
mmcv.resize_video('test.mp4', 'resized2.mp4', ratio=2)

 

(3)光流操作
我們提供了兩個選項來轉儲光流文件:未壓縮和壓縮。未壓縮的方法只是將浮點數轉儲到二進制文件中。它是無損的,但轉儲文件有一個更大的大小。這種壓縮方法將光流量化到0-255,並將其轉儲為jpeg圖像。x-dim和y-dim的流程將被連接成一個單獨的圖像。
flow = np.random.rand(800, 600, 2).astype(np.float32)
# dump the flow to a flo file (~3.7M)
mmcv.flowwrite(flow, 'uncompressed.flo')
# dump the flow to a jpeg file (~230K)
# the shape of the dumped image is (800, 1200)
mmcv.flowwrite(flow, 'compressed.jpg', quantize=True, concat_axis=1)

# read the flow file, the shape of loaded flow is (800, 600, 2) for both ways
flow = mmcv.flowread('uncompressed.flo')
flow = mmcv.flowread('compressed.jpg', quantize=True, concat_axis=1)
使用mmcv.flowshow()可以可視化光流。
mmcv.flowshow(flow)
 
四、可視化
mmcv可以顯示圖像和注釋(當前支持的類型包括邊框)。
# show an image file
mmcv.imshow('a.jpg')

# show a loaded image
img = np.random.rand(100, 100, 3)
mmcv.imshow(img)

# show image with bounding boxes
img = np.random.rand(100, 100, 3)
bboxes = np.array([[0, 0, 50, 50], [20, 20, 60, 60]])
mmcv.imshow_bboxes(img, bboxes)
mmcv還可以可視化特殊的圖像,如光流。
flow = mmcv.flowread('test.flo') mmcv.flowshow(flow)

 

五、Utils
(1)Config配置這個類很經常拿來使用配置網絡
Config類用於操作配置和配置文件。它支持從多種文件格式加載config,包括python、json和yaml。它提供了類似dict的api來獲取和設置值。
下面是配置文件test.py的示例。
a = 1
b = dict(b1=[0, 1, 2], b2=None)
c = (1, 2)
d = 'string'
>>> cfg = Config.fromfile('test.py')
>>> print(cfg)
>>> dict(a=1,
...      b=dict(b1=[0, 1, 2], b2=None),
...      c=(1, 2),
...      d='string')
對於所有的配置格式,都支持一些預定義的變量。它將{{var}}中的變量與它的實際值進行轉換。
目前,它支持四個預定義變量:
{{fileDirname}} -當前打開文件的dirname,例如/home/your-username/your-project/文件夾
{{fileBasename}} -當前打開文件的basename,例如file.ext
{{fileBasenameNoExtension}} -當前打開文件的basename,不帶文件擴展名,例如file
{{fileExtname}} -當前打開文件的擴展名,例如.ext
這些變量名是從VS代碼中引用的。
下面是一個帶有預定義變量的配置示例。
config_a.py
a = 1
b = './work_dir/{{ fileBasenameNoExtension }}'
c = '{{ fileExtname }}'
>>> cfg = Config.fromfile('./config_a.py')
>>> print(cfg)
>>> dict(a=1,
...      b='./work_dir/config_a',
...      c='.py')
對於所有的配置格式,都支持繼承。要在其他配置文件中重用字段,請指定_base_='./config_a。或一個configs _base_=['./config_a的列表。py”、“。/ config_b.py ']。下面是4個配置繼承的例子。
第一類:從基本配置繼承,沒有重疊的鍵
config_a.py
a = 1
b = dict(b1=[0, 1, 2], b2=None)
config_b.py
_base_ = './config_a.py'
c = (1, 2)
d = 'string'
>>> cfg = Config.fromfile('./config_b.py')
>>> print(cfg)
>>> dict(a=1,
...      b=dict(b1=[0, 1, 2], b2=None),
...      c=(1, 2),
...      d='string')
config_b.py中的新字段與config_a.py中的舊字段結合在一起
第二類:從基礎配置繼承重疊的鍵
config_c.py
_base_ = './config_a.py'
b = dict(b2=1)
c = (1, 2)
>>> cfg = Config.fromfile('./config_c.py')
>>> print(cfg)
>>> dict(a=1,
...      b=dict(b1=[0, 1, 2], b2=1),
...      c=(1, 2))
config_c.py中的b.b b2=1替換config_a中的b.b b2=1。
第三類:從忽略字段的基本配置繼承
config_d.py
_base_ = './config_a.py'
b = dict(_delete_=True, b2=None, b3=0.1)
c = (1, 2)
>>> cfg = Config.fromfile('./config_d.py')
>>> print(cfg)
>>> dict(a=1,
...      b=dict(b2=None, b3=0.1),
...      c=(1, 2))
還可以設置_delete_=True來忽略基配置中的一些字段。b中的所有舊鍵b1, b2, b3都被替換為新鍵b2, b3。
第四類:繼承多個基配置(基配置不應該包含相同的鍵)
config_e.py
c = (1, 2)
d = 'string'
config_f.py
_base_ = ['./config_a.py', './config_e.py']
>>> cfg = Config.fromfile('./config_f.py')
>>> print(cfg)
>>> dict(a=1,
...      b=dict(b1=[0, 1, 2], b2=None),
...      c=(1, 2),
...      d='string')
(2)進度條
如果您想對項目列表應用一個方法並跟蹤進度,track_progress是一個不錯的選擇。它將顯示一個進度條來告知進度和ETA。
import mmcv
def func(item):
    # do something
    pass
tasks = [item_1, item_2, ..., item_n]
mmcv.track_progress(func, tasks)
還有另一個方法track_parallel_progress,它包裝了多處理和進程可視化。
mmcv.track_parallel_progress(func, tasks, 8)  # 8 workers
如果您想迭代或枚舉一列項目並跟蹤進度,track_iter_progress是一個不錯的選擇。它將顯示一個進度條來告知進度和ETA。
import mmcv

tasks = [item_1, item_2, ..., item_n]

for task in mmcv.track_iter_progress(tasks):
    # do something like print
    print(task)

for i, task in enumerate(mmcv.track_iter_progress(tasks)):
    # do something like print
    print(i)
    print(task)
(3)計時器
用計時器計算代碼塊的運行時間是方便的。
import time
with mmcv.Timer():
    # simulate some code block
    time.sleep(1)
或者嘗試使用since_start()和since_last_check()。前者可以返回自計時器啟動以來的運行時,后者將返回自上次檢查以來的時間。
timer = mmcv.Timer()
# code block 1 here
print(timer.since_start())
# code block 2 here
print(timer.since_last_check())
print(timer.since_start())

 

六、Runner
runner模塊旨在幫助用戶用更少的代碼開始訓練,同時保持靈活性和可配置性。
文檔和示例仍在更新中。
 
七、Register
MMCV實現了registry來管理在檢測器中共享類似功能的不同模塊,如backbone、head和neck。OpenMMLab中的大多數項目都使用注冊表來管理數據集和模型模塊,如MMDetection、MMDetection3D、MMClassification、MMEditing等。
什么是register?
在MMCV中,registry可以看作是類到字符串的映射。單個注冊表包含的這些類通常具有類似的api,但實現不同的算法或支持不同的數據集。使用注冊表,用戶可以通過相應的字符串查找和實例化類,並根據需要使用實例化的模塊。一個典型的例子是大多數OpenMMLab項目中的配置系統,它們使用注冊表通過配置創建鈎子(hook)、運行器(runner)、模型(model)和數據集(datasets)。
要通過注冊表管理代碼基中的模塊,有如下三個步驟。
(1)創建一個注冊表
(2)創建一個構建方法
(3)使用這個注冊表來管理模塊
一個簡單的例子:這里我們展示了一個使用registry管理包中的模塊的簡單示例。您可以在OpenMMLab項目中找到更多實際的示例。
假設我們希望實現一系列數據集轉換器,用於將不同格式的數據轉換為預期的數據格式。我們將目錄創建為一個名為converters的包。在包中,我們首先創建一個文件來實現構建器,名為converters/builder.py。如下所示。
from mmcv.utils import Registry
# create a registry for converters
CONVERTERS = Registry('converter')
# create a build function
def build_converter(cfg, *args, **kwargs):
    cfg_ = cfg.copy()
    converter_type = cfg_.pop('type')
    if converter_type not in CONVERTERS:
        raise KeyError(f'Unrecognized task type {converter_type}')
    else:
        converter_cls = CONVERTERS.get(converter_type)
    converter = converter_cls(*args, **kwargs, **cfg_)
    return converter
然后我們可以在包中實現不同的轉換器。例如,在converters/ Converter1 .py中實現Converter1
from .builder import CONVERTERS
# use the registry to namge the module
@CONVERTERS.register_module()
class Converter1(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
使用registry管理模塊的關鍵步驟是在創建模塊時通過@CONVERTERS.register_module()將實現的模塊注冊到注冊表轉換器中。如果模塊注冊成功,您可以通過configs as使用這個轉換器
converter_cfg = dict(type='Converter1', a=a_value, b=b_value)
converter = build_converter(converter_cfg)
 
八、CNN
我們提供了一些CNNs的構建塊,包括層構建、模塊捆綁和權重初始化。
(1)構建層
在運行實驗時,我們可能需要嘗試相同類型的不同層,但不希望不時地修改代碼。這里我們提供了一些從dict構建層的方法,dict可以用configs編寫,也可以通過命令行參數指定
cfg = dict(type='Conv3d')
layer = build_norm_layer(cfg, in_channels=3, out_channels=8, kernel_size=3)
build_conv_layer: Supported types are Conv1d, Conv2d, Conv3d, Conv (alias for Conv2d).
build_norm_layer: Supported types are BN1d, BN2d, BN3d, BN (alias for BN2d), SyncBN, GN, LN, IN1d, IN2d, IN3d, IN (alias for IN2d).
build_activation_layer: Supported types are ReLU, LeakyReLU, PReLU, RReLU, ReLU6, ELU, Sigmoid, Tanh.
build_upsample_layer: Supported types are nearest, bilinear, deconv, pixel_shuffle.
build_padding_layer: Supported types are zero, reflect, replicate.
我們還允許使用定制的層和操作符擴展構建方法。
編寫和注冊您自己的模塊。
from mmcv.cnn import UPSAMPLE_LAYERS
@UPSAMPLE_LAYERS.register_module()
class MyUpsample:
    def __init__(self, scale_factor):
        pass
    def forward(self, x):
        pass
將MyUpsample導入到某個地方(例如,在__init__.py中),然后使用它。
cfg = dict(type='MyUpsample', scale_factor=2)
layer = build_upsample_layer(cfg)
(2)模塊捆綁
我們還提供了通用模塊包,方便網絡建設。ConvModule是卷積層、歸一化層和激活層的捆綁,詳細請參考api。
# conv + bn + relu
conv = ConvModule(3, 8, 2, norm_cfg=dict(type='BN'))
# conv + gn + relu
conv = ConvModule(3, 8, 2, norm_cfg=dict(type='GN', num_groups=2))
# conv + relu
conv = ConvModule(3, 8, 2)
# conv
conv = ConvModule(3, 8, 2, act_cfg=None)
# conv + leaky relu
conv = ConvModule(3, 8, 3, padding=1, act_cfg=dict(type='LeakyReLU'))
# bn + conv + relu
conv = ConvModule(
    3, 8, 2, norm_cfg=dict(type='BN'), order=('norm', 'conv', 'act'))
(3)權重初始化
constant_init
xavier_init
normal_init
uniform_init
kaiming_init
caffe2_xavier_init
bias_init_with_prob
conv1 = nn.Conv2d(3, 3, 1)
normal_init(conv1, std=0.01, bias=0)
xavier_init(conv1, distribution='uniform')
(4)除了torchvision的預訓練模型,我們還提供以下CNN的預訓練模型:
VGG Caffe
ResNet Caffe
ResNeXt
ResNet with Group Normalization
ResNet with Group Normalization and Weight Standardization
HRNetV2
Res2Net
RegNet
MMCV中的模型zoo鏈接由JSON文件管理。json文件由模型名稱及其url或路徑的鍵-值對組成。一個json文件:
{
    "model_a": "https://example.com/models/model_a_9e5bac.pth",
    "model_b": "pretrain/model_b_ab3ef2c.pth"
}
OpenMMLab AWS上托管的預訓練模型的默認鏈接可以在這里找到。
你可以通過打開mmlab來覆蓋默認鏈接。json MMCV_HOME之下。如果在環境中找不到MMCV_HOME,則為~/。默認使用cache/mmcv。您可以導出MMCV_HOME=/your/path來使用自己的路徑。外部json文件將合並到默認文件中。如果在外部json和默認json中都有相同的鍵,那么將使用外部鍵。
(5)加載權重
mmcv.load_checkpoint()的文件名參數支持以下類型。
(1)文件路徑:checkpoint的文件路徑。
(2)http://xxx和https://xxx:下載checkpoint的鏈接。SHA256后綴應該包含在文件名中。
(3)torchvision//xxx:模型鏈接在torchvision.models中。詳情請參閱torchvision。
(4)open-mmlab://xxx:默認和其他json文件中提供的模型鏈接或文件路徑。
 
九、我們實現了常用CUDA ops在檢測、分割等方面的應用。
BBoxOverlaps
CARAFE
CrissCrossAttention
ContextBlock
CornerPool
Deformable Convolution v1/v2
Deformable RoIPool
GeneralizedAttention
MaskedConv
NMS
PSAMask
RoIPool
RoIAlign
SimpleRoIAlign
SigmoidFocalLoss
SoftmaxFocalLoss
SoftNMS
Synchronized BatchNorm
Weight standardization
 
 
 
 
 
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM