From 297d9e5f924102c76b59c1e45c473b00951e79b0 Mon Sep 17 00:00:00 2001 From: LutaoChu <30695251+LutaoChu@users.noreply.github.com> Date: Fri, 10 Jan 2020 12:09:16 +0800 Subject: [PATCH] =?UTF-8?q?contrib=E7=9B=AE=E5=BD=95=E4=BC=98=E5=8C=96(#14?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update all docs involving color label * modify usage.md * usage.md * Update data_prepare.md * Update jingling2seg.md * Update jingling2seg.md * Update labelme2seg.md * Update jingling2seg.md * a * Update config.md * Update config.md * Update config.py * Update config.py * Update config.py * Update config.md * Update basic_group.md * Update basic_group.md * Update data_aug.md * Update config.md * Update finetune_pspnet.md * Update finetune_pspnet.md * Update finetune_unet.md * Update finetune_unet.md * Update finetune_icnet.md * Update finetune_pspnet.md * Update finetune_hrnet.md * Update README.md * Update finetune_deeplabv3plus.md * Update finetune_deeplabv3plus.md * Update README.md * Update config.md * Update train_group.md * Update models.md * Update model_group.md * Update model_group.md * Update train_group.md * Update train_group.md * Update model_group.md * Update model_group.md * Update README.md * Update README.md * Update models.md * Add files via upload * Add files via upload * Update models.md * Update models.md * Add files via upload * Update README.md * Update models.md * Update models.md * Update models.md * Update models.md * Update models.md * Update models.md * Update models.md * Update models.md * Update models.md * Add files via upload * Update models.md * Update models.md * Update loss_select.md * Update README.md * Update loss_select.md * Add files via upload * Update loss_select.md * Add files via upload * Update loss_select.md * Update README.md * Add files via upload * Update models.md * Add files via upload * Update models.md * Update models.md * Create 1 * Delete 1 * Create 1 * Add files via upload * Delete 1 * Add files via upload * Add files via upload * Update README.md * Add files via upload * Update finetune_deeplabv3plus.md * Update finetune_icnet.md * Update finetune_pspnet.md * Update finetune_hrnet.md * Update finetune_unet.md * Update config.md * Update config.md * Update usage.md * Update usage.md * Update usage.md * Update usage.md * Update usage.md * Update usage.md * Update usage.md * Update usage.md * Create download_optic.py * Add files via upload * Add files via upload * Update usage.md * Update README.md * Update usage.md * Update usage.md * Update usage.md * add optic.yaml * Add files via upload * Delete deeplabv3p_xception65_pet.yaml * Delete hrnet_w18_pet.yaml * Delete icnet_pet.yaml * Delete pspnet.yaml * Delete unet_pet.yaml * contrib * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md --- contrib/ACE2P/config.py | 8 +- contrib/ACE2P/download_ACE2P.py | 31 +++ contrib/ACE2P/imgs/117676_2149260.jpg | Bin 0 -> 22536 bytes contrib/ACE2P/imgs/117676_2149260.png | Bin 0 -> 2121 bytes contrib/ACE2P/infer.py | 130 ++++++++++++ contrib/ACE2P/reader.py | 2 +- contrib/{ => ACE2P}/utils/__init__.py | 0 contrib/{ => ACE2P}/utils/palette.py | 0 contrib/{ => ACE2P}/utils/util.py | 0 contrib/{ => HumanSeg}/imgs/Human.jpg | Bin contrib/{ => HumanSeg}/imgs/HumanSeg.jpg | Bin contrib/{ => HumanSeg}/infer.py | 2 +- contrib/HumanSeg/utils/__init__.py | 0 contrib/HumanSeg/utils/palette.py | 38 ++++ contrib/HumanSeg/utils/util.py | 47 +++++ ...download_mini_mechanical_industry_meter.py | 2 +- ...download_unet_mechanical_industry_meter.py | 30 +++ .../imgs/1560143028.5_IMG_3091.JPG | Bin .../imgs/1560143028.5_IMG_3091.png | Bin .../unet_mechanical_meter.yaml | 8 +- contrib/README.md | 198 +++++++++++++----- contrib/RoadLine/download_RoadLine.py | 31 +++ contrib/{ => RoadLine}/imgs/RoadLine.jpg | Bin contrib/{ => RoadLine}/imgs/RoadLine.png | Bin contrib/RoadLine/infer.py | 130 ++++++++++++ contrib/RoadLine/utils/__init__.py | 0 contrib/RoadLine/utils/palette.py | 38 ++++ contrib/RoadLine/utils/util.py | 47 +++++ 28 files changed, 684 insertions(+), 58 deletions(-) create mode 100644 contrib/ACE2P/download_ACE2P.py create mode 100644 contrib/ACE2P/imgs/117676_2149260.jpg create mode 100644 contrib/ACE2P/imgs/117676_2149260.png create mode 100644 contrib/ACE2P/infer.py rename contrib/{ => ACE2P}/utils/__init__.py (100%) rename contrib/{ => ACE2P}/utils/palette.py (100%) rename contrib/{ => ACE2P}/utils/util.py (100%) rename contrib/{ => HumanSeg}/imgs/Human.jpg (100%) rename contrib/{ => HumanSeg}/imgs/HumanSeg.jpg (100%) rename contrib/{ => HumanSeg}/infer.py (98%) create mode 100644 contrib/HumanSeg/utils/__init__.py create mode 100644 contrib/HumanSeg/utils/palette.py create mode 100644 contrib/HumanSeg/utils/util.py rename {dataset => contrib/MechanicalIndustryMeter}/download_mini_mechanical_industry_meter.py (95%) create mode 100644 contrib/MechanicalIndustryMeter/download_unet_mechanical_industry_meter.py rename contrib/{ => MechanicalIndustryMeter}/imgs/1560143028.5_IMG_3091.JPG (100%) rename contrib/{ => MechanicalIndustryMeter}/imgs/1560143028.5_IMG_3091.png (100%) rename {configs => contrib/MechanicalIndustryMeter}/unet_mechanical_meter.yaml (77%) create mode 100644 contrib/RoadLine/download_RoadLine.py rename contrib/{ => RoadLine}/imgs/RoadLine.jpg (100%) rename contrib/{ => RoadLine}/imgs/RoadLine.png (100%) create mode 100644 contrib/RoadLine/infer.py create mode 100644 contrib/RoadLine/utils/__init__.py create mode 100644 contrib/RoadLine/utils/palette.py create mode 100644 contrib/RoadLine/utils/util.py diff --git a/contrib/ACE2P/config.py b/contrib/ACE2P/config.py index f6ad5095..a1fad0ec 100644 --- a/contrib/ACE2P/config.py +++ b/contrib/ACE2P/config.py @@ -6,13 +6,13 @@ args = get_arguments() cfg = AttrDict() # 待预测图像所在路径 -cfg.data_dir = os.path.join(args.example , "data", "testing_images") +cfg.data_dir = os.path.join("data", "testing_images") # 待预测图像名称列表 -cfg.data_list_file = os.path.join(args.example , "data", "test_id.txt") +cfg.data_list_file = os.path.join("data", "test_id.txt") # 模型加载路径 -cfg.model_path = os.path.join(args.example , "ACE2P") +cfg.model_path = args.example # 预测结果保存路径 -cfg.vis_dir = os.path.join(args.example , "result") +cfg.vis_dir = "result" # 预测类别数 cfg.class_num = 20 diff --git a/contrib/ACE2P/download_ACE2P.py b/contrib/ACE2P/download_ACE2P.py new file mode 100644 index 00000000..bb4d3377 --- /dev/null +++ b/contrib/ACE2P/download_ACE2P.py @@ -0,0 +1,31 @@ +# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License" +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import os + +LOCAL_PATH = os.path.dirname(os.path.abspath(__file__)) +TEST_PATH = os.path.join(LOCAL_PATH, "..", "..", "test") +sys.path.append(TEST_PATH) + +from test_utils import download_file_and_uncompress + +if __name__ == "__main__": + download_file_and_uncompress( + url='https://paddleseg.bj.bcebos.com/models/ACE2P.tgz', + savepath=LOCAL_PATH, + extrapath=LOCAL_PATH, + extraname='ACE2P') + + print("Pretrained Model download success!") diff --git a/contrib/ACE2P/imgs/117676_2149260.jpg b/contrib/ACE2P/imgs/117676_2149260.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8314d8f8cc723b6f96785053bdcfe39d867755d5 GIT binary patch literal 22536 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%0A)yHR+%tr=lX6TP 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

m0oLi&k~?Cv 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 0) & 1) << (7 - i)) + palette[j * 3 + 1] |= (((lab >> 1) & 1) << (7 - i)) + palette[j * 3 + 2] |= (((lab >> 2) & 1) << (7 - i)) + i += 1 + lab >>= 3 + return palette diff --git a/contrib/HumanSeg/utils/util.py b/contrib/HumanSeg/utils/util.py new file mode 100644 index 00000000..7394870e --- /dev/null +++ b/contrib/HumanSeg/utils/util.py @@ -0,0 +1,47 @@ +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals +import argparse +import os + +def get_arguments(): + parser = argparse.ArgumentParser() + parser.add_argument("--use_gpu", + action="store_true", + help="Use gpu or cpu to test.") + parser.add_argument('--example', + type=str, + help='RoadLine, HumanSeg or ACE2P') + + return parser.parse_args() + + +class AttrDict(dict): + def __init__(self, *args, **kwargs): + super(AttrDict, self).__init__(*args, **kwargs) + + def __getattr__(self, name): + if name in self.__dict__: + return self.__dict__[name] + elif name in self: + return self[name] + else: + raise AttributeError(name) + + def __setattr__(self, name, value): + if name in self.__dict__: + self.__dict__[name] = value + else: + self[name] = value + +def merge_cfg_from_args(args, cfg): + """Merge config keys, values in args into the global config.""" + for k, v in vars(args).items(): + d = cfg + try: + value = eval(v) + except: + value = v + if value is not None: + cfg[k] = value + diff --git a/dataset/download_mini_mechanical_industry_meter.py b/contrib/MechanicalIndustryMeter/download_mini_mechanical_industry_meter.py similarity index 95% rename from dataset/download_mini_mechanical_industry_meter.py rename to contrib/MechanicalIndustryMeter/download_mini_mechanical_industry_meter.py index 3049df25..f0409581 100644 --- a/dataset/download_mini_mechanical_industry_meter.py +++ b/contrib/MechanicalIndustryMeter/download_mini_mechanical_industry_meter.py @@ -16,7 +16,7 @@ import sys import os LOCAL_PATH = os.path.dirname(os.path.abspath(__file__)) -TEST_PATH = os.path.join(LOCAL_PATH, "..", "test") +TEST_PATH = os.path.join(LOCAL_PATH, "..", "..", "test") sys.path.append(TEST_PATH) from test_utils import download_file_and_uncompress diff --git a/contrib/MechanicalIndustryMeter/download_unet_mechanical_industry_meter.py b/contrib/MechanicalIndustryMeter/download_unet_mechanical_industry_meter.py new file mode 100644 index 00000000..aa55bf5e --- /dev/null +++ b/contrib/MechanicalIndustryMeter/download_unet_mechanical_industry_meter.py @@ -0,0 +1,30 @@ +# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License" +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import os + +LOCAL_PATH = os.path.dirname(os.path.abspath(__file__)) +TEST_PATH = os.path.join(LOCAL_PATH, "..", "..", "test") +sys.path.append(TEST_PATH) + +from test_utils import download_file_and_uncompress + +if __name__ == "__main__": + download_file_and_uncompress( + url='https://paddleseg.bj.bcebos.com/models/unet_mechanical_industry_meter.tar', + savepath=LOCAL_PATH, + extrapath=LOCAL_PATH) + + print("Pretrained Model download success!") diff --git a/contrib/imgs/1560143028.5_IMG_3091.JPG b/contrib/MechanicalIndustryMeter/imgs/1560143028.5_IMG_3091.JPG similarity index 100% rename from contrib/imgs/1560143028.5_IMG_3091.JPG rename to contrib/MechanicalIndustryMeter/imgs/1560143028.5_IMG_3091.JPG diff --git a/contrib/imgs/1560143028.5_IMG_3091.png b/contrib/MechanicalIndustryMeter/imgs/1560143028.5_IMG_3091.png similarity index 100% rename from contrib/imgs/1560143028.5_IMG_3091.png rename to contrib/MechanicalIndustryMeter/imgs/1560143028.5_IMG_3091.png diff --git a/configs/unet_mechanical_meter.yaml b/contrib/MechanicalIndustryMeter/unet_mechanical_meter.yaml similarity index 77% rename from configs/unet_mechanical_meter.yaml rename to contrib/MechanicalIndustryMeter/unet_mechanical_meter.yaml index e1bc3a11..45ac8616 100644 --- a/configs/unet_mechanical_meter.yaml +++ b/contrib/MechanicalIndustryMeter/unet_mechanical_meter.yaml @@ -21,14 +21,14 @@ DATALOADER: BUF_SIZE: 256 NUM_WORKERS: 4 DATASET: - DATA_DIR: "./dataset/mini_mechanical_industry_meter_data/" + DATA_DIR: "./contrib/MechanicalIndustryMeter/mini_mechanical_industry_meter_data/" IMAGE_TYPE: "rgb" # choice rgb or rgba NUM_CLASSES: 5 - TEST_FILE_LIST: "./dataset/mini_mechanical_industry_meter_data/val_mini.txt" + TEST_FILE_LIST: "./contrib/MechanicalIndustryMeter/mini_mechanical_industry_meter_data/val_mini.txt" TEST_TOTAL_IMAGES: 8 - TRAIN_FILE_LIST: "./dataset/mini_mechanical_industry_meter_data/train_mini.txt" + TRAIN_FILE_LIST: "./contrib/MechanicalIndustryMeter/mini_mechanical_industry_meter_data/train_mini.txt" TRAIN_TOTAL_IMAGES: 64 - VAL_FILE_LIST: "./dataset/mini_mechanical_industry_meter_data/val_mini.txt" + VAL_FILE_LIST: "./contrib/MechanicalIndustryMeter/mini_mechanical_industry_meter_data/val_mini.txt" VAL_TOTAL_IMAGES: 8 SEPARATOR: "|" IGNORE_INDEX: 255 diff --git a/contrib/README.md b/contrib/README.md index c3914125..225ffb77 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -1,72 +1,139 @@ # PaddleSeg 特色垂类分割模型 -提供基于PaddlePaddle最新的分割特色模型 +提供基于PaddlePaddle最新的分割特色模型: -## Augmented Context Embedding with Edge Perceiving (ACE2P) +- [人像分割](#人像分割) +- [人体解析](#人体解析) +- [车道线分割](#车道线分割) +- [工业用表分割](#工业用表分割) +- [在线体验](#在线体验) +## 人像分割 -### 1. 模型概述 - -CVPR 19 Look into Person (LIP) 单人人像分割比赛冠军模型,详见[ACE2P](./ACE2P) +**Note:** 本章节所有命令均在`contrib/HumanSeg`目录下执行。 -### 2. 模型下载 +``` +cd contrib/HumanSeg +``` -点击[链接](https://paddleseg.bj.bcebos.com/models/ACE2P.tgz),下载, 在contrib/ACE2P下解压, `tar -xzf ACE2P.tgz` +### 1. 模型结构 -### 3. 数据下载 +DeepLabv3+ backbone为Xception65 -前往LIP数据集官网: http://47.100.21.47:9999/overview.php 或点击 [Baidu_Drive](https://pan.baidu.com/s/1nvqmZBN#list/path=%2Fsharelink2787269280-523292635003760%2FLIP%2FLIP&parentPath=%2Fsharelink2787269280-523292635003760), +### 2. 下载模型和数据 + +执行以下命令下载并解压模型和数据集: -加载Testing_images.zip, 解压到contrib/ACE2P/data文件夹下 +``` +python download_HumanSeg.py +``` +或点击[链接](https://paddleseg.bj.bcebos.com/models/HumanSeg.tgz)进行手动下载,并解压到contrib/HumanSeg文件夹下 -### 4. 运行 -**NOTE:** 运行该模型需要2G左右显存 +### 3. 运行 -使用GPU预测 +使用GPU预测: ``` -python -u infer.py --example ACE2P --use_gpu +python -u infer.py --example HumanSeg --use_gpu ``` + 使用CPU预测: ``` -python -u infer.py --example ACE2P +python -u infer.py --example HumanSeg ``` -## 人像分割 (HumanSeg) +预测结果存放在contrib/HumanSeg/HumanSeg/result目录下。 -### 1. 模型结构 +### 4. 预测结果示例: -DeepLabv3+ backbone为Xception65 + 原图: + + ![](HumanSeg/imgs/Human.jpg) + + 预测结果: + + ![](HumanSeg/imgs/HumanSeg.jpg) -### 2. 下载模型和数据 - -点击[链接](https://paddleseg.bj.bcebos.com/models/HumanSeg.tgz),下载解压到contrib文件夹下 -### 3. 运行 +## 人体解析 + +![](ACE2P/imgs/result.jpg) + +人体解析(Human Parsing)是细粒度的语义分割任务,旨在识别像素级别的人类图像的组成部分(例如,身体部位和服装)。本章节使用冠军模型Augmented Context Embedding with Edge Perceiving (ACE2P)进行预测分割。 + + +**Note:** 本章节所有命令均在`contrib/ACE2P`目录下执行。 -使用GPU预测: ``` -python -u infer.py --example HumanSeg --use_gpu +cd contrib/ACE2P ``` +### 1. 模型概述 + +Augmented Context Embedding with Edge Perceiving (ACE2P)通过融合底层特征、全局上下文信息和边缘细节,端到端训练学习人体解析任务。以ACE2P单人人体解析网络为基础的解决方案在CVPR2019第三届Look into Person (LIP)挑战赛中赢得了全部三个人体解析任务的第一名。详情请参见[ACE2P](./ACE2P) + +### 2. 模型下载 + +执行以下命令下载并解压ACE2P预测模型: -使用CPU预测: ``` -python -u infer.py --example HumanSeg +python download_ACE2P.py ``` +或点击[链接](https://paddleseg.bj.bcebos.com/models/ACE2P.tgz)进行手动下载, 并在contrib/ACE2P下解压。 -### 4. 预测结果示例: +### 3. 数据下载 + +测试图片共10000张, +点击 [Baidu_Drive](https://pan.baidu.com/s/1nvqmZBN#list/path=%2Fsharelink2787269280-523292635003760%2FLIP%2FLIP&parentPath=%2Fsharelink2787269280-523292635003760) +下载Testing_images.zip,或前往LIP数据集官网进行下载。 +下载后解压到contrib/ACE2P/data文件夹下 - 原图:![](imgs/Human.jpg) + +### 4. 运行 + + +使用GPU预测 +``` +python -u infer.py --example ACE2P --use_gpu +``` + +使用CPU预测: +``` +python -u infer.py --example ACE2P +``` + +**NOTE:** 运行该模型需要2G左右显存。由于数据图片较多,预测过程将比较耗时。 + +#### 5. 预测结果示例: + + 原图: + + ![](ACE2P/imgs/117676_2149260.jpg) + + 预测结果: + + ![](ACE2P/imgs/117676_2149260.png) - 预测结果:![](imgs/HumanSeg.jpg) +### 备注 -## 车道线分割 (RoadLine) +1. 数据及模型路径等详细配置见ACE2P/HumanSeg/RoadLine下的config.py文件 +2. ACE2P模型需预留2G显存,若显存超可调小FLAGS_fraction_of_gpu_memory_to_use + + + + +## 车道线分割 + +**Note:** 本章节所有命令均在`contrib/RoadLine`目录下执行。 + +``` +cd contrib/RoadLine +``` ### 1. 模型结构 @@ -75,7 +142,15 @@ Deeplabv3+ backbone为MobileNetv2 ### 2. 下载模型和数据 -点击[链接](https://paddleseg.bj.bcebos.com/inference_model/RoadLine.tgz),下载解压在contrib文件夹下 + +执行以下命令下载并解压模型和数据集: + +``` +python download_RoadLine.py +``` + +或点击[链接](https://paddleseg.bj.bcebos.com/inference_model/RoadLine.tgz)进行手动下载,并解压到contrib/RoadLine文件夹下 + ### 3. 运行 @@ -92,43 +167,75 @@ python -u infer.py --example RoadLine --use_gpu python -u infer.py --example RoadLine ``` +预测结果存放在contrib/RoadLine/RoadLine/result目录下。 #### 4. 预测结果示例: - 原图:![](imgs/RoadLine.jpg) + 原图: + + ![](RoadLine/imgs/RoadLine.jpg) - 预测结果:![](imgs/RoadLine.png) + 预测结果: + + ![](RoadLine/imgs/RoadLine.png) + + ## 工业用表分割 + +**Note:** 本章节所有命令均在`PaddleSeg`目录下执行。 + ### 1. 模型结构 unet ### 2. 数据准备 -cd到PaddleSeg/dataset文件夹下,执行download_mini_mechanical_industry_meter.py +执行以下命令下载并解压数据集,数据集将存放在contrib/MechanicalIndustryMeter文件夹下: + +``` +python ./contrib/MechanicalIndustryMeter/download_mini_mechanical_industry_meter.py +``` -### 3. 训练与评估 +### 3. 下载预训练模型 ``` -CUDA_VISIBLE_DEVICES=0 python ./pdseg/train.py --log_steps 10 --cfg configs/unet_mechanical_meter.yaml --use_gpu --do_eval --use_mpio +python ./pretrained_model/download_model.py unet_bn_coco ``` -### 4. 可视化 -我们提供了一个训练好的模型,点击[链接](https://paddleseg.bj.bcebos.com/models/unet_mechanical_industry_meter.tar),下载后放在PaddleSeg/pretrained_model下 +### 4. 训练与评估 + ``` -CUDA_VISIBLE_DEVICES=0 python ./pdseg/vis.py --cfg configs/unet_mechanical_meter.yaml --use_gpu --vis_dir vis_meter \ -TEST.TEST_MODEL "./pretrained_model/unet_gongyeyongbiao/" +export CUDA_VISIBLE_DEVICES=0 +python ./pdseg/train.py --log_steps 10 --cfg contrib/MechanicalIndustryMeter/unet_mechanical_meter.yaml --use_gpu --do_eval --use_mpio ``` -可视化结果会保存在vis_meter文件夹下 -### 5. 可视化结果示例: +### 5. 可视化 +我们已提供了一个训练好的模型,执行以下命令进行下载,下载后将存放在./contrib/MechanicalIndustryMeter/文件夹下。 - 原图:![](imgs/1560143028.5_IMG_3091.JPG) +``` +python ./contrib/MechanicalIndustryMeter/download_unet_mechanical_industry_meter.py +``` + +使用该模型进行预测可视化: + +``` +python ./pdseg/vis.py --cfg contrib/MechanicalIndustryMeter/unet_mechanical_meter.yaml --use_gpu --vis_dir vis_meter \ +TEST.TEST_MODEL "./contrib/MechanicalIndustryMeter/unet_mechanical_industry_meter/" +``` +可视化结果会保存在./vis_meter文件夹下。 + +### 6. 可视化结果示例: + + 原图: + + ![](MechanicalIndustryMeter/imgs/1560143028.5_IMG_3091.JPG) - 预测结果:![](imgs/1560143028.5_IMG_3091.png) + 预测结果: + + ![](MechanicalIndustryMeter/imgs/1560143028.5_IMG_3091.png) ## 在线体验 @@ -140,7 +247,4 @@ PaddleSeg在AI Studio平台上提供了在线体验的教程,欢迎体验: |人像分割|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/188833)| |特色垂类模型|[点击体验](https://aistudio.baidu.com/aistudio/projectdetail/115541)| -## 备注 -1. 数据及模型路径等详细配置见ACE2P/HumanSeg/RoadLine下的config.py文件 -2. ACE2P模型需预留2G显存,若显存超可调小FLAGS_fraction_of_gpu_memory_to_use diff --git a/contrib/RoadLine/download_RoadLine.py b/contrib/RoadLine/download_RoadLine.py new file mode 100644 index 00000000..86b63178 --- /dev/null +++ b/contrib/RoadLine/download_RoadLine.py @@ -0,0 +1,31 @@ +# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License" +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import os + +LOCAL_PATH = os.path.dirname(os.path.abspath(__file__)) +TEST_PATH = os.path.join(LOCAL_PATH, "..", "..", "test") +sys.path.append(TEST_PATH) + +from test_utils import download_file_and_uncompress + +if __name__ == "__main__": + download_file_and_uncompress( + url='https://paddleseg.bj.bcebos.com/inference_model/RoadLine.tgz', + savepath=LOCAL_PATH, + extrapath=LOCAL_PATH, + extraname='RoadLine') + + print("Pretrained Model download success!") diff --git a/contrib/imgs/RoadLine.jpg b/contrib/RoadLine/imgs/RoadLine.jpg similarity index 100% rename from contrib/imgs/RoadLine.jpg rename to contrib/RoadLine/imgs/RoadLine.jpg diff --git a/contrib/imgs/RoadLine.png b/contrib/RoadLine/imgs/RoadLine.png similarity index 100% rename from contrib/imgs/RoadLine.png rename to contrib/RoadLine/imgs/RoadLine.png diff --git a/contrib/RoadLine/infer.py b/contrib/RoadLine/infer.py new file mode 100644 index 00000000..97147693 --- /dev/null +++ b/contrib/RoadLine/infer.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +import os +import cv2 +import numpy as np +from utils.util import get_arguments +from utils.palette import get_palette +from PIL import Image as PILImage +import importlib + +args = get_arguments() +config = importlib.import_module('config') +cfg = getattr(config, 'cfg') + +# paddle垃圾回收策略FLAG,ACE2P模型较大,当显存不够时建议开启 +os.environ['FLAGS_eager_delete_tensor_gb']='0.0' + +import paddle.fluid as fluid + +# 预测数据集类 +class TestDataSet(): + def __init__(self): + self.data_dir = cfg.data_dir + self.data_list_file = cfg.data_list_file + self.data_list = self.get_data_list() + self.data_num = len(self.data_list) + + def get_data_list(self): + # 获取预测图像路径列表 + data_list = [] + data_file_handler = open(self.data_list_file, 'r') + for line in data_file_handler: + img_name = line.strip() + name_prefix = img_name.split('.')[0] + if len(img_name.split('.')) == 1: + img_name = img_name + '.jpg' + img_path = os.path.join(self.data_dir, img_name) + data_list.append(img_path) + return data_list + + def preprocess(self, img): + # 图像预处理 + if cfg.example == 'ACE2P': + reader = importlib.import_module(args.example+'.reader') + ACE2P_preprocess = getattr(reader, 'preprocess') + img = ACE2P_preprocess(img) + else: + img = cv2.resize(img, cfg.input_size).astype(np.float32) + img -= np.array(cfg.MEAN) + img /= np.array(cfg.STD) + img = img.transpose((2, 0, 1)) + img = np.expand_dims(img, axis=0) + return img + + def get_data(self, index): + # 获取图像信息 + img_path = self.data_list[index] + img = cv2.imread(img_path, cv2.IMREAD_COLOR) + if img is None: + return img, img,img_path, None + + img_name = img_path.split(os.sep)[-1] + name_prefix = img_name.replace('.'+img_name.split('.')[-1],'') + img_shape = img.shape[:2] + img_process = self.preprocess(img) + + return img, img_process, name_prefix, img_shape + + +def infer(): + if not os.path.exists(cfg.vis_dir): + os.makedirs(cfg.vis_dir) + palette = get_palette(cfg.class_num) + # 人像分割结果显示阈值 + thresh = 120 + + place = fluid.CUDAPlace(0) if cfg.use_gpu else fluid.CPUPlace() + exe = fluid.Executor(place) + + # 加载预测模型 + test_prog, feed_name, fetch_list = fluid.io.load_inference_model( + dirname=cfg.model_path, executor=exe, params_filename='__params__') + + #加载预测数据集 + test_dataset = TestDataSet() + data_num = test_dataset.data_num + + for idx in range(data_num): + # 数据获取 + ori_img, image, im_name, im_shape = test_dataset.get_data(idx) + if image is None: + print(im_name, 'is None') + continue + + # 预测 + if cfg.example == 'ACE2P': + # ACE2P模型使用多尺度预测 + reader = importlib.import_module(args.example+'.reader') + multi_scale_test = getattr(reader, 'multi_scale_test') + parsing, logits = multi_scale_test(exe, test_prog, feed_name, fetch_list, image, im_shape) + else: + # HumanSeg,RoadLine模型单尺度预测 + result = exe.run(program=test_prog, feed={feed_name[0]: image}, fetch_list=fetch_list) + parsing = np.argmax(result[0][0], axis=0) + parsing = cv2.resize(parsing.astype(np.uint8), im_shape[::-1]) + + # 预测结果保存 + result_path = os.path.join(cfg.vis_dir, im_name + '.png') + if cfg.example == 'HumanSeg': + logits = result[0][0][1]*255 + logits = cv2.resize(logits, im_shape[::-1]) + ret, logits = cv2.threshold(logits, thresh, 0, cv2.THRESH_TOZERO) + logits = 255 *(logits - thresh)/(255 - thresh) + # 将分割结果添加到alpha通道 + rgba = np.concatenate((ori_img, np.expand_dims(logits, axis=2)), axis=2) + cv2.imwrite(result_path, rgba) + else: + output_im = PILImage.fromarray(np.asarray(parsing, dtype=np.uint8)) + output_im.putpalette(palette) + output_im.save(result_path) + + if (idx + 1) % 100 == 0: + print('%d processd' % (idx + 1)) + + print('%d processd done' % (idx + 1)) + + return 0 + + +if __name__ == "__main__": + infer() diff --git a/contrib/RoadLine/utils/__init__.py b/contrib/RoadLine/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/contrib/RoadLine/utils/palette.py b/contrib/RoadLine/utils/palette.py new file mode 100644 index 00000000..2186203c --- /dev/null +++ b/contrib/RoadLine/utils/palette.py @@ -0,0 +1,38 @@ +##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +## Created by: RainbowSecret +## Microsoft Research +## yuyua@microsoft.com +## Copyright (c) 2018 +## +## This source code is licensed under the MIT-style license found in the +## LICENSE file in the root directory of this source tree +##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +import numpy as np +import cv2 + + +def get_palette(num_cls): + """ Returns the color map for visualizing the segmentation mask. + Args: + num_cls: Number of classes + Returns: + The color map + """ + n = num_cls + palette = [0] * (n * 3) + for j in range(0, n): + lab = j + palette[j * 3 + 0] = 0 + palette[j * 3 + 1] = 0 + palette[j * 3 + 2] = 0 + i = 0 + while lab: + palette[j * 3 + 0] |= (((lab >> 0) & 1) << (7 - i)) + palette[j * 3 + 1] |= (((lab >> 1) & 1) << (7 - i)) + palette[j * 3 + 2] |= (((lab >> 2) & 1) << (7 - i)) + i += 1 + lab >>= 3 + return palette diff --git a/contrib/RoadLine/utils/util.py b/contrib/RoadLine/utils/util.py new file mode 100644 index 00000000..7394870e --- /dev/null +++ b/contrib/RoadLine/utils/util.py @@ -0,0 +1,47 @@ +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals +import argparse +import os + +def get_arguments(): + parser = argparse.ArgumentParser() + parser.add_argument("--use_gpu", + action="store_true", + help="Use gpu or cpu to test.") + parser.add_argument('--example', + type=str, + help='RoadLine, HumanSeg or ACE2P') + + return parser.parse_args() + + +class AttrDict(dict): + def __init__(self, *args, **kwargs): + super(AttrDict, self).__init__(*args, **kwargs) + + def __getattr__(self, name): + if name in self.__dict__: + return self.__dict__[name] + elif name in self: + return self[name] + else: + raise AttributeError(name) + + def __setattr__(self, name, value): + if name in self.__dict__: + self.__dict__[name] = value + else: + self[name] = value + +def merge_cfg_from_args(args, cfg): + """Merge config keys, values in args into the global config.""" + for k, v in vars(args).items(): + d = cfg + try: + value = eval(v) + except: + value = v + if value is not None: + cfg[k] = value + -- GitLab