使用飞桨PaddleSeg实现语义分割识别天空(一)

PaddleSeg地址:https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.2/README_CN.md

制作数据集

这一步先略过,一般可以用labelme完成,这个在paddle的readme中有介绍
我使用的是另一个语义分割开源项目中的数据集 (701张图片)

数据预处理

根据paddleSeg的要求,将图片进行以下处理

文件夹结构

将701张图片和701张label图片放在两个文件夹中,训练集验证集测试集的划分通过 train.txt val.txt test.txt实现,最终文件结构如下:
在data/NewCamVid下:
├── images
│ ├── Seq05VD_f05040.png
│ ├── Seq05VD_f05070.png
│ ├──Seq05VD_f05100.png
│ ├── …
├── labels
│ ├── Seq05VD_f05040_L.png
│ ├── Seq05VD_f05070_L.png
│ ├──Seq05VD_f05100_L.png
│ ├── …
├── labels.txt
├── test.txt
├── train.txt
└── val.txt
test.txt, train.txt,val.txt三个文件的内容参照官网要求
在这里插入图片描述

原图以及标注图处理

首先修改原图的图片格式为jpg
(这一点不确定是不是必要,为了避免出错,我根据官网的示例,将原图从png转换成jpg)

接下来,修改标注图的像素值和通道数
官方描述

修改像素值

根据要求只需要识别出天空,因此将原数据的天空部分修改为(1,1,1)其余部分修改成(0,0,0)
代码如下

# @*@ #huaiZ
import cv2 as cv
import os
from loguru import logger
import argparse
import math
import multiprocessing


def change_label(save_folder, img_list):
    for img_path in img_list:
        filename = os.path.basename(img_path)
        logger.debug(f"deal with images: {img_path}")

        img = cv.imread(img_path)
        height, width, ch = img.shape

        for x in range(height):
            for y in range(width):
                if all(img[x, y] == [128, 128, 128]):
                    img[x, y] = [1, 1, 1]
                else:
                    img[x, y] = [0,0,0]
        assert cv.imwrite(os.path.join(save_folder, filename), img), "failed with save new images"
        logger.debug(f"new image's position: {os.path.join(save_folder, filename)}")


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", default=False, help="要改变的图片文件夹路径")
    parser.add_argument("--output", default=False, help="存放新的图片文件夹路径")

    args = parser.parse_args()
    folder_path = args.input
    save_folder = args.output

    img_list = []

    for file in os.listdir(folder_path):
        img_path = os.path.join(folder_path, file)
        img_list.append(img_path)

    pList = []

    thead_num = 5
    length = len(img_list)
    for i in range(thead_num):
        item_list = img_list[math.floor(i / thead_num * length):math.floor((i + 1) / thead_num * length)]

        p = multiprocessing.Process(target=change_label, args=(save_folder, item_list,))

        pList.append(p)
        p.start()

    for p in pList:
        p.join()

再将标签数据集转换成单通道即灰度图

import cv2
import os

folder = r"原图文件夹的路径"
save_folder = '保存灰度图的路径'
for file in os.listdir(folder):
    img = cv2.imread(os.path.join(folder, file), cv2.IMREAD_UNCHANGED)

    # 查看原始图像
    shape = img.shape
    print(f"before shape:{shape}")
    img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    cv2.imwrite(os.path.join(save_folder, file),img_gray)
    print(f"after shape:{img_gray.shape}") 

这样数据集基本准备完毕了

配置文件修改

将configs/quick_start/bisenet_optic_disc_512x512_1k.yml复制一份,并重命名
将其中有关配置修改,对应自己的数据集:

batch_size: 4
iters: 1000

train_dataset:
  type: Dataset
  dataset_root: data/NewCamVid
  train_path: data/NewCamVid/train.txt
  num_classes: 2
  transforms:
    - type: Resize
      target_size: [512, 512]
    - type: RandomHorizontalFlip
    - type: Normalize
  mode: train

val_dataset:
  type: Dataset
  dataset_root: data/NewCamVid
  val_path: data/NewCamVid/val.txt
  num_classes: 2
  transforms:
    - type: Resize
      target_size: [512, 512]
    - type: Normalize
  mode: val

optimizer:
  type: sgd
  momentum: 0.9
  weight_decay: 4.0e-5

lr_scheduler:
  type: PolynomialDecay
  learning_rate: 0.01
  end_lr: 0
  power: 0.9

loss:
  types:
    - type: CrossEntropyLoss
  coef: [1, 1, 1, 1, 1]

model:
  type: BiSeNetV2
  pretrained: Null

接下来就可以开始训练了,这部分内容和官网的基本一致,我贴一下训练验证的指令吧

训练验证以及推理

export CUDA_VISIBLE_DEVICES=0 # 设置1张可用的卡

训练指令

python train.py --config configs/quick_start/bisenet_new_camvid_512x512_1k.yml \
--do_eval \
--use_vdl \
--save_interval 500 \
--save_dir my_output

等待训练完成后

验证指令

python val.py \
       --config configs/quick_start/bisenet_new_camvid_512x512_1k.yml \
       --model_path my_output/best_model/model.pdparams

部分结果如下

26/26 [==============================] - 1s 41ms/step - batch_cost: 0.0411 - reader cost: 0.0037
2021-07-30 16:50:53 [INFO]	[EVAL] #Images: 26 mIoU: 0.9275 Acc: 0.9813 Kappa: 0.9233 
2021-07-30 16:50:53 [INFO]	[EVAL] Class IoU: 
[0.9784 0.8766]
2021-07-30 16:50:53 [INFO]	[EVAL] Class Acc: 
[0.9893 0.9329]

预测指令

python predict.py \
       --config configs/quick_start/bisenet_new_camvid_512x512_1k.yml \
       --model_path my_output/best_model/model.pdparams \
       --image_path data/NewCamVid/images/0016E5_06960.jpg \
       --save_dir my_output/result

输出的结果如下:

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

导出模型什么的官方都有介绍,我就不赘述了

结束

接下来研究怎么将模型转化成tflite部署到android上

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值