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上