在 PyTorch 中使用 Detectron2 进行对象检测的指南
介绍 Detectron2
安装
torch.__version__
import torchvision
#torchvision.__version__
!pip install detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu102/torch1.7/index.html
from detectron2.utils.logger import setup_logger
setup_logger()
%matplotlib inline
from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.utils.visualizer import Visualizer
from detectron2.data import MetadataCatalog, DatasetCatalog
from detectron2.structures import BoxMode
import os, json, cv2, random
import matplotlib.pyplot as plt
使用预训练模型进行推理:代码
cfg.merge_from_file(model_zoo.get_config_file('COCOInstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml'))
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url('COCOInstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml')
im = cv2.imread('./input.jpg')
print(im.shape)
plt.figure(figsize=(15,7.5))
plt.imshow(im[..., ::-1])
out = v.draw_instance_predictions(outputs['instances'].to('cpu'))
plt.figure(figsize=(20,10))
plt.imshow(out.get_image()[..., ::-1][..., ::-1])
自定义数据集上的 Detectron2
准备数据集
!unzip balloon_dataset.zip > /dev/null
def get_balloon_images(img_folder):
json_file = os.path.join(img_folder, 'via_region_data.json')
with open(json_file) as f:
imgs_anns = json.load(f)
dataset_dicts = []
for idx, v in enumerate(imgs_anns.values()):
record = {}
filename = os.path.join(img_dir, v['filename'])
height, width = cv2.imread(filename).shape[:2]
record['file_name'] = filename
record['image_id'] = idx
record['height'] = height
record['width'] = width
annos = v['regions']
objs = []
for _, anno in annos.items():
assert not anno['region_attributes']
anno = anno['shape_attributes']
px = anno['all_points_x']
py = anno['all_points_y']
poly = [(x + 0.5, y + 0.5) for x, y in zip(px, py)]
poly = [p for x in poly for p in x]
obj = {
'bbox': [np.min(px), np.min(py), np.max(px), np.max(py)],
'bbox_mode': BoxMode.XYXY_ABS,
'segmentation': [poly],
'category_id': 0,
}
objs.append(obj)
record['annotations'] = objs
dataset_dicts.append(record)
return dataset_dicts
DatasetCatalog.register('balloon_' + d, lambda d=d: get_balloon_images('balloon/' + d))
MetadataCatalog.get('balloon_' + d).set(thing_classes=['balloon'])
balloon_metadata = MetadataCatalog.get('balloon_train')
训练数据可视化
for d in random.sample(dataset_dicts, 3):
img = cv2.imread(d['file_name'])
visualizer = Visualizer(img[:, :, ::-1], metadata=balloon_metadata, scale=0.5)
out = visualizer.draw_dataset_dict(d)
plt.figure(figsize=(15,7))
plt.imshow(out.get_image()[:, :, ::-1][..., ::-1])
自定义数据训练
cfg = get_cfg()
cfg.merge_from_file(model_zoo.get_config_file('COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml'))
cfg.DATASETS.TRAIN = ('balloon_train',)
cfg.DATASETS.TEST = ()
cfg.DATALOADER.NUM_WORKERS = 6
# Let training initialize from model zoo
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url('COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml')
cfg.SOLVER.IMS_PER_BATCH = 8
cfg.SOLVER.BASE_LR = 0.001
cfg.SOLVER.MAX_ITER = 500
cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 128 # faster, enough for this dataset (default: 512)
cfg.MODEL.ROI_HEADS.NUM_CLASSES = 1 #only one class (balloon)
os.makedirs(cfg.OUTPUT_DIR, exist_ok=True)
trainer = DefaultTrainer(cfg)
trainer.resume_or_load(resume=False)
trainer.train()
结果
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 # set a testing threshold
predictor = DefaultPredictor(cfg)
from detectron2.utils.visualizer import ColorMode
dataset_dicts = get_balloon_images('balloon/val')
for d in random.sample(dataset_dicts, 2):
im = cv2.imread(d['file_name'])
outputs = predictor(im)
v = Visualizer(im[:, :, ::-1],
metadata=balloon_metadata,
scale=0.5,
instance_mode=ColorMode.IMAGE_BW
)
out = v.draw_instance_predictions(outputs['instances'].to('cpu'))
plt.figure(figsize=(15,7))
plt.imshow(out.get_image()[:, :, ::-1][..., ::-1])
赞 (0)