由于上一篇中已经搭建了mmdetection的环境,本实验中沿用上一个环境
源码https://github.com/open-mmlab/mmsegmentation下载zip,解压,然后使用pip install -v -e .
进行安装
跑示例demo进行验证
第一步 我们需要下载配置文件和模型权重文件。
mim download mmsegmentation --config pspnet_r50-d8_512x1024_40k_cityscapes --dest .
完成后,你会在当前文件夹中发现两个文件pspnet_r50-d8_512x1024_40k_cityscapes.py和pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth。
第二步 验证推理示例
python demo/image_demo.py demo/demo.png pspnet_r50-d8_512x1024_40k_cityscapes.py pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth --device cpu --out-file result.jpg
在当前文件夹中看到一个新的图像result.jpg,其中的分割掩膜覆盖在所有对象上。
成功
数据集准备,推荐在 mmsegmetaion 目录新建路径 data-my_data,然后将数据集转换成 MMSegmentation 可用的格式,我采用的是VOC2012格式
│ ├── VOCdevkit
│ │ ├── VOC2012
│ │ │ ├── JPEGImages
│ │ │ ├── SegmentationClass
│ │ │ ├── ImageSets
│ │ │ │ ├── Segmentation
# dataset settings
dataset_type = 'groupVOCDataset'
data_root = 'data/my_dataset'
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
crop_size = (512, 512)
train_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations'),
dict(type='Resize', img_scale=(2048, 512), ratio_range=(0.5, 2.0)),
dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
dict(type='RandomFlip', prob=0.5),
dict(type='PhotoMetricDistortion'),
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
dict(type='DefaultFormatBundle'),
dict(type='Collect', keys=['img', 'gt_semantic_seg']),
]
test_pipeline = [
dict(type='LoadImageFromFile'),
dict(
type='MultiScaleFlipAug',
img_scale=(2048, 512),
# img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],
flip=False,
transforms=[
dict(type='Resize', keep_ratio=True),
dict(type='RandomFlip'),
dict(type='Normalize', **img_norm_cfg),
dict(type='ImageToTensor', keys=['img']),
dict(type='Collect', keys=['img']),
])
]
data = dict(
samples_per_gpu=4,
workers_per_gpu=4,
train=dict(
type=dataset_type,
data_root=data_root,
img_dir='JPEGImages',
ann_dir='SegmentationClass',
split='ImageSets/Segmentation/train.txt',
pipeline=train_pipeline),
val=dict(
type=dataset_type,
data_root=data_root,
img_dir='JPEGImages',
ann_dir='SegmentationClass',
split='ImageSets/Segmentation/val.txt',
pipeline=test_pipeline),
test=dict(
type=dataset_type,
data_root=data_root,
img_dir='JPEGImages',
ann_dir='SegmentationClass',
split='ImageSets/Segmentation/val.txt',
pipeline=test_pipeline))
dataset_type:更改为自己数据集的类型,可以自己命名,也可以不动;
data_root:更改为自己数据集的路径;
img_dir:更改为自己数据集图片路径;
ann_dir:更改为自己数据集标签的路径;
split:更改为自己的train.txt路径。
其他参数的含义:
img_norm_cfg:数据集的方差与均差
crop_size:数据增强时裁剪的大小
image_scale:原始图像大小
sample_per_gpu: batch size
works_per_gpu: dataloader的线程数目,一般设置为2,4,8
photoMetricDistortion:数据增强操作。分贝是亮度、对比度、饱和度和色调。
# Copyright (c) OpenMMLab. All rights reserved.
import os.path as osp
from .builder import DATASETS
from .custom import CustomDataset
@DATASETS.register_module()
class groupVOCDataset(CustomDataset):#改成自己的
"""Pascal VOC dataset.
Args:
split (str): Split txt file for Pascal VOC.
"""
#改
CLASSES = ('background', 'white_edge', 'silver_defect', 'white_exposed', 'top_half', 'bottom_half',
'triangle', 'black_spot', 'sides', 'bag_sides', 'small_white_strip')
#个数保持一致
PALETTE = [[0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0], [0, 0, 128],
[128, 0, 128], [0, 128, 128], [128, 128, 128], [64, 0, 0],
[192, 0, 0], [64, 128, 0]]
def __init__(self, split, **kwargs):
super(groupVOCDataset, self).__init__(
img_suffix='.jpg', seg_map_suffix='.png', split=split, **kwargs)
assert osp.exists(self.img_dir) and self.split is not None
设置好之后,还需要设置一下该目录下的__init__文件:
# Copyright (c) OpenMMLab. All rights reserved.
from .ade import ADE20KDataset
from .builder import DATASETS, PIPELINES, build_dataloader, build_dataset
from .chase_db1 import ChaseDB1Dataset
from .cityscapes import CityscapesDataset
from .coco_stuff import COCOStuffDataset
from .custom import CustomDataset
from .dark_zurich import DarkZurichDataset
from .dataset_wrappers import (ConcatDataset, MultiImageMixDataset,
RepeatDataset)
from .drive import DRIVEDataset
from .hrf import HRFDataset
from .isaid import iSAIDDataset
from .isprs import ISPRSDataset
from .loveda import LoveDADataset
from .night_driving import NightDrivingDataset
from .pascal_context import PascalContextDataset, PascalContextDataset59
from .potsdam import PotsdamDataset
from .stare import STAREDataset
from .voc import PascalVOCDataset
from .mydata_voc import groupVOCDataset
__all__ = [
'CustomDataset', 'build_dataloader', 'ConcatDataset', 'RepeatDataset',
'DATASETS', 'build_dataset', 'PIPELINES', 'CityscapesDataset',
'PascalVOCDataset', 'ADE20KDataset', 'PascalContextDataset',
'PascalContextDataset59', 'ChaseDB1Dataset', 'DRIVEDataset', 'HRFDataset',
'STAREDataset', 'DarkZurichDataset', 'NightDrivingDataset',
'COCOStuffDataset', 'LoveDADataset', 'MultiImageMixDataset',
'iSAIDDataset', 'ISPRSDataset', 'PotsdamDataset','groupVOCDataset'
]
import的时候要把自己的Dataset加载进来
__all__数组里面需要加入自己的Dataset类名称
_base_ = [
'../_base_/models/bisenetv2.py',
'../_base_/datasets/mydata_voc2012.py',
'../_base_/default_runtime.py', '../_base_/schedules/schedule_160k.py'
]
lr_config = dict(warmup='linear', warmup_iters=1000)
optimizer = dict(lr=0.05)
data = dict(
samples_per_gpu=4,
workers_per_gpu=4,
)
python tools/train.py E:\PycharmProjects\mmsegmentation-master\configs\bisenetv2\bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py --work-dir workplace
python tools/test.py configs/bisenetv2/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py workplace/latest.pth --show-dir workplace/output_dir
137/137, 3.4 task/s, elapsed: 40s, ETA: 0s
demo展示
python demo/image_demo.py data/my_dataset/JPEGImages/20220328_white_6.jpg work_dirs/my_psp/my_psp.py work_dirs/my_psp/latest.pth --device cuda:0 --palette mydata
python tools/deploy.py configs/mmdet/detection/detection_tensorrt_dynamic-320x320-1344x1344.py ../mmdetection-master/configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py ../mmdetection-master/checkpoints/latest.pth ../mmdetection-master/demo/1.jpg --work-dir ../mmdeploy_out/mmdet/faster_rcnn_r50_trt/ --device cuda:0 --dump-info
python tools/pytorch2onnx.py \
configs/bisenetv2、bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py
--checkpoint ${CHECKPOINT_FILE} \
--output-file ${ONNX_FILE} \
--input-img ${INPUT_IMG} \
--shape ${INPUT_SHAPE} \
--rescale-shape ${RESCALE_SHAPE} \
--show \
--verify \
--dynamic-export \
--cfg-options \
model.test_cfg.mode="whole"
config : 模型配置文件的路径
checkpoint : 模型检查点文件的路径
output-file: 输出的 ONNX 模型的路径。如果没有专门指定,它默认是 tmp.onnx
input-img : 用来转换和可视化的一张输入图像的路径
shape: 模型的输入张量的高和宽。如果没有专门指定,它将被设置成 test_pipeline 的 img_scale
rescale-shape: 改变输出的形状。设置这个值来避免 OOM,它仅在 slide 模式下可以用
show: 是否打印输出模型的结构。如果没有被专门指定,它将被设置成 False
verify: 是否验证一个输出模型的正确性 (correctness)。如果没有被专门指定,它将被设置成 False
dynamic-export: 是否导出形状变化的输入与输出的 ONNX 模型。如果没有被专门指定,它将被设置成 False
cfg-options: 更新配置选项
python ./tools/deploy.py
configs/mmseg/segmentation_tensorrt_dynamic-512x1024-2048x2048.py
../mmsegmentation-master/configs/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py
../mmsegmentation-master/checkpoints/latest.pth
../mmsegmentation-master/workplace/demo/1.jpg
--work-dir ../mmdeploy_out/mmseg/bisenetv2
--show
--device cuda:0
python ./tools/deploy.py configs/mmseg/segmentation_tensorrt_dynamic-512x1024-2048x2048.py ../mmsegmentation-master/configs/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py ../mmsegmentation-master/checkpoints/latest.pth ../mmsegmentation-master/workplace/demo/1.jpg --work-dir ../mmdeploy_out/mmseg/bisenetv2 --show --device cuda:0
python tools/deploy.py configs/mmseg/segmentation_tensorrt_static-512x512.py ../mmsegmentation-master/configs/bisenetv2/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes.py ../mmsegmentation-master/checkpoints/bisenetv2/latest.pth ../mmsegmentation-master/workplace/demo/1.jpg --work-dir ../mmdeploy_out/mmseg/bisenetv2/test/ --device cuda:0 --dump-info
部署完成以后在c++中使用exe文件进行推理
cd Release
image_segmentation.exe cuda E:\\PycharmProjects\\mmdeploy_out\\mmseg\\bisenetv2 E:\\PycharmProjects\\mmsegmentation-master\\workplace\\demo\\1.jpg
image_segmentation.exe cuda E:\\PycharmProjects\\mmdeploy_out\\mmseg\\bisenetv2\\test E:\\PycharmProjects\\mmsegmentation-master\\workplace\\demo\\1.jpg