PaddleX: 道路裂缝检测
道路裂缝数据,使用EasyDL智能标注数据,并直接使用PaddleX进行训练预测
·
PaddleX:道路裂缝检测
- 使用EasyDL标注部分道路裂缝数据,转换为PaddleX使用的VOC格式
- 使用PPYOLOV2模型进行训练
一、数据处理
1. PaddleX安装及数据集解压
! pip install -q paddlex
! mkdir -p data/dataset
# ! unzip -oq data/data109050/India.zip -d data/dataset # 公开数据集
! unzip -oq data/data113986/RC2V1.zip -d data/dataset # 从EasyDL标注的数据
2. EasyDL json转VOC xml
from convert import Batch2Xmls
easydl_folder = "data/dataset/DatasetId_251670_1635398672"
save_path = "data/dataset/pdx_data"
Batch2Xmls(easydl_folder, save_path)
100%|██████████| 812/812 [00:01<00:00, 559.98it/s]
3. 转为PaddleX数据组织格式
- 划分数据集
- 生成标签列表
import os
import os.path as osp
import random
from tqdm import tqdm
import xml.dom.minidom
def read_xml(xml_path, names):
try:
dom = xml.dom.minidom.parse(xml_path) # 打开XML文件
collection = dom.documentElement # 获取元素对象
object_list = collection.getElementsByTagName("object") # 获取标签名信息
for obj in object_list:
name = obj.getElementsByTagName('name')[0].childNodes[0].data
if name not in names:
names.append(name)
except:
return
img_folder_path = "data/dataset/pdx_data/images"
img_names = os.listdir(img_folder_path)
random.seed(2)
random.shuffle(img_names)
labels = []
with open("data/dataset/pdx_data/train_list.txt", "w") as tf:
with open("data/dataset/pdx_data/eval_list.txt", "w") as ef:
for idx, ima_name in tqdm(enumerate(img_names)):
img_path = osp.join(img_folder_path, ima_name)
xml_path = img_path.replace("images", "annotations").replace(".jpg", ".xml") # annotations/xmls
if osp.exists(img_path) and osp.exists(xml_path):
read_xml(xml_path, labels)
img_path = img_path.replace("data/dataset/pdx_data/", "")
xml_path = xml_path.replace("data/dataset/pdx_data/", "")
if idx % 10 == 0:
ef.write(img_path + " " + xml_path + "\n")
else:
tf.write(img_path + " " + xml_path + "\n")
with open("data/dataset/pdx_data/labels.txt", "w") as lf:
for lab in labels:
lf.write(lab + "\n")
422it [00:00, 3470.44it/s]
4. 统计mean和std
- 公开数据集太大了,抽样统计的
# import os
# import cv2
# import numpy as np
# import random
# from tqdm import tqdm
# means, stdevs = [], []
# img_list = []
# imgs_path = 'data/dataset/pdx_data/images'
# imgs_name = os.listdir(imgs_path)
# random.shuffle(imgs_name)
# for idx, name in tqdm(enumerate(imgs_name)):
# img = cv2.cvtColor(cv2.imread(os.path.join(imgs_path, name)), cv2.COLOR_BGR2RGB)
# img = img[:, :, :, np.newaxis]
# # if idx % 10 == 0: # 内存不够,抽样
# # img_list.append(img)
# img_list.append(img)
# imgs = np.concatenate(img_list, axis=-1)
# imgs = imgs.astype(np.float32) / 255.
# for i in tqdm(range(3)):
# pixels = imgs[:, :, i, :].ravel() # 拉成一行
# means.append(np.mean(pixels))
# stdevs.append(np.std(pixels))
# print(means, stdevs)
422it [00:18, 23.32it/s]
100%|██████████| 3/3 [00:27<00:00, 9.05s/it]
[0.40158695, 0.43556893, 0.507324] [0.19307534, 0.19843009, 0.2915112]
归一化
India
mean: [0.51279986, 0.52223563, 0.52388006]
std: [0.26084045, 0.26875973, 0.29285163]
RC2_V1
mean: [0.40158695, 0.43556893, 0.507324]
std: [0.19307534, 0.19843009, 0.2915112]
5. 锚框聚类
# from anchor import load_one_info, get_kmeans
# result = []
# xml_folder = "data/dataset/pdx_data/annotations"
# for name in os.listdir(xml_folder):
# result.extend(load_one_info(name, xml_folder))
# result = np.array(result)
# anchors, ave_iou = get_kmeans(result, 9)
# anchor_string = ''
# anchor_sizes = []
# for anchor in anchors:
# anchor_string += '{},{}, '.format(anchor[0], anchor[1])
# anchor_sizes.append([anchor[0], anchor[1]])
# anchor_string = anchor_string[:-2]
# print('anchors are:')
# print(anchor_string)
# print('the average iou is:')
# print(ave_iou)
anchors are:
81,20, 243,20, 138,37, 404,27, 565,20, 259,77, 670,30, 1141,31, 444,177
the average iou is:
0.7248688626535296
锚框
RC2_V1
anchors are:81,20, 243,20, 138,37, 404,27, 565,20, 259,77, 670,30, 1141,31, 444,177
the average iou is:0.7248688626535296
6. 准备数据
import paddlex as pdx
from paddlex import transforms as T
train_transforms = T.Compose([
T.MixupImage(mixup_epoch=-1),
T.RandomDistort(),
T.RandomExpand(),
T.RandomCrop(),
T.RandomHorizontalFlip(),
T.Resize(target_size=(1088, 1920), interp='RANDOM'),
# T.BatchRandomResize(
# target_sizes=[416, 448, 480, 512, 544, 576, 608, 640, 672, 704, 736],
# interp='RANDOM'),
T.Normalize(mean=[0.40158695, 0.43556893, 0.507324], std=[0.19307534, 0.19843009, 0.2915112])])
eval_transforms = T.Compose([
T.Resize(target_size=(1088, 1920), interp='CUBIC'),
T.Normalize(mean=[0.40158695, 0.43556893, 0.507324], std=[0.19307534, 0.19843009, 0.2915112])])
train_dataset = pdx.datasets.VOCDetection(
data_dir='data/dataset/pdx_data',
file_list='data/dataset/pdx_data/train_list.txt',
label_list='data/dataset/pdx_data/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.VOCDetection(
data_dir='data/dataset/pdx_data',
file_list='data/dataset/pdx_data/eval_list.txt',
label_list='data/dataset/pdx_data/labels.txt',
transforms=eval_transforms)
2021-10-29 17:34:42 [INFO] Starting to read file list from dataset...
2021-10-29 17:34:42 [INFO] 352 samples in file data/dataset/pdx_data/train_list.txt, including 352 positive samples and 0 negative samples.
creating index...
index created!
2021-10-29 17:34:42 [INFO] Starting to read file list from dataset...
2021-10-29 17:34:42 [INFO] 38 samples in file data/dataset/pdx_data/eval_list.txt, including 38 positive samples and 0 negative samples.
creating index...
index created!
二、训练
- 先使用过公开数据集训练,然后将模型作为预训练模型
num_classes = len(train_dataset.labels)
model = pdx.det.PPYOLOv2(num_classes=num_classes, anchors=
[[82, 20], [244, 20], [138, 38], [404, 28], [566, 20], [260, 78], [670, 30], [1142, 32], [444, 178]])
model.train(
num_epochs=200,
train_dataset=train_dataset,
train_batch_size=2,
eval_dataset=eval_dataset,
pretrain_weights='output_rc2_v1/best_model_v1/model.pdparams',
learning_rate=3e-6,
warmup_steps=20,
warmup_start_lr=1e-8,
lr_decay_epochs=[30, 112],
lr_decay_gamma=.5,
save_interval_epochs=40,
save_dir='output_rc2_v1',
use_vdl=True)
三、预测
import paddlex as pdx
from paddlex import transforms as T
import matplotlib.pyplot as plt
%matplotlib inline
eval_transforms = T.Compose([
T.Resize(target_size=(1088, 1920), interp='CUBIC'),
T.Normalize(mean=[0.40158695, 0.43556893, 0.507324], std=[0.19307534, 0.19843009, 0.2915112])])
model = pdx.load_model('output_rc2_v1/best_model')
image_name = 'data/dataset/pdx_data/images/D_0002388.jpg'
result = model.predict(image_name)
pred = pdx.det.visualize(image_name, result, threshold=0.5, save_dir=None)
pred = pred[:, :, ::-1] # 2RGB
plt.figure(figsize=(10, 10))
dict(image_name)
pred = pdx.det.visualize(image_name, result, threshold=0.5, save_dir=None)
pred = pred[:, :, ::-1] # 2RGB
plt.figure(figsize=(10, 10))
plt.imshow(pred)
2021-10-30 00:09:25 [INFO] Model[PPYOLOv2] loaded.
<matplotlib.image.AxesImage at 0x7f24f87cf1d0>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jtJbd1yE-1637193156413)(output_20_2.png)]
四、导出inference预测*
! paddlex --export_inference --model_dir=output_rc2_v1/best_model/ --save_dir=infer_rc2_v1 --fixed_input_shape=[1,3,1088,1920]
更多推荐
所有评论(0)