微軟發佈的 COCO 數據庫是一個大型圖像數據集, 專爲對象檢測、分割、人體關鍵點檢測、語義分割和字幕生成而設計。html
COCO 數據庫的網址是:python
COCO API 提供了 Matlab, Python 和 Lua 的 API 接口. 該 API 接口能夠提供完整的圖像標籤數據的加載, parsing 和可視化。此外,網站還提供了數據相關的文章, 教程等。git
在使用 COCO 數據庫提供的 API 和 demo 以前, 須要首先下載 COCO 的圖像和標籤數據(類別標誌、類別數量區分、像素級的分割等 ):github
coco/images/
文件夾中coco/annotations/
文件夾中下面咱們來探討一下如何利用 Python 來使用 COCO 數據集?數據庫
COCO API 對 WIndows 系統不是太友好,首先我先是 fork 了 COCO API,而後下載到本地,並切換到:D:\API\cocoapi\PythonAPI
。json
cd D:\API\cocoapi\PythonAPI
打開 Makefile 能夠看到 API 的安裝和使用說明。api
在 Windows 下直接運行 python setup.py build_ext --inplace
會報錯:數組
Windows 中 (通常須要安裝 visual studio)有許多的坑,參考 Windows 10 編譯 Pycocotools 踩坑記 暴力刪掉參數 Wno-cpp
和 Wno-unused-function
,以下圖所示:app
這樣,咱們即可以使用 pycocotools
,不過每次你想要調用 pycocotools
都須要先載入局部環境:dom
import sys sys.path.append('D:\API\cocoapi\PythonAPI') # 將你的 `pycocotools` 所在路徑添加到系統環境
若是你不想這麼麻煩,你能夠直接將 pycocotools
安裝在你的主環境下:
先切換到包所在路徑
cd D:\API\cocoapi\PythonAPI
而後,運行
python setup.py build_ext install rd build # 刪除
在 Linux 下,不須要上面這麼多編譯步驟,咱們直接在終端輸入下列命令便可正常使用 COCO API:
pip3 install -U Cython pip3 install -U pycocotools
下面你即可載入 pycocotools
了。
COCO API 能夠幫助你載入、解析和可視化 annotations。 該 API 支持 multiple annotation 格式 (詳情見 data format). 更多關於 API 的細節可參考 coco.py,同時你也能夠查看 Python API demo。
COCO API 的記號說明:
COCO 爲每一個實例對象提供分割掩碼(segmentation masks)。這就產生了兩個挑戰: 緊湊地存儲掩碼和高效地執行掩碼計算。 MASK API 使用自定義運行長度編碼 (Run Length Encoding, RLE) 方案解決這兩個難題。RLE 表示的大小與掩碼的邊界像素數成正比, 而且能夠在 RLE 上直接有效地計算操做 (如面積、聯合或交集)。具體來講, 假設 shapes 至關簡單, RLE 表示形式爲 \(O(\sqrt{n}\), 其中 \(n\) 是對象中的像素數, 而一般計算量一樣是 \(O(\sqrt{n})\)。在解碼掩碼 (存儲爲陣列) 上進行相同操做的天然的計算量將是 \(O(n)\)。
Mask API 提供了一個用於操做以 RLE 格式存儲的掩碼的接口。這個 API 被定義在 mask.py。最後, 大多數 ground truth masks 存儲爲多邊形 (至關緊湊), 這些多邊形在須要時轉換爲 RLE。
下面咱們來解讀一下 pycocoDemo.ipynb。因爲 COCO API 對 Windows 不是那麼友好,爲了不去調試各類 Bug,下面咱們先在 Linux 系統下來使用 COCO API。下面我是在 Jupyter Notebook 下運行代碼的。
%matplotlib inline import zipfile import os import numpy as np import skimage.io as io import matplotlib.pyplot as plt import pylab pylab.rcParams['figure.figsize'] = (8.0, 10.0) # ------------------- try: # pycocotools 已經加入了全局環境變量中 from pycocotools.coco import COCO except ModuleNotFoundError: import sys # 加載 COCO API 環境 sys.path.append('D:\API\cocoapi\PythonAPI') from pycocotools.coco import COCO root = 'E:/Data/coco' # 你下載的 COCO 數據集所在目錄 # 查看 images 下的圖片 os.listdir(f'{root}/images')
['test2014.zip', 'test2015.zip', 'test2017.zip', 'train2014.zip', 'train2017.zip', 'unlabeled2017.zip', 'val2014.zip', 'val2017.zip']
下面我以 val2017.zip
圖片數據集爲例,來講明下面的一些問題。
Z = zipfile.ZipFile(f'{root}/images/val2017.zip') Z.namelist()[7] # 查看一張圖片的文件名
'val2017/000000463918.jpg'
因爲 Z.read
函數返回的是 bytes
,因此,咱們須要藉助一些其餘模塊來將圖片數據轉換爲 np.uint8
形式。
img_b = Z.read(Z.namelist()[7]) print(type(img_b))
<class 'bytes'>
方式1:np.frombuffer(img_b, 'B')
import numpy as np import cv2 img_flatten = np.frombuffer(img_b, 'B') img_cv = cv2.imdecode(img_flatten, cv2.IMREAD_ANYCOLOR) print(img_cv.shape)
(359, 500, 3)
方式2:imageio.imread
import imageio img_io = imageio.imread(img_b) print(img_io.shape)
(359, 500, 3)
方式3:mxnet.image.imdecode
import mxnet as mx img_mx = mx.image.imdecode(img_b)
下面咱們來看看這張圖片張什麼樣?
from matplotlib import pyplot as plt plt.subplot(231) plt.imshow(cv2.cvtColor(img_cv, cv2.COLOR_BGR2RGB)) plt.title('OpenCV') plt.axis('off') plt.subplot(232) plt.imshow(img_io) plt.title('imageio') plt.axis('off') plt.subplot(233) plt.imshow(img_io) plt.title('MXNet') plt.axis('off') plt.show()
考慮到 OpenCV 的高效性,咱們採用方式1 來處理 images
下的圖片數據。
def buffer2array(Z, image_name): ''' 無需解壓,直接獲取圖片數據 參數 =========== Z:: 圖片數據是 ZipFile 對象 ''' buffer = Z.read(image_name) image = np.frombuffer(buffer, dtype="B") # 將 buffer 轉換爲 np.uint8 數組 img = cv2.imdecode(image, cv2.IMREAD_COLOR) return img img = buffer2array(Z, Z.namelist()[8]) print('圖片的尺寸:', img.shape)
圖片的尺寸: (480, 640, 3)
這裏有一個坑 (由 PIL 引起) import skimage.io as io
在 Windows 下可能會報錯,個人解決辦法是:
先卸載 Pillow,而後從新安裝便可。
插曲:PIL(Python Imaging Library)是Python一個強大方便的圖像處理庫,名氣也比較大。Pillow 是 PIL 的一個派生分支,但現在已經發展成爲比 PIL 自己更具活力的圖像處理庫。
dataDir = cocox.root dataType = 'val2017' annFile = '{}/annotations/instances_{}.json'.format(dataDir, dataType)
# initialize COCO api for instance annotations coco=COCO(annFile)
loading annotations into memory... Done (t=0.93s) creating index... index created!
COCO??
COCO
是一個類:
Constructor of Microsoft COCO helper class for reading and visualizing annotations. :param annotation_file (str): location of annotation file :param image_folder (str): location to the folder that hosts images.
cats = coco.loadCats(coco.getCatIds()) nms = [cat['name'] for cat in cats] print('COCO categories: \n{}\n'.format(' '.join(nms))) nms = set([cat['supercategory'] for cat in cats]) print('COCO supercategories: \n{}'.format(' '.join(nms)))
COCO categories: person bicycle car motorcycle airplane bus train truck boat traffic light fire hydrant stop sign parking meter bench bird cat dog horse sheep cow elephant bear zebra giraffe backpack umbrella handbag tie suitcase frisbee skis snowboard sports ball kite baseball bat baseball glove skateboard surfboard tennis racket bottle wine glass cup fork knife spoon bowl banana apple sandwich orange broccoli carrot hot dog pizza donut cake chair couch potted plant bed dining table toilet tv laptop mouse remote keyboard cell phone microwave oven toaster sink refrigerator book clock vase scissors teddy bear hair drier toothbrush COCO supercategories: appliance sports person indoor vehicle food electronic furniture animal outdoor accessory kitchen
# get all images containing given categories, select one at random catIds = coco.getCatIds(catNms=['person', 'dog', 'skateboard']) imgIds = coco.getImgIds(catIds=catIds) imgIds = coco.getImgIds(imgIds=[335328]) img = coco.loadImgs(imgIds[np.random.randint(0, len(imgIds))])[0]
img
{'license': 4, 'file_name': '000000335328.jpg', 'coco_url': 'http://images.cocodataset.org/val2017/000000335328.jpg', 'height': 640, 'width': 512, 'date_captured': '2013-11-20 19:29:37', 'flickr_url': 'http://farm3.staticflickr.com/2079/2128089396_ddd988a59a_z.jpg', 'id': 335328}
官方給的這個代碼須要將圖片數據集解壓:
# load and display image # use url to load image # I = io.imread(img['coco_url']) I = io.imread('%s/images/%s/%s' % (dataDir, dataType, img['file_name'])) plt.axis('off') plt.imshow(I) plt.show()
咱們可使用 zipfile
模塊直接讀取圖片,而無須解壓:
image_names[-1]
'E:/Data/coco/images/val2017.zip'
val_z = zipfile.ZipFile(image_names[-1]) I = image.imdecode(val_z.read('%s/%s' % (dataType, img['file_name']))).asnumpy() # 或者直接使用 I = buffer2array(val_z, val_z.namelist()[8]) plt.axis('off') plt.imshow(I) plt.show()
plt.imshow(I) plt.axis('off') annIds = coco.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None) anns = coco.loadAnns(annIds) coco.showAnns(anns)
初始化人體關鍵點標註(person keypoints annotations)的 COCO api
annFile = '{}/annotations/person_keypoints_{}.json'.format(dataDir, dataType) coco_kps = COCO(annFile)
loading annotations into memory... Done (t=0.43s) creating index... index created!
show:
plt.imshow(I) plt.axis('off') ax = plt.gca() annIds = coco_kps.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None) anns = coco_kps.loadAnns(annIds) coco_kps.showAnns(anns)
annFile = '{}/annotations/captions_{}.json'.format(dataDir, dataType) coco_caps = COCO(annFile)
loading annotations into memory... Done (t=0.06s) creating index... index created!
show:
annIds = coco_caps.getAnnIds(imgIds=img['id']) anns = coco_caps.loadAnns(annIds) coco_caps.showAnns(anns) plt.imshow(I) plt.axis('off') plt.show()
A couple of people riding waves on top of boards. a couple of people that are surfing in water A man and a young child in wet suits surfing in the ocean. a man and small child standing on a surf board and riding some waves A young boy on a surfboard being taught to surf.
我在 Github 上放置了一個倉庫:datasetsome,該倉庫存儲一些數據集處理相關的 API,若是感受對您有幫助,請給個 star。
你也能夠在線編輯:https://mybinder.org/v2/gh/DataLoaderX/datasetsome/master
除此以外,我還寫了一個 深度學習經常使用數據集 API。
爲了令 Windows 系統也能夠更好的使用 COCO 數據集,我打算開發一個能夠適用於 Windows 和 Linux 系統是 API,同時利用 Python 的 ZipFile
模塊直接讀取 images
下的圖片數據以及 annotations
下的標註數據。(直接跳過解壓這一費時的步驟)該 API 的更新我放置在了 cocox。歡迎你們閱覽!
COCO 數據集使用說明書 着重介紹了 cocoz.py
。
自制 COCO api 直接讀取類 COCO 的標註數據的壓縮文件 改進 ImageZ
,使其支持索引和切片以及迭代功能。爲了令其餘數據也可使用 ImageZ 類,我將 ImageZ
的輸入參數改成 images 所在路徑,其餘不變。同時,舉了一個 Kaggle 比賽的例子:Humpback Whale Identification 來講明 ImageZ
的通用性。
利用 ImageZ 與 MXNet 實戰 Kaggle 貓狗分類
更多的項目更新
建立計算機視覺社區:動手實踐計算機視覺。本社區歡迎你們貢獻與計算機視覺相關的代碼或者文檔,同時也歡迎你們分享一些有意思的 idea 或者 issue。還能夠在 gitter@cv-actions 或者 GitPress@cv_actions 交流計算機視覺學習心得。