mask rcnn Keras+Tensor 训练自己的数据集
前言
最近在使用mask rcnn训练自己的数据,主要使用的是基于Mask RCNN开源项目github地址为
https://github.com/matterport/Mask_RCNN
本文主要参考
https://blog.csdn.net/qq_29462849/article/details/81037343
https://blog.csdn.net/l297969586/article/details/79140840
https://blog.csdn.net/u012746060/article/details/82143285
但是采用以上博客的方法的时候会遇到问题:
- 重写的draw_mask功能,采用了两层for循环来遍历像素,这样生成mask的时候会非常耗时;
- 重写的loadmask的功能,直接将# number of object=1,这个不太明白,这样反馈出来的mask的层数好像不对;
- 重新写draw_mask的设置设置像素为1的时候,只用了三维;
- 以上的问题,应该用示例代码中的## Load and display random samples功能来验证一下,由于mask实在load不出来;
重新写laodmask功能
参考了官方的例程Balloon.py和train_shapes两个例子程序
- Balloon程序的标注格式是使用VIA标注,Json文件是将所有的图片保存到一个.json文件,文件的格式参考如下
// annotations
# VGG Image Annotator (up to version 1.6) saves each image in the form:
# { 'filename': '28503151_5b5b7ec140_b.jpg',
# 'regions': {
# '0': {
# 'region_attributes': {},
# 'shape_attributes': {
# 'all_points_x': [...],
# 'all_points_y': [...],
# 'name': 'polygon'}},
# ... more regions ...
# },
# 'size': 100202
# }
- add_image可以发现这个是添加了polygon到imagelist里面
- 其实labelme的json的数据也有polygon的信息,只不过存储的方式不一样,所以可以先将json的shape中代码如下
// annotations
for json_file in imglist:
with json_file.open() as f:
json_result = json.load(f)
if type(json_result['shapes']) is dict:
polygons = [r['points'] for r in json_result['shapes'].values()]
shapes=[r['label'] for r in json_result['shapes']]
else:
polygons = [r['points'] for r in json_result['shapes']]
shapes=[r['label'] for r in json_result['shapes']]
#shapes=
# load_mask() needs the image size to convert polygons to masks.
# Unfortunately, VIA doesn't include it in JSON, so we must read
# the image. This is only managable since the dataset is tiny.
# labelme include the height and weight
image_path = os.path.join(dataset_dir, json_result['imagePath'])
height=json_result['imageHeight']
width = json_result['imageWidth']
self.add_image(
"shapes",
image_id=json_result['imagePath'], # use file name as a unique image id
path=image_path,
width=width, height=height,
polygons=polygons,
shapes=shapes)
- 通过loadmask可以通过将mask按照类别添加到mask中代码如下
def load_mask(self, image_id):
"""Generate instance masks for an image.
Returns:
masks: A bool array of shape [height, width, instance count] with
one mask per instance.
class_ids: a 1D array of class IDs of the instance masks.
"""
# If not a balloon dataset image, delegate to parent class.
#image_info = self.image_info[image_id]
#if image_info["source"] != "balloon":
# return super(self.__class__, self).load_mask(image_id)
info = self.image_info[image_id]
shapes = info['shapes']
count = len(shapes) # number of object
# Convert polygons to a bitmap mask of shape
# [height, width, instance_count]
mask = np.zeros([info["height"], info["width"], count],
dtype=np.uint8)
for i, p in enumerate(info['polygons']):
p_y=[]
p_x=[]
for point in p:
p_y.append(point[1])
p_x.append(point[0])
rr, cc = skimage.draw.polygon(p_y, p_x)
mask[rr, cc, i:i+1] = 1
# Handle occlusions
occlusion = np.logical_not(mask[:, :, -1]).astype(np.uint8)
for i in range(count-2, -1, -1):
mask[:, :, i] = mask[:, :, i] * occlusion
occlusion = np.logical_and(occlusion, np.logical_not(mask[:, :, i]))
# Map class names to class IDs.
class_ids = np.array([self.class_names.index(s) for s in shapes])
return mask.astype(np.bool), class_ids.astype(np.int32)
- 用display_top_masks显示出来的效果
训练自己的数据
之后就可以愉快的训练自己的数据了