使用PointRend实例分割训练自己的coco数据集

更新时间:2023-07-29 15:25:43 阅读: 评论:0

使⽤PointRend实例分割训练⾃⼰的coco数据集
近期在研究将何恺明团队提出的Pointrend算法来实现⾃⼰图像⽬标分割,⽽Fackbook的开源检测框架已开源了⼀段时间,但是⾃⼰也是刚刚接触到,通过实现PointRend,来慢慢的认识这个框架。这⾥主要写的是如何实现⾃⼰的coco数据集。
1、安装Detectron2
安装Detectron2,现在⽹上也是⼀⼤推,我也写了⼀个我⾃⼰理解的安装和测试的,感兴趣的可以参考⼀下。安装成功了,就是要准备⾃⼰的数据集了。
2、准备⾃⼰的coco数据集
①我是使⽤labelme标注⾃⼰的图像,并转换成json⽂件,这个不是我这⾥说的重点,所以就放·······。
②将json⽂件分成train和val两个⽂件夹,然后分别转换成train.json和val.json,转换代码可以参考下⾯,或者去上下载。
# -*- coding: utf-8 -*-
"""
Created on Fri May 15 14:27:14 2020
@author: Administrator
"""
import argpar
import json
import matplotlib.pyplot as plt
import skimage.io as io
import cv2
from labelme import utils
import numpy as np
import glob
import PIL.Image
class MyEncoder(json.JSONEncoder):
def default(lf, obj):
if isinstance(obj, np.integer):
return int(obj)
elif isinstance(obj, np.floating):
return float(obj)
elif isinstance(obj, np.ndarray):
list()
el:
return super(MyEncoder, lf).default(obj)
class labelme2coco(object):
def __init__(lf, labelme_json=[], save_json_path='./tran.json'):
'''
:param labelme_json: 所有labelme的json⽂件路径组成的列表
:param save_json_path: json保存位置
'''
lf.labelme_json = labelme_json
lf.save_json_path = save_json_path
lf.images = []
lf.categories = []
lf.annotations = []
# lf.data_coco = {}
lf.label = []
lf.annID = 1
lf.height = 0
lf.width = 0
lf.save_json()
def data_transfer(lf):
for num, json_file in enumerate(lf.labelme_json):
with open(json_file, 'r') as fp:
data = json.load(fp)  # 加载json⽂件
lf.images.append(lf.image(data, num))
for shapes in data['shapes']:
label = shapes['label']
if label not in lf.label:
lf.categories.append(lf.categorie(label))
lf.label.append(label)
points = shapes['points']#这⾥的point是⽤rectangle标注得到的,只有两个点,需要转成四个点                    #points.append([points[0][0],points[1][1]])
#points.append([points[1][0],points[0][1]])
lf.annotations.append(lf.annotation(points, label, num))
lf.annID += 1
def image(lf, data, num):
image = {}
img = utils.img_b64_to_arr(data['imageData'])  # 解析原图⽚数据
# img=io.imread(data['imagePath']) # 通过图⽚路径打开图⽚
# img = cv2.imread(data['imagePath'], 0)
height, width = img.shape[:2]
img = None
image['height'] = height
image['width'] = width
image['id'] = num + 1
#image['file_name'] = data['imagePath'].split('/')[-1]
image['file_name'] = data['imagePath']  #github中,⾃⼰要根据⾃⼰的图像名修改
lf.height = height
lf.width = width
return image
def categorie(lf, label):
楚王categorie = {}
categorie['supercategory'] = 'Cancer'
categorie['id'] = len(lf.label) + 1  # 0 默认为背景
categorie['name'] = label
return categorie
def annotation(lf, points, label, num):
annotation = {}
annotation['gmentation'] = [list(np.asarray(points).flatten())]
annotation['iscrowd'] = 0
annotation['image_id'] = num + 1
# annotation['bbox'] = bbox(points)) # 使⽤list保存json⽂件时报错(不知道为什么)
# list(map(int,a[1:-1].split(','))) a=annotation['bbox'] 使⽤该⽅式转成list
annotation['bbox'] = list(map(float, lf.getbbox(points)))
annotation['area'] = annotation['bbox'][2] * annotation['bbox'][3]
# annotation['category_id'] = lf.getcatid(label)
annotation['category_id'] = lf.getcatid(label)#注意,源代码默认为1
annotation['id'] = lf.annID
return annotation
def getcatid(lf, label):
for categorie in lf.categories:君空
if label == categorie['name']:
return categorie['id']
return 1
def getbbox(lf, points):
当局者迷旁观者清什么意思
# img = np.zeros([lf.height,lf.width],np.uint8)
校园科技节
# cv2.polylines(img, [np.asarray(points)], True, 1, lineType=cv2.LINE_AA)  # 画边界线
# cv2.fillPoly(img, [np.asarray(points)], 1)  # 画多边形内部像素值为1
polygons = points
polygons = points
mask = lf.polygons_to_mask([lf.height, lf.width], polygons)
return lf.mask2box(mask)
def mask2box(lf, mask):
'''从mask反算出其边框
mask:[h,w]  0、1组成的图⽚
1对应对象,只需计算1对应的⾏列号(左上⾓⾏列号,右下⾓⾏列号,就可以算出其边框)
'''
# np.where(mask==1)
index = np.argwhere(mask == 1)
rows = index[:, 0]
clos = index[:, 1]
# 解析左上⾓⾏列号
left_top_r = np.min(rows)  # y
left_top_c = np.min(clos)  # x
# 解析右下⾓⾏列号
right_bottom_r = np.max(rows)
right_bottom_c = np.max(clos)
# return [(left_top_r,left_top_c),(right_bottom_r,right_bottom_c)]
# return [(left_top_c, left_top_r), (right_bottom_c, right_bottom_r)]
# return [left_top_c, left_top_r, right_bottom_c, right_bottom_r]  # [x1,y1,x2,y2]
return [left_top_c, left_top_r, right_bottom_c - left_top_c,
right_bottom_r - left_top_r]  # [x1,y1,w,h] 对应COCO的bbox格式
def polygons_to_mask(lf, img_shape, polygons):
mask = np.zeros(img_shape, dtype=np.uint8)
mask = PIL.Image.fromarray(mask)
xy = list(map(tuple, polygons))
英语小课堂
PIL.ImageDraw.Draw(mask).polygon(xy=xy, outline=1, fill=1)
mask = np.array(mask, dtype=bool)
return mask
def data2coco(lf):
data_coco = {}
data_coco['images'] = lf.images
data_coco['categories'] = lf.categories
data_coco['annotations'] = lf.annotations
return data_coco
def save_json(lf):
lf.data_transfer()
lf.data_coco = lf.data2coco()
# 保存json⽂件
json.dump(lf.data_coco, open(lf.save_json_path, 'w'), indent=4, cls=MyEncoder)  # indent=4 更加美观显⽰
labelme_json = glob.glob(r'I:/timage/val/json/*.json')
# labelme_json=['./Annotations/*.json']
labelme2coco(labelme_json, 'I:/image//val/footdeep_val.json')
我都⾃⼰运⾏了,并且也跑通了,转换结果都没有问题,这⾥要注意⼀个,⾃⼰在做别的项⽬的时候,把图像给重命名了,导致json⽂件的imagepath与图像名不⼀致,然后训练⼀直报错,哎,这个⼀
定要注意,也是给⾃⼰提个醒,以后标注了数据⼀定要存⼀份最原始的数据集,还要注意⼀点,使⽤labelme标注图⽚,背景是没有标注的,因此在上⾯代码中⼀定要将 annotation['category_id'] =
最后的数据结构如下:
footdata
--foot
train.json
val.json
train
png图⽚
val
png图⽚
我的数据集就1个类别,所以毕竟简单
3、使⽤API训练
基本与Detectron2训练差不多,这⾥附上代码,我定义为train_foot.py:
# -*- coding: utf-8 -*-
"""
Created on Thu Jul  2 16:26:02 2020
@author: CTZN
"""
import os
import torch
import as comm
from detectron2.checkpoint import DetectionCheckpointer
fig import get_cfg
from detectron2.data import MetadataCatalog
ine import DefaultTrainer, default_argument_parr, default_tup, launch from detectron2.evaluation import (
CityscapesEvaluator,
COCOEvaluator,
DatatEvaluators,
LVISEvaluator,
verify_results,
)
from point_rend import add_pointrend_config
from detectron2.data import DatatCatalog, MetadataCatalog
from detectron2. import load_coco_json
import pycocotools
#声明类别,尽量保持
CLASS_NAMES =["__background__","foot"]
DATASET_ROOT = '/root/detectron2/projects/PointRend/footdata'
ANN_ROOT = os.path.join(DATASET_ROOT, 'foot')
TRAIN_PATH = os.path.join(DATASET_ROOT, 'train')
VAL_PATH = os.path.join(DATASET_ROOT, 'val')
TRAIN_JSON = os.path.join(ANN_ROOT, 'footdeep_train.json')
#VAL_JSON = os.path.join(ANN_ROOT, 'val.json')
VAL_JSON = os.path.join(ANN_ROOT, 'footdeep_val.json')
# 声明数据集的⼦集
PREDEFINED_SPLITS_DATASET = {
"coco_my_train": (TRAIN_PATH, TRAIN_JSON),
"coco_my_val": (VAL_PATH, VAL_JSON),
}
#注册数据集(这⼀步就是将⾃定义数据集注册进Detectron2)
数学王国#注册数据集(这⼀步就是将⾃定义数据集注册进Detectron2)
def register_datat():
"""
purpo: register all splits of datat with PREDEFINED_SPLITS_DATASET
"""
for key, (image_root, json_file) in PREDEFINED_SPLITS_DATASET.items():
register_datat_instances(name=key,
json_file=json_file,
image_root=image_root)
def register_datat_instances(name, json_file, image_root):
"""
purpo: register datat to DatatCatalog,
register metadata to MetadataCatalog and t attribute
"""
<(name).t(json_file=json_file,
image_root=image_root,
evaluator_type="coco")
# 注册数据集和元数据
def plain_register_datat():
#训练集
<("coco_my_train").t(thing_class=CLASS_NAMES,  # 可以选择开启,但是不能显⽰中⽂,这⾥需要注意,中⽂的话最好关闭                                                    evaluator_type='coco', # 指定评估⽅式
json_file=TRAIN_JSON,
image_root=TRAIN_PATH)
#验证/测试集
<("coco_my_val").t(thing_class=CLASS_NAMES, # 可以选择开启,但是不能显⽰中⽂,这⾥需要注意,中⽂的话最好关闭                                                evaluator_type='coco', # 指定评估⽅式
json_file=VAL_JSON,
image_root=VAL_PATH)
class Trainer(DefaultTrainer):
"""
We u the "DefaultTrainer" which contains a number pre-defined logic for
standard training workflow. They may not work for you, especially if you
are working on a new rearch project. In that ca you can u the cleaner
"SimpleTrainer", or write your own training loop.
"""
@classmethod
def build_evaluator(cls, cfg, datat_name, output_folder=None):
"""
米酒鸡蛋的功效与作用Create evaluator(s) for a given datat.
This us the special metadata "evaluator_type" associated with each builtin datat.
For your own datat, you can simply create an evaluator manually in your
script and do not have to worry about the hacky if-el logic here.
"""
if output_folder is None:
output_folder = os.path.join(cfg.OUTPUT_DIR, "inference")
evaluator_list = []
evaluator_type = (datat_name).evaluator_type
if evaluator_type == "lvis":宝宝急性荨麻疹
return LVISEvaluator(datat_name, cfg, True, output_folder)
if evaluator_type == "coco":
return COCOEvaluator(datat_name, cfg, True, output_folder)
if evaluator_type == "cityscapes":
asrt (
torch.cuda.device_count() >= _rank()

本文发布于:2023-07-29 15:25:43,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1100966.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   标注   测试   背景   没有   图像   对应   开源
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图