python tools/analysis_tools/analyze_logs.py plot_curve [--keys ${KEYS}] [--title ${TITLE}] [--legend ${LEGEND}] [--backend ${BACKEND}] [--style ${STYLE}] [--out ${OUT_FILE}]
绘制一些运行的分类和回归损失,并将图保存为pdf
python tools/analysis_tools/analyze_logs.py plot_curve log.json --keys loss_cls loss_bbox --out losses.pdf
#可视化命令参数介绍:
plot_curve:该参数后跟的是训练保存的json文件 --keys:后面跟的是要绘制的损失关键字,可以跟多个值 --out:后面跟的是绘制保存的结果,可以保存成png图片,也可以保存成pdf
案例:
python tools/analysis_tools/analyze_logs.py plot_curve work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco_visdrone2019/20220518_023715.log.json --keys loss_cls loss_bbox --legend loss_cls loss_bbox --out work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco_visdrone2019/losses.png
python tools/analysis_tools/analyze_logs.py cal_train_time log.json [--include-outliers]
python tools/test.py configs/faster_rcnn_r50_fpn_1x.py \
checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth \
--show
生成测试结果,.json和.pkl文件,加–eval bbox生成框的信息,用于目标检测。
python tools/test.py configs/faster_rcnn_r50_fpn_1x.py \
checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth \
--eval bbox --show
python tools/test.py configs/pascal_voc/faster_rcnn_r50_fpn_1x_voc.py \
checkpoints/SOME_CHECKPOINT.pth \
--eval mAP
python tools/test.py configs/mask_rcnn_r50_fpn_1x.py \
checkpoints/mask_rcnn_r50_fpn_1x_20181010-069fa190.pth \
--out results.pkl --eval bbox segm
./tools/dist_test.sh configs/mask_rcnn_r50_fpn_1x.py \
checkpoints/mask_rcnn_r50_fpn_1x_20181010-069fa190.pth \
8 --out results.pkl --eval bbox segm
tools/dist_test.sh也支持多节点测试,但依赖于PyTorch的启动工具。
./tools/dist_test.sh configs/mask_rcnn_r50_fpn_1x.py \
checkpoints/mask_rcnn_r50_fpn_1x_20181010-069fa190.pth \
8 --format-only --options "jsonfile_prefix=./mask_rcnn_test-dev_results"
/media/lhy/Swin-Transformer-Object-Detection# python ./tools/test.py4_window7_mstrain_480-800_adamw_3x_coco.py work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco/latest.pth --format_only --options "jsonfile_prefix=./result/maskrcnn_result"
问题解决:运行代码不输出结果的原因是官方给的代码–format-only这条命令参数在代码中是format_only,所以我们将参数统一为format_only
你将获得两个json文件mask_rcnn_test-dev_results.bbox.json和mask_rcnn_test-dev_results.segm.json。
./tools/dist_test.sh \
configs/cityscapes/mask_rcnn_r50_fpn_1x_cityscapes.py \
checkpoints/mask_rcnn_r50_fpn_1x_cityscapes_20200227-afe51d5a.pth \
8 \
--format-only \
--options "txtfile_prefix=./mask_rcnn_cityscapes_test_results"
或者
python tools/test.py work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco.py work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco/latest.pth --out inference_dirs/mask_rcnn_swin_tiny_coco_result.pkl --format_only --show-dir ./inference_dirs/ --options "txtfile_prefix=./inference_dirs/mask_rcnn_swin_tiny_coco_test_results"
生成的png和txt文件将在./mask_rcnn_cityscapes_test_results目录下
python tools/test.py work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco_visdrone2019/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco.py work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco_visdrone2019/best_bbox_mAP.pth --out inference_dirs/mask_rcnn_swin_tiny_coco_visdrone2019_test_result/result.pkl --eval bbox --show-dir inference_dirs/mask_rcnn_swin_tiny_coco_visdrone2019_test_result/png/
参考博客
将mmdetection产生的coco(json)格式的测试结果转化成VisDrone19官网所需要的txt格式文件(还包括无标签测试图片产生mmdet所需要的test.json方法)
最近VisDrone19开放测试服务器了,自己尝试在它的test的图片上给出标签然后提交到官网上去。
使用了mmdetection工具,这个工具出来的结果是coco(json)格式的。
我们需要把它转化成官网需要的visdrone的txt格式才可以提交到服务器上,查看自己的score。
这个转化脚本目前找不到,所以只能自己写了。
import json
import os
import argparse
# wangzhifneg write in 2021-6-30
def coco2vistxt(json_path, out_folder):
labels = json.load(open(json_path, 'r', encoding='utf-8'))
for i in range(len(labels)):
# print(len(labels)) 158000
# print(labels[i]['image_id'])
# print(labels[i]['bbox'])
file_name = labels[i]['image_id'] + '.txt'
with open(os.path.join(args.o, file_name), 'a+', encoding='utf-8') as f:
l = labels[i]['bbox']
s = [round(i) for i in l]
line =str(s)[1:-1].replace(' ','')+ ',' + str(labels[i]['score'])[:6] + ',' + str(labels[i]['category_id']) + ',' + str('-1') + ',' + str('-1')
f.write(line+'\n')
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='coco test json to visdrone txt file.')
parser.add_argument('-j', help='JSON file', default='D:/07_codeD/datasets/visdrone/cascadevis10test.bbox.json')
parser.add_argument('-o', help='path to output folder', default='D:/07_codeD/datasets/visdrone/testout')
args = parser.parse_args()
coco2vistxt(json_path=args.j,out_folder=args.o)
简单说一下:
cascadevis10test.bbox.json这个是我们mmdetection产生的json文件,里面有我们对测试图片产生的coco格式的结果。
testout10cascade是传出txt存放的目录。
具体如下图:
我们结果出来了,打包可以提交到官网上。
mmdetection需要把测试集(完全是图片,没有标签)转化成一个带有图片信息的json文件才可以进行coco格式的test。
这部分代码官方没有,要自己写,我找了好久才找到可以参考的,自己改动了下。具体代码如下。
import os
import PIL.Image as Image
import json
root = 'D:/07_codeD/datasets/visdrone/VisDrone2019-DET-test-challenge'
test_json = os.path.join(root, 'images') # test image root
out_file = os.path.join(root, 'test.json') # test json output path 生成json的位置
data = {}
# 这部分如果不同数据集可以替换
data['categories'] = [{"id": 1, "name": "Pedestrain", "supercategory": "none"},
{"id": 2, "name": "People", "supercategory": "none"},
{"id": 3, "name": "Bicycle", "supercategory": "none"},
{"id": 4, "name": "Car", "supercategory": "none"},
{"id": 5, "name": "Van", "supercategory": "none"},
{"id": 6, "name": "Truck", "supercategory": "none"},
{"id": 7, "name": "Tricycle", "supercategory": "none"},
{"id": 8, "name": "Awning-tricycle", "supercategory": "none"},
{"id": 9, "name": "Bus", "supercategory": "none"},
{"id": 10, "name": "Motor", "supercategory": "none"}] # 数据集的类别
images = []
for name in os.listdir(test_json):
file_path = os.path.join(test_json, name)
file = Image.open(file_path)
tmp = dict()
tmp['id'] = name[:-4]
# idx += 1
tmp['width'] = file.size[0]
tmp['height'] = file.size[1]
tmp['file_name'] = name
images.append(tmp)
data['images'] = images
with open(out_file, 'w') as f:
json.dump(data, f)
# with open(out_file, 'r') as f:
# test = json.load(f)
# for i in test['categories']:
# print(i['id'])
print('finish')
这里注意VisDrone是12个类,其中1和11我们是不需要的,大家建立自己的coco(json)和voc(xml)标签的时候就要去除。
我们上面这个代码可以将我们的test(完全是图片),生成相应的test.json(这里面没有标签,只有图片信息),然后将test.json写入到我们的mmdetection的config中的test部分就好了。
(这部分代码mmdetection官方居然没有。。。资料也好少,之前搞得我恼火得很,这里给后面想做这个数据集的给点参考)
image2coco官方参考
下面是具体代码
import argparse
import os
import mmcv
from PIL import Image
def parse_args():
parser = argparse.ArgumentParser(
description='Convert images to coco format without annotations')
parser.add_argument('img_path', help='The root path of images')
parser.add_argument(
'classes', type=str, help='The text file name of storage class list')
parser.add_argument(
'out',
type=str,
help='The output annotation json file name, The save dir is in the '
'same directory as img_path')
parser.add_argument(
'-e',
'--exclude-extensions',
type=str,
nargs='+',
help='The suffix of images to be excluded, such as "png" and "bmp"')
args = parser.parse_args()
return args
def collect_image_infos(path, exclude_extensions=None):
img_infos = []
images_generator = mmcv.scandir(path, recursive=True)
for image_path in mmcv.track_iter_progress(list(images_generator)):
if exclude_extensions is None or (
exclude_extensions is not None
and not image_path.lower().endswith(exclude_extensions)):
image_path = os.path.join(path, image_path)
img_pillow = Image.open(image_path)
img_info = {
'filename': image_path,
'width': img_pillow.width,
'height': img_pillow.height,
}
img_infos.append(img_info)
return img_infos
def cvt_to_coco_json(img_infos, classes):
image_id = 0
coco = dict()
coco['images'] = []
coco['type'] = 'instance'
coco['categories'] = []
coco['annotations'] = []
image_set = set()
for category_id, name in enumerate(classes):
category_item = dict()
category_item['supercategory'] = str('none')
category_item['id'] = int(category_id)
category_item['name'] = str(name)
coco['categories'].append(category_item)
for img_dict in img_infos:
file_name = img_dict['filename']
assert file_name not in image_set
image_item = dict()
image_item['id'] = int(image_id)
image_item['file_name'] = str(file_name)
image_item['height'] = int(img_dict['height'])
image_item['width'] = int(img_dict['width'])
coco['images'].append(image_item)
image_set.add(file_name)
image_id += 1
return coco
def main():
args = parse_args()
assert args.out.endswith(
'json'), 'The output file name must be json suffix'
# 1 load image list info
img_infos = collect_image_infos(args.img_path, args.exclude_extensions)
# 2 convert to coco format data
classes = mmcv.list_from_file(args.classes)
coco_info = cvt_to_coco_json(img_infos, classes)
# 3 dump
save_dir = os.path.join(args.img_path, '..', 'annotations')
mmcv.mkdir_or_exist(save_dir)
save_path = os.path.join(save_dir, args.out)
mmcv.dump(coco_info, save_path)
print(f'save json file: {save_path}')
if __name__ == '__main__':
main()