在一篇文中,讲到对水表盘的读数进行语义分割后的数据处理和文字识别。可以参看:73.Python——语义分割后期处理:水表读数。本文主要是对水表盘的读数进行语义分割。
数据集:150张水表图片:
一、标签标注
使用labelme工具,标注过程是枯燥、机械、无聊的,把水表盘数字的区域框选出来。
标注过程
二、数据格式转换和划分数据集LabelMe标注后的数据还需要进行转换为SEG格式,才可以用于语义分割任务的训练。
paddlex --data_conversion --source labelme --to SEG --pics jpegimages --annotations annotations --save_dir meter-water-seg
生成一个label.txt文件,内容
_background_
number
生成的annotations标注文件
划分数据集:
>paddlex --split_dataset --format SEG --dataset_dir meter-water-seg --val_value 0.2 --test_value 0.1
这先使用的是fastscnn网络模型。训练代码:
import paddlex as pdx
from paddlex import transforms as T
#数据集格式转换
#数据集划分
#paddlex --data_conversion --source labelme --to SEG --pics holder\JPEGImages --annotations holder\Annotations --save_dir holder-seg
#paddlex --split_dataset --format SEG --dataset_dir holder-seg --val_value 0.2 --test_value 0.1
# 输出推理模型
# paddlex -export_inference --model_dir best_model --save_dir inference
# 定义训练和验证时的transforms
train_transforms = T.Compose([
T.Resize(target_size=512),
T.RandomHorizontalFlip(),
T.Normalize(
mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
])
eval_transforms = T.Compose([
T.Resize(target_size=512),
T.Normalize(
mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
])
# 定义训练和验证所用的数据集
train_dataset = pdx.datasets.SegDataset(
data_dir='meter-water-seg',
file_list='meter-water-seg/train_list.txt',
label_list='meter-water-seg/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.SegDataset(
data_dir='meter-water-seg',
file_list='meter-water-seg/val_list.txt',
label_list='meter-water-seg/labels.txt',
transforms=eval_transforms,
shuffle=False)
# 初始化模型,并进行训练
num_classes = len(train_dataset.labels)
model = pdx.seg.FastSCNN(num_classes=num_classes)
model.train(
num_epochs=10,
train_dataset=train_dataset,
train_batch_size=4,
eval_dataset=eval_dataset,
learning_rate=0.05,
save_dir='output/fastscnn-water-meter-seg')
#训练最后一轮评估
[INFO] Start to evaluate(total_samples=30, total_steps=30)...
[INFO] [EVAL] Finished, Epoch=10, miou=0.926228, category_iou=[0.9961706 0.8562857]
, oacc=0.996256, category_acc=[0.99774253 0.93541026], kappa=0.920662, category_F1-score=[0.99808163 0.92257
966] .
输出部署模型
paddlex --export_inference --model_dir best_model --save_dir infer
四、语义分割模型预测
import paddlex as pdx
import cv2
import os
import numpy as np
#os.environ["CUDA_VISBLE_DEVICES"]="0,1"
predictor=pdx.deploy.Predictor("output/fastscnn-water-meter-seg/inference_model",use_gpu=True)
image_name="meter-water-seg/JPEGImages/train_136.jpg"
img=cv2.imread(image_name)
result=predictor.predict(img)
lblmap=result["label_map"]
#返回label_map的轮廓多边形顶点坐标
def get_contours(lblmap):
lblmap=lblmap.astype(np.uint8)
contours,hir=cv2.findContours(lblmap,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
epoll=0.01*cv2.arcLength(contours[0], True)
ap=cv2.approxPolyDP(contours[0], epoll, True)
return ap
#画多边形
cv2.polylines(img,[get_contours(lblmap)],True,(0,0,255),4)
cv2.imshow("result",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
预测结果1
预测结果2
,