MaskRCNN识别Pascal VOC 2007
参考:
- 使用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相关推荐
- Retinanet训练Pascal VOC 2007
参考: fizyr/keras-retinanet facebookresearch/Detectron kuangliu/pytorch-retinanet CasiaFan/tensorflow_ ...
- 如何快速下载Pascal VOC 2007数据集(某些数据集也可以这样尝试)
直接进入正题,截图加步骤,我用的是迅雷下载 1.这三个网址就是数据集的下载网址. http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_ ...
- 目标检测数据集PASCAL VOC简介
简介 PASCAL VOC挑战赛 (The PASCAL Visual Object Classes )是一个世界级的计算机视觉挑战赛, PASCAL全称:Pattern Analysis, Stat ...
- 目标检测:PASCAL VOC 数据集简介
一.简介 PASCAL VOC 挑战赛主要有 Object Classification .Object Detection.Object Segmentation.Human Layout.Acti ...
- Dataset之Pascal:Pascal竞赛及其Pascal VOC(VOC 2012、VOC 2007) 数据集的简介、下载、使用方法详细攻略
Dataset之Pascal VOC:Pascal VOC(VOC 2012.VOC 2007) 数据集的简介.下载.使用方法详细攻略 目录 Pascal 竞赛 1.PASCAL VOC竞赛任务 2. ...
- 建立自己的voc数据集_一次将自己的数据集制作成PASCAL VOC格式的惨痛经历
因为准备训练keras-yolo3,开源代码上给出了voc_annotation.py文件,只要将自己的数据格式处理成PASCAL VOC格式,那么运行voc_annotation.py就可以将自己的 ...
- 目标检测实战篇1——数据集介绍(PASCAL VOC,MS COCO)
前言 前面我们讲过了目标检测的YOLO系列算法,SSD算法.从这个博文开始,我们要真实开启实战篇章.在正式介绍实战篇之前,我们需要先知道两个数据集:PASCAL VOC和COCO数据集. 一.PA ...
- 目标检测数据集VOC 2007/2012 整理
做目标检测时我们经常用到voc 2007, voc 2012 数据集,今天就来整理一下. 数据集的下载地址: https://pjreddie.com/projects/pascal-voc-data ...
- Pascal VOC 数据集介绍(tensorflow model zoo)
Pascal VOC 数据集的下载 # 下载2007年的训练数据 wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06- ...
- PASCAL VOC
参考网页:http://www.360doc.com/content/13/0517/10/1054746_286033689.shtml PASCAL VOC(pattern analysis,s ...
最新文章
- chrome 硬件渲染(GPU Accelerated Compositing in Chrome)
- MultiBoot设计参考链接
- 《Effective Java 2nd》第4章 类和接口
- Flutter混合开发:Android中如何启动Flutter
- ECharts 雷达图在类目值下面显示数值
- 基于java SSM图书管理系统简单版设计和实现
- k8s高可用集群_搭建高可用集群(部署master2和node节点)---K8S_Google工作笔记0058
- java的cxf的maven_Maven+Spirng+Mybatis+CXF搭建WebService服务
- JavaScript(三)数据类型转换
- Zuul 代理文件上传、为路由提供 hystrix 回退、过滤器、超时时间
- 你还在期待彩票中奖么?
- 百度诉被奇虎科技有限公司(以下简称北京奇虎公司)、奇虎三六零软件(北京)有限公司(以下简称奇虎三六零公司)不正当竞争纠纷一案
- win7显示500服务器错误,搞定win10系统提示http500内部服务器错误的解决步骤
- python xlwt 设置表格的行高方法
- 如何在iphone上模拟定位
- python --安装pylab
- ipa在线安装搭建_HBuilder如何打包ipa文件?如何获取苹果证书?
- Vivado 综合约束实用命令(更新中……)
- 覆盖Laracon:在线会议会向内倾吗?
- 苹果编辑器在哪_苹果 WWDC 2020 发布的ARKit 4 为何低调 ?
热门文章
- python的def语句_关于语法:python def函数:如何指定函数的结尾?
- a10 amd 安装黑苹果_黑苹果整合版系统U盘镜像Niresh macOS Sierra 10.12.3 支持Intel/AMD......
- JS JavaScript 实现文字上下滚动效果
- Jasmine JavaScript测试 - toBe vs toEqual
- gzip already installed and latest version解决方法
- 免上传音乐外链(QQ音乐)
- 把EditPlus添加到右键快捷菜单
- 免费和开源引擎的游戏引擎,转载自维基
- 禁用浏览器的后退按钮
- DeleteRow()