掩码R-CNN用于对象检测和分割[训练自定义数据集]

Vaj*_*aka 0 python machine-learning object-detection computer-vision semantic-segmentation

我正在研究" Mask R-CNN用于对象检测和分割".因此,我已阅读呈现原始研究论文Mask R-CNN为目标检测,也发现了我的几个实现Mask R-CNN,在这里这里(被Facebook人工智能研究小组称为detectron).但他们都使用coco数据集进行测试.

但是,对于使用具有大量图像的自定义数据集进行上述实现的培训,我有点困惑,并且对于每个图像,存在用于在相应图像中标记对象的掩模图像的子集.

所以,如果有人可以为此任务发布有用的资源或代码示例,我很高兴.

注意:我的数据集具有以下结构,

它包含大量图像,每个图像都有单独的图像文件,将对象突出显示为黑色图像中的白色色块.

这是一个示例图像和它的掩码:

图片;

在此输入图像描述

面具;

在此输入图像描述 在此输入图像描述

Aks*_*oam 9

我已经训练了https://github.com/matterport/Mask_RCNN的实例分段模型,以便在我的数据集上运行.

我的假设是您完成了所有基本设置,并且模型已经使用默认数据集运行,现在您希望它运行自定义数据集.

以下是步骤

  1. 您需要拥有所有注释.
  2. 所有这些都需要转换为VGG Polygon架构(是的,我的意思是多边形).我在本答案的最后添加了一个样本VGG Polygon格式.
  3. 您需要将自定义数据集划分为train,test和val
  4. 默认情况下,注释via_region_data.json在单个数据集文件夹中以文件名查找.例如,对于训练图像,它会看train\via_region_data.json.如果需要,您也可以更改它.
  5. 在Samples Samples文件夹中,您可以找到Balloon,Nucleus,Shapes等文件夹.复制其中一个文件夹.优选气球.我们现在将尝试为自定义数据集修改此新文件夹.
  6. 在复制的文件夹中,您将有一个.py文件(对于气球,它将是balloon.py),更改以下变量
    • ROOT_DIR :克隆项目的绝对路径
    • DEFAULT_LOGS_DIR:此文件夹的大小会更大,因此请相应地更改此路径(如果您在低磁盘存储VM中运行代码).它也会存储.h5文件.它将在日志文件夹中创建子文件夹,并附加时间戳.
    • .h5文件大约200 - 300 MB每个时期.但是猜猜这个日志目录与Tensorboard兼容.您可以--logdir在运行tensorboard时将带时间戳的子文件夹作为参数传递.
  7. .py文件还有两个类 - 一个带后缀的Config类,另一个带后缀的类Dataset.
  8. 在Config类中覆盖所需的东西
    • NAME :项目的名称.
    • NUM_CLASSES :它应该比标签类多一个,因为背景也被视为一个标签
    • DETECTION_MIN_CONFIDENCE :默认情况下为0.9(如果您的训练图像质量不高或者您没有太多训练数据,请减少它)
    • STEPS_PER_EPOCH 等等
  9. 在Dataset类中,重写以下方法.所有这些功能都已经过充分评论,因此您可以根据自己的需要跟踪评论.
    • load_(name_of_the_sample_project)例如load_balloon
    • load_mask(请参阅示例的最后一个答案)
    • image_reference
  10. 训练功能(数据集类外):如果你必须改变时期数或学习率等

您现在可以直接从终端运行它

python samples\your_folder_name\your_python_file_name.py train --dataset="location_of_custom_dataset" --weights=coco
Run Code Online (Sandbox Code Playgroud)

有关上述行的命令行参数的完整信息,您可以在此.py文件的顶部将其视为注释.

这些是我记忆中的事情,我想在记忆中添加更多步骤.也许你可以告诉我,如果你遇到任何特定的步骤,我会详细说明这一步骤.

VGG Polygon Schema

宽度和高度是可选的

[{
    "filename": "000dfce9-f14c-4a25-89b6-226316f557f3.jpeg",
    "regions": {
        "0": {
            "region_attributes": {
                "object_name": "Cat"
            },
            "shape_attributes": {
                "all_points_x": [75.30864197530865, 80.0925925925926, 80.0925925925926, 75.30864197530865],
                "all_points_y": [11.672189112257607, 11.672189112257607, 17.72093488703078, 17.72093488703078],
                "name": "polygon"
            }
        },
        "1": {
            "region_attributes": {
                "object_name": "Cat"
            },
            "shape_attributes": {
                "all_points_x": [80.40123456790124, 84.64506172839506, 84.64506172839506, 80.40123456790124],
                "all_points_y": [8.114103362391036, 8.114103362391036, 12.205901974737595, 12.205901974737595],
                "name": "polygon"
            }
        }
    },
    "width": 504,
    "height": 495
}]
Run Code Online (Sandbox Code Playgroud)

示例load_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 your dataset image, delegate to parent class.
    image_info = self.image_info[image_id]
    if image_info["source"] != "name_of_your_project":   //change your project name
        return super(self.__class__, self).load_mask(image_id)

    # Convert polygons to a bitmap mask of shape
    # [height, width, instance_count]
    info = self.image_info[image_id]
    mask = np.zeros([info["height"], info["width"], len(info["polygons"])], dtype=np.uint8)
    class_id =  np.zeros([mask.shape[-1]], dtype=np.int32)

    for i, p in enumerate(info["polygons"]):
        # Get indexes of pixels inside the polygon and set them to 1
        rr, cc = skimage.draw.polygon(p['all_points_y'], p['all_points_x'])
        # print(rr.shape, cc.shape, i, np.ones([mask.shape[-1]], dtype=np.int32).shape, info['classes'][i])

        class_id[i] = self.class_dict[info['classes'][i]]
        mask[rr, cc, i] = 1


    # Return mask, and array of class IDs of each instance. Since we have
    # one class ID only, we return an array of 1s
    return mask.astype(np.bool), class_id
Run Code Online (Sandbox Code Playgroud)