参考:

  • 使用Keras和Tensorflow设置和安装Mask RCNN
  • Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow

  • MaskRCNN识别Pascal VOC 2007
  • Pascal VOC 2007数据下载
    • 数据预览
  • 解析出imagemaskclass_nameclass_id
  • 重写ShapesConfig类
  • 重写ShapesDataset类
  • 最终结果

MaskRCNN识别Pascal VOC 2007

完整程序在这里


Pascal VOC 2007数据下载

wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCdevkit_08-Jun-2007.tar
# 执行以下命令将解压到一个名为VOCdevkit的目录中
tar xvf VOCtrainval_06-Nov-2007.tar
tar xvf VOCtest_06-Nov-2007.tar
tar xvf VOCdevkit_08-Jun-2007.tar

数据预览

1、VOC2007/Annotations

类别名与对象的矩形框位置

2、VOC2007/JPEGImages

3、VOC2007/SegmentationClass

4、VOC2007/SegmentationObject

解析出image,mask,class_name(class_id)

1、解析xml文件

import osfile_name=r'C:\Users\Administrator\Desktop\009901.xml'fp=open(file_name)for p in fp:if '<object>' in p:print(next(fp).split('>')[1].split('<')[0])if '<bndbox>' in p:print(next(fp).split('>')[1].split('<')[0])print(next(fp).split('>')[1].split('<')[0])print(next(fp).split('>')[1].split('<')[0])print(next(fp).split('>')[1].split('<')[0])
'''
person
104
76
199
337
……

2、从xml中解析出class,及矩形位置

def analyze_xml(file_name):'''从xml文件中解析class,对象位置:param file_name: xml文件位置:return: class,每个类别的矩形位置'''fp=open(file_name)class_name=[]rectangle_position=[]for p in fp:if '<object>' in p:class_name.append(next(fp).split('>')[1].split('<')[0])if '<bndbox>' in p:rectangle = [][rectangle.append(int(next(fp).split('>')[1].split('<')[0])) for _ in range(4)]rectangle_position.append(rectangle)# print(class_name)# print(rectangle_position)fp.close()return class_name,rectangle_position

3、解析所有的类别(生成class id)

def analyze_xml_class(file_names,class_name = []):'''解析xml的所有类别'''for file_name in file_names:with open(file_name) as fp:for p in fp:if '<object>' in p:class_name.append(next(fp).split('>')[1].split('<')[0])

4、将每张图片的image,mask,class_id 存放到pickle文件中,便于后续加载

for num,path in enumerate(Object_path):# 进度输出sys.stdout.write('\r>> Converting image %d/%d' % (num + 1, len(Object_path)))sys.stdout.flush()file_name=path.split('/')[-1].split('.')[0]Annotations_path_=os.path.join(Annotations_path,file_name+'.xml') # 对应的xml文件class_name,rectangle_position=analyze_xml(Annotations_path_)# 解析对象的mask[h,w,m] m为对象的个数,0、1组成的1波段图像mask_1=cv2.imread(path,0)masks=[]for rectangle in rectangle_position:mask=np.zeros_like(mask_1,np.uint8)mask[rectangle[1]:rectangle[3], rectangle[0]:rectangle[2]] = mask_1[rectangle[1]:rectangle[3],rectangle[0]:rectangle[2]]# 计算矩形中点像素值mean_x=(rectangle[0]+rectangle[2])//2mean_y=(rectangle[1]+rectangle[3])//2end=min((mask.shape[1],int(rectangle[2])+1))start=max((0,int(rectangle[0])-1))flag=Truefor i in range(mean_x,end):x_=i;y_=mean_ypixels = mask_1[y_, x_]if pixels!=0 and pixels!=220: # 0 对应背景 220对应边界线mask=(mask==pixels).astype(np.uint8)flag=Falsebreakif flag:for i in range(mean_x,start,-1):x_ = i;y_ = mean_ypixels = mask_1[y_, x_]if pixels != 0 and pixels != 220:mask = (mask == pixels).astype(np.uint8)break# 统一大小 64*n# mask=cv2.resize(mask,(h,w)) # 后面进行统一缩放masks.append(mask)# mask转成[h,w,m]格式masks=np.asarray(masks,np.uint8).transpose([1,2,0]) # [h,w,m]# class name 与class id 对应class_id=[][class_id.append(class_dict[i]) for i in class_name]class_id=np.asarray(class_id,np.uint8) # [m,]mask_1=None# images 原图像image = cv2.imread(os.path.join(Image_path, file_name + '.jpg'))# image = cv2.resize(image, (h, w)) # /255.  # 不需要转到0.~1. 程序内部会自动进行归一化处理# 图像与mask都进行缩放image, _, scale, padding=resize_image(image, min_dim=IMAGE_MIN_DIM, max_dim=IMAGE_MAX_DIM, padding=True)masks=resize_mask(masks, scale, padding)'''# 可视化结果num_masks=masks.shape[-1]for i in range(num_masks):plt.subplot(1,num_masks+1,i+2)plt.imshow(masks[:,:,i],'gray')plt.axis('off')plt.title(class_name_dict[class_id[i]])plt.subplot(1, num_masks + 1, 1)plt.imshow(image)plt.axis('off')plt.show()# '''object_data.append([image,masks,class_id])if num>0 and num%200==0:with open('./data/data_'+str(num)+'.pkl','wb') as fp:pickle.dump(object_data,fp)object_data=[]object_data.append([class_dict])if num==len(Object_path)-1 and object_data!=None:with open('./data/data_' + str(num) + '.pkl', 'wb') as fp:pickle.dump(object_data, fp)object_data = Nonesys.stdout.write('\n')
sys.stdout.flush()

重写ShapesConfig类

class ShapesConfig(Config):# 命名配置NAME = "shapes"# 输入图像resingIMAGE_MIN_DIM = 512IMAGE_MAX_DIM = 512# 使用的GPU数量。 对于CPU训练,请使用1GPU_COUNT = 1IMAGES_PER_GPU = int(1024 * 1024 * 4 // (IMAGE_MAX_DIM * IMAGE_MAX_DIM * 12))+1batch_size = GPU_COUNT * IMAGES_PER_GPUSTEPS_PER_EPOCH = int(train_images / batch_size * (3 / 4))VALIDATION_STEPS = STEPS_PER_EPOCH // (1000 // 50)NUM_CLASSES = 1 + 20  # 必须包含一个背景(背景作为一个类别)scale = 1024 // IMAGE_MAX_DIMRPN_ANCHOR_SCALES = (32 // scale, 64 // scale, 128 // scale, 256 // scale, 512 // scale)  # anchor side in pixelsRPN_NMS_THRESHOLD = 0.6  # 0.6RPN_TRAIN_ANCHORS_PER_IMAGE = 256 // scaleMINI_MASK_SHAPE = (56 // scale, 56 // scale)TRAIN_ROIS_PER_IMAGE = 200 // scaleDETECTION_MAX_INSTANCES = 100 * scale * 2 // 3DETECTION_MIN_CONFIDENCE = 0.6

重写ShapesDataset类

class ShapesDataset(utils.Dataset):def __init__(self,pkl_path,class_map=None):super(ShapesDataset, self).__init__(class_map)self.pkl_path=pkl_pathdef load_shapes(self, count, height, width):data=self.load_pkl()class_dict=data[0][0] # 所有类别字典 从1开始# self.add_class("shapes", 0, 'BG') # 标签0默认为背景 utils中已经添加了 这里不用再添加# self.add_class("shapes", 1, "square")# self.add_class("shapes", 2, "circle")# self.add_class("shapes", 3, "triangle")# 必须从1、2、3、……开始添加,否则会出错 ,下面这种情况会导致标签对不上# [self.add_class('shapes',class_dict[i],i) for i in list(class_dict.keys())] # 无序添加会导致标签对应不上# class id反算出class nameclass_name_dict = dict(zip(class_dict.values(), class_dict.keys()))[self.add_class('shapes',i,class_name_dict[i]) for i in range(1,21)] # 共20类'''for i in range(count):comb_image, mask, class_ids = self.random_image(height, width)self.add_image("shapes", image_id=i, path=None,width=width, height=height,image=comb_image, mask=mask, class_ids=class_ids)'''for i in range(1,len(data)):comb_image=data[i][0]mask=data[i][1]class_ids=data[i][2]self.add_image("shapes", image_id=i-1, path=None,width=height, height=width,image=comb_image, mask=mask, class_ids=class_ids)def load_image(self, image_id):info = self.image_info[image_id]image = info['image']return imagedef image_reference(self, image_id):"""Return the shapes data of the image."""info = self.image_info[image_id]if info["source"] == "shapes":return info["shapes"]else:super(self.__class__).image_reference(self, image_id)def load_mask(self, image_id):info = self.image_info[image_id]mask = info['mask']class_ids = info['class_ids']return mask, class_ids.astype(np.int32)'''def random_shape(self,height, width):# Shapeshape = random.choice(["square", "circle", "triangle"])# Colorcolor = tuple([random.randint(0, 255) for _ in range(3)])# Center x, ybuffer = 20y = random.randint(buffer, height - buffer - 1)x = random.randint(buffer, width - buffer - 1)# Sizes = random.randint(buffer, height // 4)return shape, color, (x, y, s)def random_image(self,height, width):# Pick random background colorbg_color = np.array([random.randint(0, 255) for _ in range(3)])# images=[]mask = []class_id = []bg_color = bg_color.reshape([1, 1, 3])image = np.ones([height, width, 3], dtype=np.uint8)image = image * bg_color.astype(np.uint8)N = random.randint(1, 4)for _ in range(N):image_mask = np.zeros([height, width], dtype=np.uint8)shape, color, dims = self.random_shape(height, width)x, y, s = dimsif shape == 'square':cv2.rectangle(image, (x - s, y - s), (x + s, y + s), color, -1)cv2.rectangle(image_mask, (x - s, y - s), (x + s, y + s), 1, -1)  # 0、1组成的图片# images.append(img)mask.append(image_mask)class_id.append(1)  # 对应class ID 1elif shape == "circle":cv2.circle(image, (x, y), s, color, -1)cv2.circle(image_mask, (x, y), s, 1, -1)# images.append(img)mask.append(image_mask)class_id.append(2)  # 对应class ID 2elif shape == "triangle":points = np.array([[(x, y - s),(x - s / math.sin(math.radians(60)), y + s),(x + s / math.sin(math.radians(60)), y + s),]], dtype=np.int32)cv2.fillPoly(image, points, color)cv2.fillPoly(image_mask, points, 1)# images.append(img)mask.append(image_mask)class_id.append(3)  # 对应class ID 3# images=np.asarray(images,np.float32) # [h,w,c]mask = np.asarray(mask, np.uint8).transpose([1, 2, 0])  # [h,w,instance count]class_id = np.asarray(class_id, np.uint8)  # [instance count,]# Handle occlusions 处理遮挡情况count = mask.shape[-1]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]))# 如果mask 全为0 也就是意味着完全被遮挡,需丢弃这种mask,否则训练会报错# (而实际标注mask时不会出现这种情况的,因为完全遮挡了没办法标注mask)if np.sum(mask[:, :, i]) < 1:  # 完全被遮挡mask = np.delete(mask, i, axis=-1)class_id = np.delete(class_id, i)  # 对应的mask的class id 也需删除return image, mask, class_id'''def load_pkl(self):with open(self.pkl_path, 'rb') as fp:data = pickle.load(fp)return data

最终结果

mAP: 0.6333333358168602

MaskRCNN识别Pascal VOC 2007相关推荐

  1. Retinanet训练Pascal VOC 2007

    参考: fizyr/keras-retinanet facebookresearch/Detectron kuangliu/pytorch-retinanet CasiaFan/tensorflow_ ...

  2. 如何快速下载Pascal VOC 2007数据集(某些数据集也可以这样尝试)

    直接进入正题,截图加步骤,我用的是迅雷下载 1.这三个网址就是数据集的下载网址. http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_ ...

  3. 目标检测数据集PASCAL VOC简介

    简介 PASCAL VOC挑战赛 (The PASCAL Visual Object Classes )是一个世界级的计算机视觉挑战赛, PASCAL全称:Pattern Analysis, Stat ...

  4. 目标检测:PASCAL VOC 数据集简介

    一.简介 PASCAL VOC 挑战赛主要有 Object Classification .Object Detection.Object Segmentation.Human Layout.Acti ...

  5. Dataset之Pascal:Pascal竞赛及其Pascal VOC(VOC 2012、VOC 2007) 数据集的简介、下载、使用方法详细攻略

    Dataset之Pascal VOC:Pascal VOC(VOC 2012.VOC 2007) 数据集的简介.下载.使用方法详细攻略 目录 Pascal 竞赛 1.PASCAL VOC竞赛任务 2. ...

  6. 建立自己的voc数据集_一次将自己的数据集制作成PASCAL VOC格式的惨痛经历

    因为准备训练keras-yolo3,开源代码上给出了voc_annotation.py文件,只要将自己的数据格式处理成PASCAL VOC格式,那么运行voc_annotation.py就可以将自己的 ...

  7. 目标检测实战篇1——数据集介绍(PASCAL VOC,MS COCO)

    前言   前面我们讲过了目标检测的YOLO系列算法,SSD算法.从这个博文开始,我们要真实开启实战篇章.在正式介绍实战篇之前,我们需要先知道两个数据集:PASCAL VOC和COCO数据集. 一.PA ...

  8. 目标检测数据集VOC 2007/2012 整理

    做目标检测时我们经常用到voc 2007, voc 2012 数据集,今天就来整理一下. 数据集的下载地址: https://pjreddie.com/projects/pascal-voc-data ...

  9. Pascal VOC 数据集介绍(tensorflow model zoo)

    Pascal VOC 数据集的下载 # 下载2007年的训练数据 wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06- ...

  10. PASCAL VOC

    参考网页:http://www.360doc.com/content/13/0517/10/1054746_286033689.shtml  PASCAL VOC(pattern analysis,s ...

最新文章

  1. chrome 硬件渲染(GPU Accelerated Compositing in Chrome)
  2. MultiBoot设计参考链接
  3. 《Effective Java 2nd》第4章 类和接口
  4. Flutter混合开发:Android中如何启动Flutter
  5. ECharts 雷达图在类目值下面显示数值
  6. 基于java SSM图书管理系统简单版设计和实现
  7. k8s高可用集群_搭建高可用集群(部署master2和node节点)---K8S_Google工作笔记0058
  8. java的cxf的maven_Maven+Spirng+Mybatis+CXF搭建WebService服务
  9. JavaScript(三)数据类型转换
  10. Zuul 代理文件上传、为路由提供 hystrix 回退、过滤器、超时时间
  11. 你还在期待彩票中奖么?
  12. 百度诉被奇虎科技有限公司(以下简称北京奇虎公司)、奇虎三六零软件(北京)有限公司(以下简称奇虎三六零公司)不正当竞争纠纷一案
  13. win7显示500服务器错误,搞定win10系统提示http500内部服务器错误的解决步骤
  14. python xlwt 设置表格的行高方法
  15. 如何在iphone上模拟定位
  16. python --安装pylab
  17. ipa在线安装搭建_HBuilder如何打包ipa文件?如何获取苹果证书?
  18. Vivado 综合约束实用命令(更新中……)
  19. 覆盖Laracon:在线会议会向内倾吗?
  20. 苹果编辑器在哪_苹果 WWDC 2020 发布的ARKit 4 为何低调 ?

热门文章

  1. python的def语句_关于语法:python def函数:如何指定函数的结尾?
  2. a10 amd 安装黑苹果_黑苹果整合版系统U盘镜像Niresh macOS Sierra 10.12.3 支持Intel/AMD......
  3. JS JavaScript 实现文字上下滚动效果
  4. Jasmine JavaScript测试 - toBe vs toEqual
  5. gzip already installed and latest version解决方法
  6. 免上传音乐外链(QQ音乐)
  7. 把EditPlus添加到右键快捷菜单
  8. 免费和开源引擎的游戏引擎,转载自维基
  9. 禁用浏览器的后退按钮
  10. DeleteRow()