Windows10安装mmrotate的步骤其实和linux一样的
首先检查自己所用的显卡以及对应的CUDA版本
我这里使用的是NVIDIA 3080TI 安装的CUDA版本是11.0
整个的安装过程其实mmrotate官网已经给出了,但是安装中难免会有些小问题,所以这里也记录一下。
创建一个虚拟环境并激活。该环境就是以后用来运行mmrotate的了,这里安装的是python3.8。
conda create -n mmrotate python=3.8
conda activate mmrotate
因为我没有在创建环境的时候安装pytorch和cudatoolkit,所以要单独安装一下。这里我的CUDA版本是11.0,安装cudatoolkit11.1没有出现问题。之前在一台Ubantu的机器上安装了CUDA11.4,使用cudatoolkit11.3也没有问题。
conda install pytorch==1.8.0 torchvision==0.9.0 torchaudio==0.8.0 cudatoolkit=11.1 -c pytorch -c conda-forge
之后也是按照官网的安装步骤,但是有一点mmcv-full请安装1.6.0,因为我使用默认的命令会安装1.6.1运行时会报错。
pip install openmim
mim install mmcv-full==1.6.0
mim install mmdet
然后就是下载mmrotate的源代码,使用git命令跟网站下载压缩包都一样,反正后边命令切换到mmrotate源码的路径下就行了
git clone https://github.com/open-mmlab/mmrotate.git
cd mmrotate
pip install -r requirements/build.txt
pip install -v -e .
到这里应该都不会出现任何问题了,mmroate的运行环境也已经配置好。
这一点其实很多文章也都有了介绍,大多数也是使用了dota数据集的格式。大部分人使用rolabelimg标注的数据格式转成dota的txt,其实本质就是VOC格式转DOTA格式,这里给一个HRSC转DOTA格式的。HRSC与rolableimg的标注格式其实都是VOC,只不过细节略有不同。
import os
import sys
import json
import os.path as osp
import numpy as np
import xmltodict
from tqdm import tqdm
sys.path.append("..")
from dota_poly2rbox import rbox2poly_single
def parse_ann_info(objects):
bboxes, labels, bboxes_ignore, labels_ignore = [], [], [], []
# only one annotation
if type(objects) != list:
objects = [objects]
for obj in objects:
if obj['difficult'] == '0':
bbox = float(obj['mbox_cx']), float(obj['mbox_cy']), float(
obj['mbox_w']), float(obj['mbox_h']), float(obj['mbox_ang'])
label = 'ship'
bboxes.append(bbox)
labels.append(label)
elif obj['difficult'] == '1':
bbox = float(obj['mbox_cx']), float(obj['mbox_cy']), float(
obj['mbox_w']), float(obj['mbox_h']), float(obj['mbox_ang'])
label = 'ship'
bboxes_ignore.append(bbox)
labels_ignore.append(label)
return bboxes, labels, bboxes_ignore, labels_ignore
def ann_to_txt(ann):
out_str = ''
for bbox, label in zip(ann['bboxes'], ann['labels']):
poly = rbox2poly_single(bbox)
str_line = '{} {} {} {} {} {} {} {} {} {}\n'.format(
poly[0], poly[1], poly[2], poly[3], poly[4], poly[5], poly[6], poly[7], label, '0')
out_str += str_line
for bbox, label in zip(ann['bboxes_ignore'], ann['labels_ignore']):
poly = rbox2poly_single(bbox)
str_line = '{} {} {} {} {} {} {} {} {} {}\n'.format(
poly[0], poly[1], poly[2], poly[3], poly[4], poly[5], poly[6], poly[7], label, '1')
out_str += str_line
return out_str
def generate_txt_labels(root_path):
img_path = osp.join(root_path, 'images')
label_path = osp.join(root_path, 'annotations')
label_txt_path = osp.join(root_path, 'labelTxt')
if not osp.exists(label_txt_path):
os.mkdir(label_txt_path)
img_names = [osp.splitext(img_name.strip())[0] for img_name in os.listdir(img_path)]
pbar = tqdm(img_names)
for img_name in pbar:
pbar.set_description("HRSC2016 Preparation...")
label = osp.join(label_path, img_name + '.xml')
label_txt = osp.join(label_txt_path, img_name + '.txt')
f_label = open(label)
data_dict = xmltodict.parse(f_label.read())
data_dict = data_dict['HRSC_Image']
f_label.close()
label_txt_str = ''
# with annotations
if data_dict['HRSC_Objects']:
objects = data_dict['HRSC_Objects']['HRSC_Object']
bboxes, labels, bboxes_ignore, labels_ignore = parse_ann_info(
objects)
ann = dict(
bboxes=bboxes,
labels=labels,
bboxes_ignore=bboxes_ignore,
labels_ignore=labels_ignore)
label_txt_str = ann_to_txt(ann)
with open(label_txt, 'w') as f_txt:
f_txt.write(label_txt_str)
if __name__ == '__main__':
generate_txt_labels('/project/jmhan/data/HRSC2016/Train')
generate_txt_labels('/project/jmhan/data/HRSC2016/Test')
print('done!')
接下来到训练部分,总结了一下需要进行的操作:
def add_parser(parser):
"""Add arguments."""
parser.add_argument(
'--base-json',
type=str,
default='./split_configs/ss_val.json',
help='json config file for split images')
{
"nproc": 10,
"img_dirs": [
"./HRSC2DOTA/train/images/"
],
"ann_dirs": [
"./HRSC2DOTA/train/labelTxt/"
],
"sizes": [
1024
],
"gaps": [
200
],
"rates": [
1.0
],
"img_rate_thr": 0.6,
"iof_thr": 0.7,
"no_padding": false,
"padding_value": [
104,
116,
124
],
"save_dir": "../split_ss_hrsc2dota/train/",
"save_ext": ".png"
def parse_args():
parser = argparse.ArgumentParser(description='Train a detector')
parser.add_argument('--config',default='../configs/rotated_faster_rcnn/rotated_faster_rcnn_r50_fpn_1x_dota_le90.py', help='train config file path')
parser.add_argument('--work-dir',default='model_weight', help='the dir to save logs and models')
_base_ = [
'../_base_/datasets/dotav1.py', '../_base_/schedules/schedule_1x.py',
'../_base_/default_runtime.py'
]
dataset_type = 'DOTADataset'
data_root = 'data/dota/split_ss_hrsc2dota/'
data = dict(
samples_per_gpu=2,
workers_per_gpu=2,
train=dict(
type=dataset_type,
ann_file=data_root + 'train/annfiles/',
img_prefix=data_root + 'train/images/',
pipeline=train_pipeline),
val=dict(
type=dataset_type,
ann_file=data_root + 'val/annfiles/',
img_prefix=data_root + 'val/images/',
pipeline=test_pipeline),
test=dict(
type=dataset_type,
ann_file=data_root + 'val/annfiles/',
img_prefix=data_root + 'val/images/',
pipeline=test_pipeline))
# CLASSES = ('plane', 'baseball-diamond', 'bridge', 'ground-track-field',
# 'small-vehicle', 'large-vehicle', 'ship', 'tennis-court',
# 'basketball-court', 'storage-tank', 'soccer-ball-field',
# 'roundabout', 'harbor', 'swimming-pool', 'helicopter')
#
# PALETTE = [(165, 42, 42), (189, 183, 107), (0, 255, 0), (255, 0, 0),
# (138, 43, 226), (255, 128, 0), (255, 0, 255), (0, 255, 255),
# (255, 193, 193), (0, 51, 153), (255, 250, 205), (0, 139, 139),
# (255, 255, 0), (147, 116, 116), (0, 0, 255)]
CLASSES = ('ship',)#只有一类时一定要添加逗号,之前我没有添加然后发现读取的类别是's','h','i','p'。。。。
PALETTE = [(165, 42, 42),]
train_dataloader_default_args = dict(
samples_per_gpu=4,
workers_per_gpu=2,
# `num_gpus` will be ignored if distributed
num_gpus=len(cfg.gpu_ids),
dist=distributed,
seed=cfg.seed,
runner_type=runner_type,
persistent_workers=False)
总体来说mmrotate同样支持windows而且配置还挺简单,有点超乎我的预料。作为一个新兴的框架,无疑完成一些工程任务会方便很多。但是里边的一些参数文件需要互相调用,阅读起来有些复杂(对我来说),感觉小坑就是里边的各种路径设置,基本都是基于你的运行文件,比如运行train文件train所依赖的其他参数文件中的路径设置都是基于train的而并非参数文件本身。总之后边要熟练使用这个框架还有很长的一段路要走,这个博客应该也会继续更新。
基于MMRotate训练自定义数据集 做旋转目标检测 2022-3-30_YD-阿三的博客-CSDN博客_旋转目标检测数据集
使用mmdetection训练和评估自定义数据集 - 知乎
MMRotate从零开始训练自己的数据集_江小白jlj的博客-CSDN博客