这篇是记录用maskrcnn训练自己的数据集,防止以后忘记.

主要参考:

1.https://blog.csdn.net/qq_29462849/article/details/81037343

2.https://github.com/matterport/Mask_RCNN

这个工作需求是识别公园道路和公园的一些立面物体,就是防止公园的无人清扫车碰撞(老板一定要用视觉解决...不要用超声波传感器),因为要识别路面,所以想到用语义分割来做,之前也用过maskrcnn来检测行人,效果很好,所以这次把公园采集到的数据来自己标注,然后训练,标注语义分割数据真是一场灾难!!!!!!!!!下面是我遇到的一些报错,记录一下,参考1其实已经写的很清楚了.但是还是遇到一些问题.

环境Ubuntu16

先下载git上的源码.配置的问题需要自己解决,Ubuntu上不难.

然后在Mask_RCNN/samples/shapes的文件夹下.自己建一个train.py,其实和/data/Mask_RCNN/samples/shapes/train_shapes.ipynb文件基本一样的,只是用惯了pycharm,回不了头用jupyter notebook了,哈哈哈哈.下面是我的shapes的文件夹模样.

主要是train.py train_data文件夹 还有16位图像转8位.py,这几个比较重要,其他的源码都有.

train_data文件夹下是这样的

我先解释数据准备.首先train_data文件夹下有5个文件夹,我是用labelme标注的.首先pic就是就是原图.

然后是json文件夹,这些就是labelme产生的json

然后是labelme_json文件夹,这些就是labelme_json_to_dataset 把json转换成文件夹,当然网上有批量处理的方法,大家可以去参考一些,我的是建立了一个sh命令.我无法修改labelme里面的py文件,可能是因为我的Ubuntu还是有点菜鸡.文件夹里就是基本的5个文件img.png info.yaml label.png label_names.txt label_viz.png

#!/bin/bash
dir=`ls /data/self-sweeper/7.23/json1/`    #定义遍历的目录
path="/data/self-sweeper/7.23/json1/"      #名字与上一行相同
for i in $dir
dolabelme_json_to_dataset ${path}$i#echo $i
done

最后在train_data里还有2个文件夹,就是16bit和cv2_mask,其实这两个文件夹是一个东西,但是参考1的博主说由于labelme生成的掩码标签 label.png为16位存储,opencv默认读取8位,需要将16位转8位,可通过C++程序转化,代码请参考这篇博文:http://blog.csdn.net/l297969586/article/details/79154150 ,所以16bit文件夹里的就是每个labelme_json文件夹中的json文件夹下的label.png,但是要记得好命名。我先给大家看我的16bit文件夹下的内容

大家可以看到,我的16bit文件夹下的就是每个label.png,这个名字要和上面的都对应好。然后我们需要把16bit转化为8bit,下面是我自己写的代码,很简单,中心思想就一条。

import os
from PIL import Image
import numpy as npimgs_path = '/data/Mask_RCNN/samples/shapes/train_data/16bit/'
res_path = '/data/Mask_RCNN/samples/shapes/train_data/cv2_mask/'imgs = sorted(os.listdir(imgs_path))for img in imgs:test = Image.open(imgs_path + img)test = Image.fromarray(np.uint8(test))test.save(res_path+img)

然后我给大家看cv2_mask文件夹下面的东西。

之前有颜色区别的,现在就变成一片黑了,但是其实还是有区别的,你可以一个一个读里面的信息,就是发现,比如我是有4类的,road,person,grass,vertical,所以里面就有0,1,2,3,4。共5种颜色(背景也是一类),不过是它的数值太接近,所以你看起来就都像是黑色。这些就是我的数据准备,在吐槽下语义分割数据太难标注了!!!!!应该数据准备的内容都说清楚了,没有什么遗忘的了。

然后就是代码了,代码和参考1中给的是一致的,但是还是有需要修改的地方,只要是根据自己的类的不同要修改。也是自己踩坑的记录了。

# Number of classes (including background)
NUM_CLASSES = 1 + 4  # background + 3 shapes

上面这里是需要自己修改的1是背景 4是你自己定义的类

# Add classes,可通过这种方式扩展多个物体
self.add_class("shapes", 1, "grass")
self.add_class("shapes", 2, "road")
self.add_class("shapes", 3, "person")
self.add_class("shapes", 4, "vertical")

这里是需要修改的是把你的类写上去,上面4个就是我自己标注的类

for i in range(len(labels)):if labels[i].find("grass") != -1:# print "box"labels_form.append("grass")elif labels[i].find("road")!=-1:#print "column"labels_form.append("road")elif labels[i].find("person")!=-1:#print "package"labels_form.append("person")elif labels[i].find("vertical")!=-1:#print "package"labels_form.append("vertical")

还有这里,需要修改,也是根据自己的类来修改

其他的我也还没有细细读代码,我是一般先把代码跑通了在去细细的读代码。修改到这里算是可以跑出权重出来了。我后面还会继续更新,我去读代码了。

# -*- coding: utf-8 -*-import os
import sys
import random
import math
import re
import time
import numpy as np
import cv2
import matplotlib
import matplotlib.pyplot as plt
import tensorflow as tf
from mrcnn.config import Config
#import utils
from mrcnn import model as modellib,utils
from mrcnn import visualize
import yaml
from mrcnn.model import log
from PIL import Image#os.environ["CUDA_VISIBLE_DEVICES"] = "0"
# Root directory of the project
ROOT_DIR = os.getcwd()#ROOT_DIR = os.path.abspath("../")
# Directory to save logs and trained model
MODEL_DIR = os.path.join(ROOT_DIR, "logs")iter_num=0# Local path to trained weights file
COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")
print(COCO_MODEL_PATH)
# Download COCO trained weights from Releases if needed
if not os.path.exists(COCO_MODEL_PATH):utils.download_trained_weights(COCO_MODEL_PATH)class ShapesConfig(Config):"""Configuration for training on the toy shapes dataset.Derives from the base Config class and overrides values specificto the toy shapes dataset."""# Give the configuration a recognizable nameNAME = "shapes"# Train on 1 GPU and 8 images per GPU. We can put multiple images on each# GPU because the images are small. Batch size is 8 (GPUs * images/GPU).GPU_COUNT = 1IMAGES_PER_GPU = 2# Number of classes (including background)NUM_CLASSES = 1 + 4  # background + 3 shapes# Use small images for faster training. Set the limits of the small side# the large side, and that determines the image shape.IMAGE_MIN_DIM = 320IMAGE_MAX_DIM = 384# Use smaller anchors because our image and objects are smallRPN_ANCHOR_SCALES = (8 * 6, 16 * 6, 32 * 6, 64 * 6, 128 * 6)  # anchor side in pixels# Reduce training ROIs per image because the images are small and have# few objects. Aim to allow ROI sampling to pick 33% positive ROIs.TRAIN_ROIS_PER_IMAGE = 100# Use a small epoch since the data is simpleSTEPS_PER_EPOCH = 100# use small validation steps since the epoch is smallVALIDATION_STEPS = 50config = ShapesConfig()
config.display()class DrugDataset(utils.Dataset):# 得到该图中有多少个实例(物体)def get_obj_index(self, image):n = np.max(image)return n# 解析labelme中得到的yaml文件,从而得到mask每一层对应的实例标签def from_yaml_get_class(self, image_id):info = self.image_info[image_id]with open(info['yaml_path']) as f:temp = yaml.load(f.read())labels = temp['label_names']del labels[0]return labels# 重新写draw_maskdef draw_mask(self, num_obj, mask, image,image_id):#print("draw_mask-->",image_id)#print("self.image_info",self.image_info)info = self.image_info[image_id]#print("info-->",info)#print("info[width]----->",info['width'],"-info[height]--->",info['height'])for index in range(num_obj):for i in range(info['width']):for j in range(info['height']):#print("image_id-->",image_id,"-i--->",i,"-j--->",j)#print("info[width]----->",info['width'],"-info[height]--->",info['height'])at_pixel = image.getpixel((i, j))if at_pixel == index + 1:mask[j, i, index] = 1return mask# 重新写load_shapes,里面包含自己的类别,可以任意添加# 并在self.image_info信息中添加了path、mask_path 、yaml_path# yaml_pathdataset_root_path = "/tongue_dateset/"# img_floder = dataset_root_path + "rgb"# mask_floder = dataset_root_path + "mask"# dataset_root_path = "/tongue_dateset/"def load_shapes(self, count, img_floder, mask_floder, imglist, dataset_root_path):"""Generate the requested number of synthetic images.count: number of images to generate.height, width: the size of the generated images."""# Add classes,可通过这种方式扩展多个物体self.add_class("shapes", 1, "grass") # 黑色素瘤self.add_class("shapes", 2, "road")self.add_class("shapes", 3, "person")self.add_class("shapes", 4, "vertical")for i in range(count):# 获取图片宽和高filestr = imglist[i].split(".")[0]# print(imglist[i],"-->",cv_img.shape[1],"--->",cv_img.shape[0])# print("id-->", i, " imglist[", i, "]-->", imglist[i],"filestr-->",filestr)# filestr = filestr.split("_")[1]mask_path = mask_floder + "/" + filestr + ".png"yaml_path = dataset_root_path + "labelme_json/" + filestr + "_json/info.yaml"print(dataset_root_path + "labelme_json/" + filestr + "_json/img.png")cv_img = cv2.imread(dataset_root_path + "labelme_json/" + filestr + "_json/img.png")self.add_image("shapes", image_id=i, path=img_floder + "/" + imglist[i],width=cv_img.shape[1], height=cv_img.shape[0], mask_path=mask_path, yaml_path=yaml_path)# 重写load_maskdef load_mask(self, image_id):"""Generate instance masks for shapes of the given image ID."""global iter_numprint("image_id",image_id)info = self.image_info[image_id]count = 1  # number of objectimg = Image.open(info['mask_path'])num_obj = self.get_obj_index(img)mask = np.zeros([info['height'], info['width'], num_obj], dtype=np.uint8)mask = self.draw_mask(num_obj, mask, img,image_id)occlusion = np.logical_not(mask[:, :, -1]).astype(np.uint8)for i in range(count - 2, -1, -1):mask[:, :, i] = mask[:, :, i] * occlusionocclusion = np.logical_and(occlusion, np.logical_not(mask[:, :, i]))labels = []labels = self.from_yaml_get_class(image_id)labels_form = []for i in range(len(labels)):if labels[i].find("grass") != -1:# print "box"labels_form.append("grass")elif labels[i].find("road")!=-1:#print "column"labels_form.append("road")elif labels[i].find("person")!=-1:#print "package"labels_form.append("person")elif labels[i].find("vertical")!=-1:#print "package"labels_form.append("vertical")class_ids = np.array([self.class_names.index(s) for s in labels_form])return mask, class_ids.astype(np.int32)def get_ax(rows=1, cols=1, size=8):"""Return a Matplotlib Axes array to be used inall visualizations in the notebook. Provide acentral point to control graph sizes.Change the default size attribute to control the sizeof rendered images"""_, ax = plt.subplots(rows, cols, figsize=(size * cols, size * rows))return ax#基础设置
dataset_root_path="train_data/"
img_floder = dataset_root_path + "pic"
mask_floder = dataset_root_path + "cv2_mask"
#yaml_floder = dataset_root_path
# print(img_floder)
imglist = os.listdir(img_floder)
count = len(imglist)#train与val数据集准备
dataset_train = DrugDataset()
dataset_train.load_shapes(count, img_floder, mask_floder, imglist,dataset_root_path)
dataset_train.prepare()#print("dataset_train-->",dataset_train._image_ids)dataset_val = DrugDataset()
dataset_val.load_shapes(1, img_floder, mask_floder, imglist,dataset_root_path)
dataset_val.prepare()#print("dataset_val-->",dataset_val._image_ids)# Load and display random samples
#image_ids = np.random.choice(dataset_train.image_ids, 4)
#for image_id in image_ids:
#    image = dataset_train.load_image(image_id)
#    mask, class_ids = dataset_train.load_mask(image_id)
#    visualize.display_top_masks(image, mask, class_ids, dataset_train.class_names)# Create model in training mode
model = modellib.MaskRCNN(mode="training", config=config,model_dir=MODEL_DIR)# Which weights to start with?
init_with = "coco"  # imagenet, coco, or lastif init_with == "imagenet":model.load_weights(model.get_imagenet_weights(), by_name=True)
elif init_with == "coco":# Load weights trained on MS COCO, but skip layers that# are different due to the different number of classes# See README for instructions to download the COCO weightsmodel.load_weights(COCO_MODEL_PATH, by_name=True,exclude=["mrcnn_class_logits", "mrcnn_bbox_fc","mrcnn_bbox", "mrcnn_mask"])
elif init_with == "last":# Load the last model you trained and continue trainingmodel.load_weights(model.find_last()[1], by_name=True)# Train the head branches
# Passing layers="heads" freezes all layers except the head
# layers. You can also pass a regular expression to select
# which layers to train by name pattern.
model.train(dataset_train, dataset_val,learning_rate=config.LEARNING_RATE,epochs=20,layers='heads')# Fine tune all layers
# Passing layers="all" trains all layers. You can also
# pass a regular expression to select which layers to
# train by name pattern.
model.train(dataset_train, dataset_val,learning_rate=config.LEARNING_RATE / 10,epochs=40,layers="all")

用mask-rcnn训练自己的数据相关推荐

  1. Mask Rcnn训练自己的航拍数据集

    最近想利用Mask Rcnn训练自己的航拍数据(数据来源:自己采集.飞行高度:200m,图片大小WxH=6000x4000),在进行自己的航拍图片训练时也与其他同学进行交流,他们一般进行识别的是一类物 ...

  2. mask rcnn训练自己的数据集

    原文首发于微信公众号「3D视觉工坊」--mask rcnn训练自己的数据集 前言 最近迷上了mask rcnn,也是由于自己工作需要吧,特意研究了其源代码,并基于自己的数据进行训练~ 本博客参考:ht ...

  3. Mask R-CNN训练日记

    Mask R-CNN训练集的踩坑日记 写在前面 Error1 Error2 Error3 Error4 Error5 Error6 写在结尾 写在前面 今天代码终于可以跑了,虽然训练的损失率很高,但是 ...

  4. 运行mask rcnn训练代码 程序在Epoch 1/20时出现程序挂起现象 解决办法

    问题描述 在运行mask rcnn训练代码 程序在Epoch 1/20时出现程序挂起现象,即程序运行但是跑不动,也不报错.如下所示: 解决办法 将keras版本修正为2.1.6即可,打开cmd,输入下 ...

  5. Mask Scoring RCNN训练自己的数据

    一. 代码准备 基于pytorch. mask scoring rcnn 代码参考:[github] mask rcnn benchmark [github] 二. 环境安装 1. 基于conda创建 ...

  6. Mask R-CNN 训练自己的数据集(balloon过程+报错解释)

    因项目需要,识别带有多边形标注的图像,舍弃了速度快精度高的yolov3,使用Mask R-CNN网络.作为一名深度学习小白,在摸爬滚打中查找资料修改代码以及不断地调整训练集,途中踩了不少坑,终于达到预 ...

  7. 从三个小时到25分钟:我们使用Apache MXNet优化Mask R-CNN训练时间全过程记录

    总览 在过去的几年中,深度神经网络(DNN)模型的规模和复杂性急剧增加.一方面,这些复杂的模型提高了模型在各种领域(例如计算机视觉,自然语言理解等)的准确性的门槛:另一方面,模型参数的庞大规模及其梯度 ...

  8. Mask R-CNN 训练自己的数据集—踩坑与填坑

    作者 | Raini 出品 | 北京图特摩斯科技有限公司(thutmose.cn) tensorflow/keras版(项目地址https://github.com/matterport). 服务器c ...

  9. 解决Mask RCNN训练时GPU内存溢出问题

    首先自己是个小白对于如何使用GPU跑程序这个学习了一下: (1)使用的是putty,安装了Anaconda这个IDE环境,用的conda install tensorflow-gpu安装的GPU版本t ...

  10. 利用边缘监督信息加速Mask R-CNN实例分割训练

    (欢迎关注"我爱计算机视觉"公众号,一个有价值有深度的公众号~) 今天跟大家分享一篇有意思的arXiv上新出的论文,作者来自德国宝马汽车公司(BMW Car IT GmbH,Ger ...

最新文章

  1. 青少年编程竞赛交流群周报(第042周)
  2. Nginx源码分析:惊群处理与负载均衡
  3. C++新增头文件.h,静态库.lib
  4. 39 岁网络技术员入住养老院,早 6 晚 9 的作息、和老人一起追剧晒太阳!
  5. CSS实现的阴影效果
  6. 中国石油计算机第二次在线作业,中国石油大学(北京)计算机应用基础第二次在线作业1教程.docx...
  7. ARM汇编中lr(r14)寄存器的作用
  8. UICollectionView reloadData后cell被隐藏
  9. redis java应用_redis在JAVA的简单应用
  10. python之字符编码(四)
  11. makefile--嵌套执行(四)
  12. 腾讯PCG事业部后台实习开发过经(已拿offer)
  13. 13.solr学习速成之IK分词器
  14. 工字型钢弹性截面模量计算公式_弹性截面模量与塑性截面模量的例析
  15. 最大子段和问题-蛮力法、分治法、动态规划法
  16. 社交网络和物联网技术,拓展了数据采集技术渠道
  17. 864. 二维数组区块计数
  18. HTML嵌套注释、多行注释、多级注释,提高生产力
  19. 水仙花数素数质因数分解的C语言实现
  20. Python自定义一个异常类【注释详细】

热门文章

  1. 龙门阵179期实录:技术专场之Android安全现状
  2. deepin标题栏边框美化
  3. linux中的dns中的hint,DNS问题
  4. React Native Apps的最佳主题
  5. 生成小程序支付的prepay_id-小程序支付开发-视频教程
  6. Win7笔记本电脑启用虚拟WIFI共享上网
  7. proteus学习笔记一:点亮LED
  8. 2013年4月TIOBE编程语言排行榜:Objective-C排名首次下滑
  9. ios 判断手机角度_iOS 角度获取及旋转
  10. 通过ReleaseId创建现有项目的KieContainer的时候,提示Cannot find KieModule