【阅读笔记】《Weakly- and Semi-Supervised Panoptic Segmentation》(二)——代码部分

本文记录了论文《Weakly- and Semi-Supervised Panoptic Segmentation》代码的阅读笔记。更新于2019.03.08。

demo_instanceTrainId_to_dets.m

输入: 读取实例训练标签,CityScapes中有11个stuff类别(stuff_classes = 0:10),8个thing类别(thing_classes = 11:18),读取了object name,忽略值为255的标签(ignore_label = 255)。

输入如下图:

在这里插入图片描述
在这里插入图片描述
最大值:18001

用于提取的主函数: instanceTrainId_to_dets.m,阅读笔记链接在这里。该函数的输出内容如下图所示(其中tmp是输出博主临时保存的名字),保存到的路径为'data/Cityscapes/gtFine_bboxes/train/panoptic'

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

instanceTrainId_to_dets.m

作用:

根据数据库给定的真值生成bounding boxes,为后续的MCG和GrabCut提供bounding box输入。

输入:

  1. label:实例训练标签。具体如下图所示。
    在这里插入图片描述
    在这里插入图片描述
    上层函数对此输入的读取方式:
    在这里插入图片描述
  2. is_panoptic:控制是否包含iamge-level stuff class dets,如果包含,设置成True。
  3. incl_grps:控制是否包含thing groups present in Cityscapes,如果包含,设置成True。
  4. stuff_classes:stuff类别的训练id(对Cityscapes是0:10)。
  5. thing_classes:thing类别的训练id(对Cityscapes是11:18)。
  6. objectNames:加载下来的目标名称。
  7. ignore_label:需要忽略的标签,对于label中的情况,忽略的是255。

输出:
在这里插入图片描述

具体过程:

  1. 提取出现过的类别并按顺序排列(升序),如下图:
    在这里插入图片描述
  2. 忽略其中ignore的标签,变成下图所示:(注意到其中255这个类别没有了)
    在这里插入图片描述

注:文件中说明,unique_ids中的每一个条目都是一个id

  • 如果id>1000,那么这是一个thing类别的实例 = trainId*1000+instance_id ……(case 1)
  • 如果id<=1000,那么如果是从0到10,那么就是stuff类别……(case 2),如果is_panoptic则包含image-wide det;如果是从11到18,那么就是thing group……(case 3),如果incl_grps则包含group-wide det。

对于stuff、thing instance和thing group这三个,博主的理解是,stuff是不可数,thing instance是可数目标的单独个体,thing group是同类可数目标的集合。

  1. 对所有的unique_ids遍历:
    若该标签属于case2,那么,xmin和ymin为‘0’,xmax和ymax分别对应整个画布的边缘,class为名字;
    若改标签属于case1,那么,找到图片中所有属于这个类别的位置并存入mask,xmin和ymin分别为该mask为1部分的最小列号和行号,xmax和ymax为最大列号和行号,class为名字;
    若case3,操作与case1相似,只是最开始的判断条件不同。

  2. 对所有有效的id,记录类别名称和以0开始的bounding box坐标。输出格式是这样的:
    在这里插入图片描述
    road类别的bndbox:
    在这里插入图片描述
    car类别的bndbox:
    在这里插入图片描述

demo_merge_cam_mandg.m

输入:

  1. 多类别分类器中获取的CAMs;
  2. MCG与GrabCut的融合线索。

注:
代码中没有给出提取CAMs的方法及文件,而是直接给出了CAMs的结果。当然,如果想训练自己的分类器,代码中也提供了下载地址(image-level tags + crops)。
其中论文用的是Grad-CAMGrabcutMCG。同样,Grabcut和MCG代码中也没有给出提取方法及文件,只给出了连接:MCG代码链接OpenCV版的Grabcut。也可以直接下载生成好的融合结果。

输出:

在这里插入图片描述

  • 首先调用demo_instanceTrainId_to_dets.m生成mask,具体看这里
  • 再运行get_opts生成必要的辅助内容,如路径、设置等等,具体看这里
  • 最后运行主函数run_sub生成最终结果,具体看这里
  • 显示用visualise_results_cam_mandg函数,具体看这里

demo_make_iterative_gt.m

用prediction和prediction scores(可选择是否加上M&G mask)生成下一次迭代需要的真值,这个函数是这一步骤的demo。

这个函数与demo_merge_cam_mandg.m(点击查看详情)基本相同,主体都是run_sub(点击查看详情)这个函数。博主注意到的唯一区别就是opt.run_score_thresh这个参数,demo_merge_cam_mandg.m这个文件将该参数设成了0,demo_make_iterative_gt.m这个文件将该参数设成了1。

下图为输出示例:

在这里插入图片描述

其他说明

如果要复现论文中的结果,在训练过程中迭代5次之后,将参数opts.run_merge_with_mcg_and_grabcut设成false,因为此时弱监督模型已经能生成比M&G mask更好的thing类别分割了。

重复训练和生成真值的步骤,直到训练过程的损失不再减小。

get_opts.m

输入: dataset的名字(比如cityscapes),分支(如train、val、train_extra)。

输出: 生成的options。

文件中设置的内容包括:

  1. 数据库的特殊设置,比如list路径、标注文件夹、真值文件夹等等;
  2. 数据库的统一设置,比如数据目录、标注模板、目标名字、colormap、尺寸、ignore_lable、类别范围等等。
  3. 任务特殊设定,比如路径、阈值、是否迭代、截图尺寸等。
  4. 一般设定,比如存储路径等普通路径、是否覆盖、是否保存结果、是否显示结果。
  5. 选择运行阶段,比如run_score_thresh、run_check_image_level_tags等。
  6. 是否生成实例真值。

注:目前只有cityscapes这一个数据库,其他数据库会显示"Unknown dataset option"。

下图为opts的内容:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

run_sub.m

对每张图片进行:

  1. 判断是否需要保存结果:如果结果已经存在且没有设置强制覆盖则忽略这张图。
  2. load_data.m(点击查看详细信息)加载必要的信息。
  3. clean_label.m(点击查看详细信息)文件处理原始估计,对语义分割的结果进行清理。
  4. ins_box_process.m(点击查看详细信息)文件创建实例标签。
  5. 每100张图汇报一下进度。

函数的输入是opts,输出为新的opts和估计结果results,其中包括语义分割结果results.final_pred、实例分割结果results.ins_pred和实例信息results.ins_info等。

输出示例:

results:
在这里插入图片描述
opts:
在这里插入图片描述

load_data.m

在这里插入图片描述
用于加载数据,包括真值等等,输出形如下图:
在这里插入图片描述
具体步骤:

  • 如果opts.run_score_thresh为真,则获取估计权重存入results.pred_scores
  • 如果opts.run_apply_bbox_prioropts.run_check_low_iouopts.run_ins_box_process这三个有一个为真,则读取bounding box信息存入results.gt_bbox_masksresults.gt_bboxes
  • 如果opts.run_check_image_level_tags为真,则读取真值信息存入results.gt_label
  • 如果opts.run_merge_with_mcg_and_grabcut为真,则读取MCG和GrabCut的结果,存入results.mandg_predresults.mandg_cmap

visualise_results_cam_mandg.m

显示original prediction,original prediction scores, processed semantic iterative GT, and generated instance。
opts(点击查看详细信息)中定义了用于显示的colormap。

clean_label.m

输入:

  • get_opts.m(点击查看详细信息)生成的options
  • 包含必要数据和原始估计的struct

下图是作为输入的results:

在这里插入图片描述

输出: 包含必要数据、原始估计和处理估计的struct

下图是作为输出的results:

在这里插入图片描述
第一部分:Confidence threshold

(需要 pred_scores + prediction + conf_thresh,如果opts.run_score_thresh为真运行这一部分)

results.final_pred在那些results.pred_scores小于opts.score_thresh的位置处的值会被设成opts.ignore_label。直观来说,就是把score小于阈值的位置的类别设成255。

下图是results.final_pred中包含的所有类别:
在这里插入图片描述

第二部分:用crops的image tags对stuff做类别检查
(需要 gt_label + prediction,如果opts.run_check_image_level_tags为真运行这一部分)

调用函数check_image_level_tags(点击查看详细信息),将结果存入results.pred_schk,再赋值给results.final_pred

作为输入的估计标签是results.final_pred,其中包括的标签形如:
在这里插入图片描述
真值形如:

在这里插入图片描述
具体流程看函数check_image_level_tags说明,其中被判断的是results.final_pred,用于作为真值的是results.gt_label

第三部分:将处理好的估计与MCG&Grabcut融合
(如果opts.run_merge_with_mcg_and_grabcut为真运行这一部分)

调用函数results.merge_mag_and_pred(点击查看详细信息),输出存入results.pred_merge_w_mandg,最终存入results.final_pred

第四部分:移除bounding boxes外的thing
(需要gt_bbox_masks + prediction,如果opts.run_apply_bbox_prior为真运行这一部分)

调用函数apply_bbox_prior.m(点击查看详细信息),将没有bounding box的类别或在bounding box之外的点设成ignore。

第五部分,IoU检查,将低IoU的部分设成纯色(solid color)
(需要gt_bboxes + prediction,如果opts.run_check_low_iou为真运行这一部分)

调用函数check_low_iou.m(点击查看详细信息),

ins_box_process.m

在这里插入图片描述
这个函数在给定语义分割真值估计的基础上,给出实例分割真值的估计。

认为thing group不属于实例。

具体步骤:
语义分割的ignore_label继承过来,也就是语义分割中定义为ignore,就还是ignore;
如果当前位置语义分割的结果对应当前类别,但是该位置上的实例分割已经有值了(比如是ignore或者之前迭代的时候已经赋值过),那么这个位置就设成ignore;否则,如果当前位置为0(没有值),就给该位置标注当前实例标签;
记录信息;
循环结束后检查,确保实例标注是连续的,不会跳过某个标注。

check_image_level_tags

这个文件检查prediction中与image-level tags相违背的部分。如果网络的prediction估计了一个class,但是其却没有显示标注的image-level tags,那么该估计label就会被换成ignore。
在这里插入图片描述

输入:

  • 估计标签
  • 用于生成image-level tags的真值
  • 截取尺寸
  • 图像尺寸
  • ignore_label

输出:
修改后的估计标签

具体流程

将整张图片按照要截取的尺寸分成各个滑动窗口(有重叠,重叠部分的尺寸根据crop和图像尺寸计算,最终结果就是整个图像都被扫描过),然后依次对每个滑动窗口比较prediction和tags,判断是否prediction中出现过的所有类别都在对应的tags中存在,如果不存在,设成ignore。

merge_mag_and_pred.m

在这里插入图片描述
检查,要求mag和pred的尺寸要相同。

第一部分:若m&g label估计了thing类别标签C1
保留mag中所有与pred估计相同的部分 -> 保留mag中所有mag与pred都有thing估计,但是二者估计不同的部分 -> 保留mag中mag估计为thing但是pred中估计为背景的部分 -> 保留mag中估计为thing但是pred估计为ignore的部分。

注:这一部分相当于给了mag优先级,也就是说只要mag认为是thing就保留。

第二部分:若m&g label估计了背景类别0
若mag估计为背景但是pred估计为thing,则将该位置变成ignore -> 若mag和pred都认为是stuff(mag估计为背景),那么保留pred的该部分 -> 若mag认为背景但是pred标注ignore,则标注ignore。

注:即对于stuff类别,除非二者都认为是stuff,才保留pred,否则都认为是ignore。

第三部分:若mag估计为ignore(255)
若mag为ignore但是pred认为是thing,设为ignore -> 若mag认为ignore但pred认为是stuff,则保留pred -> 若二者都是ignore,则ignore。

apply_bbox_prior.m

在这里插入图片描述

对所有存在的thing类别遍历,如果该类别对于当前图像不存在bounding box,则将pred_label中对应该类别的位置设成ignore;若存在,找到所有该类别的位置,将不在bounding box中的位置设成ignore。

check_low_iou.m

在这里插入图片描述
在这里插入图片描述
对标注为ignore和属于stuff类别的位置不做处理;
默认小目标在大目标前面;
忽略stuff类别(因为stuff的标注是image-level的);
忽略thing group,因为thing group boxes通常有低precision高recall的特征,不适合这种后处理方式;
将IoU低于阈值的窗口内的所有点换成gt_class(可以设置不改变ignore和stuff部分)。

Cityscapes

按照Readme中的说明,如果在第二步时想运行batch_instanceTrainId_to_dets.m这个文件,需要首先clone好cityscapes repository。这一部分介绍Cityscapes中的相关文件。

在Linux下运行的时候,clone好需要先到根目录下(有setup.py的那个路径),运行命令sudo pip install .,安装cityscapesscripts才可以,否则直接运行的时候会报错:“Importerror: No module named ‘cityscapes’.”

注:这个是在python2下的文件,如果用python3安装会报错(至少博主遇到的是这个情况)。修改系统默认的python版本的方法看这里

在Windows系统下运行,首先需要到第26行,将open("README.md")改成open("README.md",encodeing='UTF-8'),否则会报错:unicodedecodeerror: 'gbk' codec can't decode byte ...。然后在含有setup.py文件的路径下打开命令行,输入python setup.py install就可以了。安装这一步需要一些依赖项,如果没有它会自动安装,因此可能需要一段时间,耐心等待即可。

createTrainIdInstanceImgs.py

运行这个文件的时候要注意,下图中显示的CITYSCAPES_DATASET需要修改环境变量,存放cityscapes的路径。
在这里插入图片描述
加入星球了解更多分割知识:
在这里插入图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值