ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Maskrcnn实现笔记---数据处理篇

2021-11-03 21:02:27  阅读:234  来源: 互联网

标签:name img mask Maskrcnn label --- 数据处理 path os


目录


前言

在深度学习中,数据集一般是指用作网络训练的数据集合。数据集包含输入和真实输出(ground truth)两部分,视觉类深度学习中输入为图片,输出为分类结果、预测框及分割结果等。
数据集一般会分为训练集(train dataset)、验证集(valid dataset)和测试集(test dataset)三部分,训练集用于网络训练,验证集一般用于在训练是验证训练效果,根据训练效果保存训练最好的模型,测试集测试训练效果。

一、labelme标定

maskrcnn需要的输入为图片,输出为lable、box及mask。正常讲应该在标定的时候,label、box和mask都进行标定,但是实际上box可以由mask推出,所以只需要标定mask及label即可。
1.安装labelme
在anaconda中新建一个环境命名为lableme,安装labelme。

# python3
conda create --name=labelme python=3.6
source activate labelme
# install pyqt
pip install pyqt5  # pyqt5 can be installed via pip on python3
# instal labelme
pip install labelme

2.标记
cmd中或anaconda中:activate labelme,labeleme。打开labelme,create polygons,把需要检测分割的对象分割出来,打上标签。
在这里插入图片描述
一个个标注好了之后,将生成json文件。

二、对data进一步处理

1.数据增强

如果自己的数据比较少的话,为了避免过拟合等问题,最好进行下数据增强。可以加噪音,翻转等操作。

2.json_to_dataset

批量给它转成dataset
批量json to dataset,将生成四个文件,都放在一个文件夹下了。
也可以把里面的json_to_dataset.py文件复制到自己的项目中,修改一下,直接指定路径是自己标记好的Json文件夹,输出的路径也进一步修改下,可以把生成的dataset生成到项目文件夹下。修改如下:

import argparse
import base64
import json
import os
import os.path as osp

import imgviz
import PIL.Image

from labelme.logger import logger
from labelme import utils


def main():

    # 输入路径
    json_file = "./json_files"

    # 为了批量处理的改动1,获得目录下所有的.json后缀文件
    path = []
    file_name = []
    for root, dirs, files in os.walk(json_file):  # 获取所有文件
        for file in files:  # 遍历所有文件名
            if os.path.splitext(file)[1] == '.json':  # 指定尾缀
                file_name.append(file.split('.')[0])   # 为了获取**.json中的**
                path.append(os.path.join(root, file))  # 拼接绝对路径并放入列表
    print('总文件数目:', len(path))

    # 为了批量处理改动2,都放入循环中
    for i in range(len(path)):
        data = json.load(open(path[i]))
        imageData = data.get("imageData")

        if not imageData:
            imagePath = os.path.join(os.path.dirname(json_file), data["imagePath"])
            with open(imagePath, "rb") as f:
                imageData = f.read()
                imageData = base64.b64encode(imageData).decode("utf-8")
        img = utils.img_b64_to_arr(imageData)

        label_name_to_value = {"_background_": 0}
        for shape in sorted(data["shapes"], key=lambda x: x["label"]):
            label_name = shape["label"]
            if label_name in label_name_to_value:
                label_value = label_name_to_value[label_name]
            else:
                label_value = len(label_name_to_value)
                label_name_to_value[label_name] = label_value
        lbl, _ = utils.shapes_to_label(
            img.shape, data["shapes"], label_name_to_value
        )

        label_names = [None] * (max(label_name_to_value.values()) + 1)
        for name, value in label_name_to_value.items():
            label_names[value] = name

        lbl_viz = imgviz.label2rgb(
            label=lbl, img=imgviz.asgray(img), label_names=label_names, loc="rb"
        )

        # 输出路径
        if not os.path.exists("train_dataset"):
            os.mkdir("train_dataset")
        mask_path = "train_dataset/mask"
        if not os.path.exists(mask_path):
            os.mkdir(mask_path)
        img_path = "train_dataset/imgs"
        if not os.path.exists(img_path):
            os.mkdir(img_path)
        class_path = "train_dataset/classes"
        if not os.path.exists(class_path):
            os.mkdir(class_path)
        label_viz_path = "train_dataset/label_viz"
        if not os.path.exists(label_viz_path):
            os.mkdir(label_viz_path)

        # 改动3:下面加了四个filename,1和2都是为了输出的时候名字改变
        PIL.Image.fromarray(img).save(osp.join(img_path, file_name[i]+".png"))
        utils.lblsave(osp.join(mask_path, file_name[i]+"_label.png"), lbl)
        PIL.Image.fromarray(lbl_viz).save(osp.join(label_viz_path, file_name[i]+"_label_viz.png"))

        with open(osp.join(class_path, file_name[i]+"label_names.txt"), "w") as f:
            for lbl_name in label_names:
                f.write(lbl_name + "\n")

        logger.info("Saved {0} files".format(i+1))



if __name__ == "__main__":
    main()

我的文件夹结构:
在这里插入图片描述
以上数据集的准备任务就完成了,下面是实际训练的时候所用的函数。

三、实际训练数据集处理

定义一个自己的数据集类,对处理过的train_dataset进行读取解析。
映射式数据集,需要定义__init__()和__getitem__()方法,之后利用torch.utitls.Dataloader()进行加载,分为一个个batch进行训练。

class PennFudanDataset(object):
    def __init__(self, root, transforms):
        self.root = root
        self.transforms = transforms
        # load all image files, sorting them to
        # ensure that they are aligned
        self.imgs = list(sorted(os.listdir(os.path.join(root, "images"))))
        self.jsons = list(sorted(os.listdir(os.path.join(root, "jsons"))))

    def __getitem__(self, idx):
        # load images and masks
        img_path = os.path.join(self.root, "images", self.imgs[idx])
        json_path = os.path.join(self.root, "jsons", self.jsons[idx])
        img = Image.open(img_path).convert("RGB")

        mask = Image.open(json_path)

        mask = np.array(mask)
        # instances are encoded as different colors
        obj_ids = np.unique(mask)  # 原图被处理为,背景部分为0,第一个行人为1.第二个为2,以此类推。
        # first id is the background, so remove it
        obj_ids = obj_ids[1:]

        # split the color-encoded mask into a set
        # of binary masks
        masks = mask == obj_ids[:, None, None]

        # get bounding box coordinates for each mask
        num_objs = len(obj_ids)
        boxes = []
        """box是通过掩码得到的,那可以直接把mask改成抓取描述,由抓取描述也可以得到boxes吧"""
        for i in range(num_objs):
            pos = np.where(masks[i])
            xmin = np.min(pos[1])
            xmax = np.max(pos[1])
            ymin = np.min(pos[0])
            ymax = np.max(pos[0])
            boxes.append([xmin, ymin, xmax, ymax])

        boxes = torch.as_tensor(boxes, dtype=torch.float32)
        # there is only one class
        labels = torch.ones((num_objs,), dtype=torch.int64)
        masks = torch.as_tensor(masks, dtype=torch.uint8)

        image_id = torch.tensor([idx])
        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
        # suppose all instances are not crowd
        iscrowd = torch.zeros((num_objs,), dtype=torch.int64)

        target = {}
        target["boxes"] = boxes
        target["labels"] = labels
        target["masks"] = masks
        target["image_id"] = image_id
        target["area"] = area
        target["iscrowd"] = iscrowd

        if self.transforms is not None:
            img, target = self.transforms(img, target)

        return img, target

    def __len__(self):
        return len(self.imgs)

标签:name,img,mask,Maskrcnn,label,---,数据处理,path,os
来源: https://blog.csdn.net/Tepmoe/article/details/121100146

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有