先佔個坑,國慶假期的時候來寫。
10月16號,終於打開了CSDN,想起了還有一篇沒寫的博客
本文適合一些小白看,比較簡單,稍微改一下別人的示例代碼就行。
之前做了點腫瘤檢測的工作,就是在圖上把腫瘤的位置用邊界框標出來,用自己的數據做成了VOC格式,然後訓練了faster R-CNN,結果還行。下面要做的工作是在之前的基礎上,還要把腫瘤勾畫出來,所以就要用到mask R-CNN了,這時候數據就成了問題。用VOC的公開數據集訓練mask R-CNN的時候就不太順利,更不用說訓練自己的數據了。於是直接轉戰COCO格式的數據,畢竟R-CNN一系列的很多模型都是用COCO數據集預訓練的。
那麼問題來了,該怎麼製作自己的COCO數據集,看了很多博客,都沒看懂,千辛萬苦下,終於找到了一個有用的教程!!
參考https://patrickwasp.com/create-your-own-coco-style-dataset/
可以下載pycococreator-master這個python工具包。
這裏展示了一個關於形狀數據集的例子,是一個三分類的數據集,分別爲三角,圓形,正方形。需要準備的就是原圖和對應的mask,如圖所示: shapes_train2018放的是原圖,這裏有兩張圖,annotations存放的就是對應的mask。
1001.jpeg裏面有四個實例,所以它對應的mask就有四幅圖。1001.jpeg和對應的mask如下所示:
然後圖像的命名也有要求,1001.jpeg的mask的文件名中必須有1001,後面的circle,square就是類別的名字。準備好後,代碼會根據你的命名來尋找對應圖像的標籤文件。
準備好自己的數據以及對應的標籤後,就要運行工具包中的 shapes_to_coco.py 文件了
#!/usr/bin/env python3
import datetime
import json
import os
import re
import fnmatch
from PIL import Image
import numpy as np
from pycococreatortools import pycococreatortools
# 這裏設置一些文件路徑
ROOT_DIR = 'train' # 根目錄
IMAGE_DIR = os.path.join(ROOT_DIR, "shapes_train2018") # 根目錄下存放你原圖的文件夾
ANNOTATION_DIR = os.path.join(ROOT_DIR, "annotations") # 根目錄下存放mask標籤的文件夾
# 這裏就是填一些有關你數據集的信息
INFO = {
"description": "Example Dataset",
"url": "https://github.com/waspinator/pycococreator",
"version": "0.1.0",
"year": 2018,
"contributor": "waspinator",
"date_created": datetime.datetime.utcnow().isoformat(' ')
}
LICENSES = [
{
"id": 1,
"name": "Attribution-NonCommercial-ShareAlike License",
"url": "http://creativecommons.org/licenses/by-nc-sa/2.0/"
}
]
# 這裏是你數據集的類別,這裏有三個分類,就是square, circle, triangle。製作自己的數據集主要改這裏就行了
CATEGORIES = [
{
'id': 1,
'name': 'square',
'supercategory': 'shape',
},
{
'id': 2,
'name': 'circle',
'supercategory': 'shape',
},
{
'id': 3,
'name': 'triangle',
'supercategory': 'shape',
},
]
def filter_for_jpeg(root, files):
file_types = ['*.jpeg', '*.jpg']
file_types = r'|'.join([fnmatch.translate(x) for x in file_types])
files = [os.path.join(root, f) for f in files]
files = [f for f in files if re.match(file_types, f)]
return files
def filter_for_annotations(root, files, image_filename):
file_types = ['*.png']
file_types = r'|'.join([fnmatch.translate(x) for x in file_types])
basename_no_extension = os.path.splitext(os.path.basename(image_filename))[0]
file_name_prefix = basename_no_extension + '.*'
files = [os.path.join(root, f) for f in files]
files = [f for f in files if re.match(file_types, f)]
files = [f for f in files if re.match(file_name_prefix, os.path.splitext(os.path.basename(f))[0])]
return files
def main():
coco_output = {
"info": INFO,
"licenses": LICENSES,
"categories": CATEGORIES,
"images": [],
"annotations": []
}
image_id = 1
segmentation_id = 1
# filter for jpeg images
for root, _, files in os.walk(IMAGE_DIR):
image_files = filter_for_jpeg(root, files)
# go through each image
for image_filename in image_files:
image = Image.open(image_filename)
image_info = pycococreatortools.create_image_info(
image_id, os.path.basename(image_filename), image.size)
coco_output["images"].append(image_info)
# filter for associated png annotations
for root, _, files in os.walk(ANNOTATION_DIR):
annotation_files = filter_for_annotations(root, files, image_filename)
# go through each associated annotation
for annotation_filename in annotation_files:
print(annotation_filename)
class_id = [x['id'] for x in CATEGORIES if x['name'] in annotation_filename][0]
category_info = {'id': class_id, 'is_crowd': 'crowd' in image_filename}
binary_mask = np.asarray(Image.open(annotation_filename)
.convert('1')).astype(np.uint8)
annotation_info = pycococreatortools.create_annotation_info(
segmentation_id, image_id, category_info, binary_mask,
image.size, tolerance=2)
if annotation_info is not None:
coco_output["annotations"].append(annotation_info)
segmentation_id = segmentation_id + 1
image_id = image_id + 1
with open('{}/instances_shape_train2018.json'.format(ROOT_DIR), 'w') as output_json_file:
json.dump(coco_output, output_json_file)
if __name__ == "__main__":
main()
最終生成的訓練數據的json文件就是上面代碼中的instances_shape_train2018.json,製作自己的數據集的時候,可以先準備一個空的.json文件放在那,程序執行完,就能把你的標註信息都寫進去了。
然後我也展示一下自己的數據吧。文件結構如圖:
訓練數據和測試數據都生成了json文件。我的原圖是81-1.png,mask文件是81-1tumor.png,因爲我的圖只有tumor一個類別,並且每一幅圖中都只有一個tumor,所以對應的mask文件也只有一個。
下面是我的原圖和標籤圖,左邊是肺部的圖,右邊是腫瘤的mask。
看到生成的json文件裏這些密密麻麻的座標有木有很開心!mask R-CNN終於可以訓練起來了。
另外:我也剛開始用醫學圖像做目標檢測相關的工作,把dcm轉成png做的,有做相關方向的同學可以一起討論。