1 项目说明
在该项目中,主要向大家介绍如何使用目标检测和语义分割来实现对指针型表计读数。

在电力能源厂区需要定期监测表计读数,以保证设备正常运行及厂区安全。但厂区分布分散,人工巡检耗时长,无法实时监测表计,且部分工作环境危险导致人工巡检无法触达。针对上述问题,希望通过摄像头拍照->智能读数的方式高效地完成此任务。

在这里插入图片描述
为实现智能读数,我们采取目标检测->语义分割->读数后处理的方案:

第一步,使用目标检测模型定位出图像中的表计;
第二步,使用语义分割模型将各表计的指针和刻度分割出来;
第三步,根据指针的相对位置和预知的量程计算出各表计的读数。
整个方案的流程如下所示:在这里插入图片描述
在这里插入图片描述
2 数据准备
本案例开放了表计检测数据集、指针和刻度分割数据集、表计测试图片(只有图片无真值标注),使用这些图片可以完成目标检测模型、语义分割模型的训练、模型预测。点击下表中的链接可下载数据集,提前下载数据集不是必须的,因为在接下来的模型训练部分中提供的训练脚本会自动下载数据集。

表计测试图片 表计检测数据集 指针和刻度分割数据集
meter_test meter_det meter_seg
解压后的表计检测数据集的文件夹内容如下:
训练集有725张图片,测试集有58张图片。

meter_det/
|-- annotations/ # 标注文件所在文件夹
| |-- instance_train.json # 训练集标注文件
| |-- instance_test.json # 测试集标注文件
|-- test/ # 测试图片所在文件夹
| |-- 20190822_105.jpg # 测试集图片
| |-- … …
|-- train/ # 训练图片所在文件夹
| |-- 20190822_101.jpg # 训练集图片
| |-- … …

解压后的指针和刻度分割数据集的文件夹内容如下:
训练集有374张图片,测试集有40张图片。

meter_seg/
|-- annotations/ # 标注文件所在文件夹
| |-- train # 训练集标注图片所在文件夹
| | |-- 105.png
| | |-- … …
| |-- val # 验证集合标注图片所在文件夹
| | |-- 110.png
| | |-- … …
|-- images/ # 图片所在文件夹
| |-- train # 训练集图片
| | |-- 105.jpg
| | |-- … …
| |-- val # 验证集图片
| | |-- 110.jpg
| | |-- … …
|-- labels.txt # 类别名列表
|-- train.txt # 训练集图片列表
|-- val.txt # 验证集图片列表

解压后的表计测试图片的文件夹内容如下:
一共有58张测试图片。

meter_test/
|-- 20190822_105.jpg
|-- 20190822_142.jpg
|-- … …
通过以下命令可以直接下载并解压该数据集:

In [ ]
!wget https://bj.bcebos.com/paddlex/examples/meter_reader/datasets/meter_det.tar.gz
!tar -xvf meter_det.tar.gz -C data/
!wget https://bj.bcebos.com/paddlex/examples/meter_reader/datasets/meter_seg.tar.gz
!tar -xvf meter_seg.tar.gz -C data/
meter_det/train/20190829154906858.jpg
meter_det/train/20190830142904939.jpg
meter_det/train/20190827135806823.jpg
meter_det/train/20190822_65.jpg
meter_det/train/20190822_80.jpg
meter_det/train/20190830095045363.jpg
meter_det/train/20190829153705962.jpg
meter_det/train/20190829150651706.jpg
meter_det/train/20190822_58.jpg
meter_det/train/20190829153412013.jpg
meter_det/train/20190827161322264.jpg
meter_det/train/20190822_21.jpg
meter_det/train/20190822_172.jpg
meter_det/train/20190830095246486.jpg
meter_det/train/20190829151116592.jpg
meter_det/train/20190827141658105.jpg
meter_det/train/20190827110625467.jpg
meter_det/train/20190829153230852.jpg
meter_det/train/20190830104754491.jpg
meter_det/train/20190829151453765.jpg
meter_det/train/20190830111624515.jpg
meter_det/train/20190830104701877.jpg
meter_det/train/20190827113019913.jpg
meter_det/train/20190830143720468.jpg
meter_det/train/20190822_139.jpg
meter_det/train/20190830111523593.jpg
meter_det/train/20190829143047731.jpg
meter_det/train/20190829093938822.jpg
meter_det/train/20190822_38.jpg
meter_det/train/20190830093533017.jpg
meter_det/train/20190830150019688.jpg
meter_det/train/20190830104545310.jpg
meter_det/train/20190822_19.jpg
meter_det/train/20190822_8.jpg
meter_det/train/20190822_87.jpg
meter_det/train/20190827104830812.jpg
meter_det/train/20190822_72.jpg
meter_det/train/20190822_159.jpg
meter_det/train/20190827104345912.jpg
meter_det/train/20190827162806022.jpg
meter_det/train/20190822_76.jpg
meter_det/train/20190830094900425.jpg
meter_det/train/20190830142803846.jpg
meter_det/train/20190829093639008.jpg
meter_det/train/20190830095425702.jpg
meter_det/train/20190822_48.jpg
meter_det/train/20190830145640003.jpg
meter_det/train/20190830095837476.jpg
meter_det/train/20190827140824290.jpg
meter_det/train/20190822_95.jpg
meter_det/train/20190827110257261.jpg
meter_det/train/20190822_118.jpg
meter_det/train/20190829153240391.jpg
meter_det/train/20190829092756768.jpg
meter_det/train/20190830143647652.jpg
meter_det/train/20190830111301750.jpg
meter_det/train/20190830144021330.jpg
meter_det/train/20190830145202294.jpg
meter_det/train/20190830104751196.jpg
meter_det/train/20190830111512846.jpg
meter_det/train/20190830150035125.jpg
meter_det/train/20190829143003986.jpg
meter_det/train/20190830160150143.jpg
meter_det/train/20190829150717479.jpg
meter_det/train/20190828163008814.jpg
meter_det/train/20190830095737063.jpg
meter_det/train/20190827151048650.jpg
meter_det/train/20190822_85.jpg
meter_det/train/20190830104730540.jpg
meter_det/train/20190829093648467.jpg
meter_det/train/20190827111641017.jpg
meter_det/train/20190822_34.jpg
meter_det/train/20190829153029645.jpg
meter_det/train/20190829143751656.jpg
meter_det/train/20190829093358595.jpg
meter_det/train/20190829153224849.jpg
meter_det/train/20190830094234552.jpg
meter_det/train/20190830105817246.jpg
meter_det/train/20190827112023125.jpg
meter_det/train/20190830093501356.jpg
meter_det/train/20190827112817109.jpg
meter_det/train/20190828162147315.jpg
meter_det/train/20190822_128.jpg
meter_det/train/20190829153546152.jpg
meter_det/train/20190830095824158.jpg
meter_det/train/20190822_141.jpg
meter_det/train/20190827105028248.jpg
meter_det/annotations/
meter_det/annotations/instance_test.json
meter_det/annotations/instance_train.json
meter_det/test/
meter_det/test/20190830093754013.jpg
meter_det/test/20190827144904196.jpg
meter_det/test/20190829154919143.jpg
meter_det/test/20190822_137.jpg
meter_det/test/20190830105613993.jpg
meter_det/test/20190829154450495.jpg
meter_det/test/20190830142017334.jpg
meter_det/test/20190830142056680.jpg
meter_det/test/20190822_135.jpg
meter_det/test/20190829145624098.jpg
meter_det/test/20190830104748296.jpg
meter_det/test/20190830095801880.jpg
meter_det/test/20190830105617843.jpg
meter_det/test/20190822_4.jpg
meter_det/test/20190822_6.jpg
meter_det/test/20190830142809547.jpg
meter_det/test/20190827162517343.jpg
meter_det/test/20190830143751252.jpg
meter_det/test/20190830105812192.jpg
meter_det/test/20190822_160.jpg
meter_det/test/20190830093446314.jpg
meter_det/test/20190829094152454.jpg
meter_det/test/20190827144044452.jpg
meter_det/test/20190822_123.jpg
meter_det/test/20190822_28.jpg
meter_det/test/20190822_18.jpg
meter_det/test/20190829151828206.jpg
meter_det/test/20190822_132.jpg
meter_det/test/20190830093702284.jpg
meter_det/test/20190829154802545.jpg
meter_det/test/20190829154558626.jpg
meter_det/test/20190828162841446.jpg
meter_det/test/20190822_51.jpg
meter_det/test/20190829093336623.jpg
meter_det/test/20190829154328801.jpg
meter_det/test/20190822_129.jpg
meter_det/test/20190830094207973.jpg
meter_det/test/20190827144452222.jpg
meter_det/test/20190830104726241.jpg
meter_det/test/20190829143301179.jpg
meter_det/test/20190822_110.jpg
meter_det/test/20190822_124.jpg
meter_det/test/20190829093217832.jpg
meter_det/test/20190822_142.jpg
meter_det/test/20190830142633607.jpg
meter_det/test/20190822_168.jpg
meter_det/test/20190828163034384.jpg
meter_det/test/20190822_93.jpg
meter_det/test/20190829151432165.jpg
meter_det/test/20190829153501975.jpg
meter_det/test/20190829145629183.jpg
meter_det/test/20190822_127.jpg
meter_det/test/20190822_86.jpg
meter_det/test/20190830104525359.jpg
meter_det/test/20190822_105.jpg
meter_det/test/20190827143933102.jpg
meter_det/test/20190830144244350.jpg
meter_det/test/20190829154752532.jpg
–2022-06-16 19:43:25-- https://bj.bcebos.com/paddlex/examples/meter_reader/datasets/meter_seg.tar.gz
Resolving bj.bcebos.com (bj.bcebos.com)… 182.61.200.195, 182.61.200.229, 2409:8c04:1001:1002:0:ff:b001:368a
Connecting to bj.bcebos.com (bj.bcebos.com)|182.61.200.195|:443… connected.
HTTP request sent, awaiting response… 200 OK
Length: 11604370 (11M) [application/octet-stream]
Saving to: ‘meter_seg.tar.gz.1’

meter_seg.tar.gz.1 100%[===================>] 11.07M 7.03MB/s in 1.6s

2022-06-16 19:43:26 (7.03 MB/s) - ‘meter_seg.tar.gz.1’ saved [11604370/11604370]

meter_seg/
meter_seg/annotations/
meter_seg/annotations/train/
meter_seg/annotations/train/414.png
meter_seg/annotations/train/730.png
meter_seg/annotations/train/723.png
meter_seg/annotations/train/721.png
meter_seg/annotations/train/463.png
meter_seg/annotations/train/486.png
meter_seg/annotations/train/607.png
meter_seg/annotations/train/170.png
meter_seg/annotations/train/190.png
meter_seg/annotations/train/315.png
meter_seg/annotations/train/204.png
meter_seg/annotations/train/183.png
meter_seg/annotations/train/234.png
meter_seg/annotations/train/220.png
meter_seg/annotations/train/326.png
meter_seg/annotations/train/11.png
meter_seg/annotations/train/467.png
meter_seg/annotations/train/821.png
meter_seg/annotations/train/189.png
meter_seg/annotations/train/681.png
meter_seg/annotations/train/764.png
meter_seg/annotations/train/121.png
meter_seg/annotations/train/154.png
meter_seg/annotations/train/339.png
meter_seg/annotations/train/345.png
meter_seg/annotations/train/324.png
meter_seg/annotations/train/727.png
meter_seg/annotations/train/276.png
meter_seg/annotations/train/38.png
meter_seg/annotations/train/318.png
meter_seg/annotations/train/642.png
meter_seg/annotations/train/323.png
meter_seg/annotations/train/86.png
meter_seg/annotations/train/408.png
meter_seg/annotations/train/74.png
meter_seg/annotations/train/675.png
meter_seg/annotations/train/180.png
meter_seg/annotations/train/212.png
meter_seg/annotations/train/449.png
meter_seg/annotations/train/719.png
meter_seg/annotations/train/374.png
meter_seg/annotations/train/794.png
meter_seg/annotations/train/389.png
meter_seg/annotations/train/182.png
meter_seg/annotations/train/448.png
meter_seg/annotations/train/146.png
meter_seg/annotations/train/257.png
meter_seg/annotations/train/474.png
meter_seg/annotations/train/355.png
meter_seg/annotations/train/280.png
meter_seg/annotations/train/746.png
meter_seg/annotations/train/316.png
meter_seg/annotations/train/628.png
meter_seg/annotations/train/441.png
meter_seg/annotations/train/649.png
meter_seg/annotations/train/492.png
meter_seg/annotations/train/292.png
meter_seg/annotations/train/412.png
meter_seg/annotations/train/173.png
meter_seg/annotations/train/631.png
meter_seg/annotations/train/42.png
meter_seg/annotations/train/452.png
meter_seg/annotations/train/15.png
meter_seg/annotations/train/144.png
meter_seg/annotations/train/296.png
meter_seg/annotations/train/822.png
meter_seg/annotations/train/789.png
meter_seg/annotations/train/669.png
meter_seg/annotations/train/830.png
meter_seg/annotations/train/791.png
meter_seg/annotations/train/663.png
meter_seg/annotations/train/90.png
meter_seg/annotations/train/201.png
meter_seg/annotations/train/8.png
meter_seg/annotations/train/709.png
meter_seg/annotations/train/347.png
meter_seg/annotations/train/453.png
meter_seg/annotations/train/156.png
meter_seg/annotations/train/635.png
meter_seg/annotations/train/240.png
meter_seg/annotations/train/613.png
meter_seg/annotations/train/361.png
meter_seg/annotations/train/237.png
meter_seg/annotations/train/609.png
meter_seg/annotations/train/235.png
meter_seg/annotations/train/12.png
meter_seg/annotations/train/445.png
meter_seg/annotations/train/198.png
meter_seg/annotations/train/136.png
meter_seg/annotations/train/771.png
meter_seg/annotations/train/697.png
meter_seg/annotations/train/437.png
meter_seg/annotations/train/163.png
meter_seg/annotations/train/367.png
meter_seg/annotations/train/368.png
meter_seg/annotations/train/728.png
meter_seg/annotations/train/332.png
meter_seg/annotations/train/406.png
meter_seg/annotations/train/298.png
meter_seg/annotations/train/119.png
meter_seg/annotations/train/113.png
meter_seg/annotations/train/383.png
meter_seg/annotations/train/820.png
meter_seg/annotations/train/636.png
meter_seg/annotations/train/75.png
meter_seg/annotations/train/50.png
meter_seg/annotations/train/290.png
meter_seg/annotations/train/676.png
meter_seg/annotations/train/651.png
meter_seg/annotations/train/733.png
meter_seg/annotations/train/818.png
meter_seg/annotations/train/614.png
meter_seg/annotations/train/281.png
meter_seg/annotations/train/287.png
meter_seg/annotations/train/615.png
meter_seg/annotations/train/695.png
meter_seg/annotations/train/381.png
meter_seg/annotations/train/611.png
meter_seg/annotations/train/806.png
meter_seg/annotations/train/786.png
meter_seg/annotations/train/792.png
meter_seg/annotations/train/172.png
meter_seg/annotations/train/739.png
meter_seg/annotations/train/700.png
meter_seg/annotations/train/39.png
meter_seg/annotations/train/354.png
meter_seg/annotations/train/5.png
meter_seg/annotations/train/392.png
meter_seg/annotations/train/457.png
meter_seg/annotations/train/195.png
meter_seg/annotations/train/743.png
meter_seg/annotations/train/765.png
meter_seg/annotations/train/61.png
meter_seg/annotations/train/803.png
meter_seg/annotations/train/59.png
meter_seg/annotations/train/197.png
meter_seg/annotations/train/241.png
meter_seg/annotations/train/621.png
meter_seg/annotations/train/109.png
meter_seg/annotations/train/179.png
meter_seg/annotations/train/433.png
meter_seg/annotations/train/304.png
meter_seg/annotations/train/423.png
meter_seg/annotations/train/205.png
meter_seg/annotations/train/289.png
meter_seg/annotations/train/832.png
meter_seg/annotations/train/459.png
meter_seg/annotations/train/402.png
meter_seg/annotations/train/620.png
meter_seg/annotations/train/718.png
meter_seg/annotations/train/790.png
meter_seg/annotations/train/193.png
meter_seg/annotations/train/747.png
meter_seg/annotations/train/646.png
meter_seg/annotations/train/632.png
meter_seg/annotations/train/477.png
meter_seg/annotations/train/9.png
meter_seg/annotations/train/111.png
meter_seg/annotations/train/65.png
meter_seg/annotations/train/263.png
meter_seg/annotations/train/768.png
meter_seg/annotations/train/650.png
meter_seg/annotations/train/253.png
meter_seg/annotations/train/344.png
meter_seg/annotations/train/688.png
meter_seg/annotations/train/823.png
meter_seg/annotations/train/188.png
meter_seg/annotations/train/68.png
meter_seg/annotations/train/338.png
meter_seg/annotations/train/605.png
meter_seg/annotations/train/191.png
meter_seg/annotations/train/438.png
meter_seg/annotations/train/219.png
meter_seg/annotations/train/702.png
meter_seg/annotations/train/619.png
meter_seg/annotations/train/781.png
meter_seg/annotations/train/250.png
meter_seg/annotations/train/365.png
meter_seg/annotations/train/772.png
meter_seg/annotations/train/808.png
meter_seg/annotations/train/629.png
meter_seg/annotations/train/742.png
meter_seg/annotations/train/384.png
meter_seg/annotations/train/343.png
meter_seg/annotations/train/311.png
meter_seg/annotations/train/18.png
meter_seg/annotations/train/331.png
meter_seg/annotations/train/415.png
meter_seg/annotations/train/243.png
meter_seg/annotations/train/404.png
meter_seg/annotations/train/639.png
meter_seg/annotations/train/301.png
meter_seg/annotations/train/671.png
meter_seg/annotations/train/129.png
meter_seg/annotations/train/693.png
meter_seg/annotations/train/751.png
meter_seg/annotations/train/440.png
meter_seg/annotations/train/394.png
meter_seg/annotations/train/89.png
meter_seg/annotations/train/797.png
meter_seg/annotations/train/88.png
meter_seg/annotations/train/407.png
meter_seg/annotations/train/294.png
meter_seg/annotations/train/829.png
meter_seg/annotations/train/319.png
meter_seg/annotations/train/227.png
meter_seg/annotations/train/139.png
meter_seg/annotations/train/480.png
meter_seg/annotations/train/656.png
meter_seg/annotations/train/114.png
meter_seg/annotations/train/418.png
meter_seg/annotations/train/299.png
meter_seg/annotations/train/726.png
meter_seg/annotations/train/677.png
meter_seg/annotations/train/691.png
meter_seg/annotations/train/458.png
meter_seg/annotations/train/455.png
meter_seg/annotations/train/124.png
meter_seg/annotations/train/446.png
meter_seg/annotations/train/349.png
meter_seg/annotations/train/662.png
meter_seg/annotations/train/608.png
meter_seg/annotations/train/485.png
meter_seg/annotations/train/270.png
meter_seg/annotations/train/825.png
meter_seg/annotations/train/682.png
meter_seg/annotations/train/701.png
meter_seg/annotations/train/429.png
meter_seg/annotations/train/659.png
meter_seg/annotations/train/22.png
meter_seg/annotations/train/215.png
meter_seg/annotations/train/465.png
meter_seg/annotations/train/307.png
meter_seg/annotations/train/302.png
meter_seg/annotations/train/286.png
meter_seg/annotations/train/807.png
meter_seg/annotations/train/358.png
meter_seg/annotations/train/491.png
meter_seg/annotations/train/750.png
meter_seg/annotations/train/796.png
meter_seg/annotations/train/763.png
meter_seg/annotations/train/123.png
meter_seg/annotations/train/460.png
meter_seg/annotations/train/826.png
meter_seg/annotations/train/295.png
meter_seg/annotations/train/678.png
meter_seg/annotations/train/85.png
meter_seg/annotations/train/831.png
meter_seg/annotations/train/660.png
meter_seg/annotations/train/233.png
meter_seg/annotations/train/782.png
meter_seg/annotations/train/652.png
meter_seg/annotations/train/622.png
meter_seg/annotations/train/814.png
meter_seg/annotations/train/334.png
meter_seg/annotations/train/603.png
meter_seg/annotations/train/633.png
meter_seg/annotations/train/128.png
meter_seg/annotations/train/184.png
meter_seg/annotations/train/801.png
meter_seg/annotations/train/34.png
meter_seg/annotations/train/58.png
meter_seg/annotations/train/416.png
meter_seg/annotations/train/137.png
meter_seg/annotations/train/60.png
meter_seg/annotations/train/376.png
meter_seg/annotations/train/653.png
meter_seg/annotations/train/787.png
meter_seg/annotations/train/153.png
meter_seg/annotations/train/79.png
meter_seg/annotations/train/67.png
meter_seg/annotations/train/793.png
meter_seg/annotations/train/325.png
meter_seg/annotations/train/744.png
meter_seg/annotations/train/274.png
meter_seg/annotations/train/245.png
meter_seg/annotations/train/254.png
meter_seg/annotations/train/76.png
meter_seg/annotations/train/432.png
meter_seg/annotations/train/306.png
meter_seg/annotations/train/483.png
meter_seg/annotations/train/616.png
meter_seg/annotations/train/481.png
meter_seg/annotations/train/435.png
meter_seg/annotations/train/668.png
meter_seg/annotations/train/346.png
meter_seg/annotations/train/217.png
meter_seg/annotations/train/378.png
meter_seg/annotations/train/466.png
meter_seg/annotations/train/687.png
meter_seg/annotations/train/138.png
meter_seg/annotations/train/317.png
meter_seg/annotations/train/66.png
meter_seg/annotations/train/819.png
meter_seg/annotations/train/236.png
meter_seg/annotations/train/698.png
meter_seg/annotations/train/767.png
meter_seg/annotations/train/397.png
meter_seg/annotations/train/710.png
meter_seg/annotations/train/288.png
meter_seg/annotations/train/759.png
meter_seg/annotations/train/145.png
meter_seg/annotations/train/624.png
meter_seg/annotations/train/282.png
meter_seg/annotations/train/424.png
meter_seg/annotations/train/199.png
meter_seg/annotations/train/278.png
meter_seg/annotations/train/679.png
meter_seg/annotations/train/70.png
meter_seg/annotations/train/105.png
meter_seg/annotations/train/400.png
meter_seg/annotations/train/168.png
meter_seg/annotations/train/98.png
meter_seg/annotations/train/439.png
meter_seg/annotations/train/231.png
meter_seg/annotations/train/773.png
meter_seg/annotations/train/456.png
meter_seg/annotations/train/464.png
meter_seg/annotations/train/604.png
meter_seg/annotations/train/115.png
meter_seg/annotations/train/106.png
meter_seg/annotations/train/749.png
meter_seg/annotations/train/648.png
meter_seg/annotations/train/488.png
meter_seg/annotations/train/630.png
meter_seg/annotations/train/377.png
meter_seg/annotations/train/471.png
meter_seg/annotations/train/293.png
meter_seg/annotations/train/166.png
meter_seg/annotations/train/696.png
meter_seg/annotations/train/149.png
meter_seg/annotations/train/762.png
meter_seg/annotations/train/756.png
meter_seg/annotations/train/388.png
meter_seg/annotations/train/612.png
meter_seg/annotations/train/308.png
meter_seg/annotations/train/752.png
meter_seg/annotations/train/800.png
meter_seg/annotations/train/420.png
meter_seg/annotations/train/729.png
meter_seg/annotations/train/658.png
meter_seg/annotations/train/647.png
meter_seg/annotations/train/606.png
meter_seg/annotations/train/73.png
meter_seg/annotations/train/722.png
meter_seg/annotations/train/271.png
meter_seg/annotations/train/45.png
meter_seg/annotations/train/353.png
meter_seg/annotations/train/706.png
meter_seg/annotations/train/655.png
meter_seg/annotations/train/322.png
meter_seg/annotations/train/175.png
meter_seg/annotations/train/475.png
meter_seg/annotations/train/256.png
meter_seg/annotations/train/33.png
meter_seg/annotations/train/24.png
meter_seg/annotations/train/431.png
meter_seg/annotations/train/405.png
meter_seg/annotations/train/741.png
meter_seg/annotations/train/54.png
meter_seg/annotations/train/273.png
meter_seg/annotations/train/133.png
meter_seg/annotations/train/654.png
meter_seg/annotations/train/99.png
meter_seg/annotations/train/824.png
meter_seg/annotations/train/208.png
meter_seg/annotations/train/478.png
meter_seg/annotations/train/421.png
meter_seg/annotations/train/745.png
meter_seg/annotations/train/313.png
meter_seg/annotations/train/352.png
meter_seg/annotations/train/242.png
meter_seg/annotations/train/147.png
meter_seg/annotations/train/375.png
meter_seg/annotations/val/
meter_seg/annotations/val/327.png
meter_seg/annotations/val/194.png
meter_seg/annotations/val/64.png
meter_seg/annotations/val/110.png
meter_seg/annotations/val/17.png
meter_seg/annotations/val/80.png
meter_seg/annotations/val/371.png
meter_seg/annotations/val/403.png
meter_seg/annotations/val/35.png
meter_seg/annotations/val/390.png
meter_seg/annotations/val/305.png
meter_seg/annotations/val/249.png
meter_seg/annotations/val/216.png
meter_seg/annotations/val/131.png
meter_seg/annotations/val/357.png
meter_seg/annotations/val/120.png
meter_seg/annotations/val/143.png
meter_seg/annotations/val/6.png
meter_seg/annotations/val/348.png
meter_seg/annotations/val/167.png
meter_seg/annotations/val/52.png
meter_seg/annotations/val/314.png
meter_seg/annotations/val/419.png
meter_seg/annotations/val/258.png
meter_seg/annotations/val/283.png
meter_seg/annotations/val/238.png
meter_seg/annotations/val/151.png
meter_seg/annotations/val/342.png
meter_seg/annotations/val/72.png
meter_seg/annotations/val/291.png
meter_seg/annotations/val/185.png
meter_seg/annotations/val/380.png
meter_seg/annotations/val/410.png
meter_seg/annotations/val/297.png
meter_seg/annotations/val/275.png
meter_seg/annotations/val/177.png
meter_seg/annotations/val/91.png
meter_seg/annotations/val/232.png
meter_seg/annotations/val/203.png
meter_seg/annotations/val/321.png
meter_seg/test.txt
meter_seg/labels.txt
meter_seg/train.txt
meter_seg/val.txt
meter_seg/images/
meter_seg/images/train/
meter_seg/images/train/746.jpg
meter_seg/images/train/821.jpg
meter_seg/images/train/358.jpg
meter_seg/images/train/455.jpg
meter_seg/images/train/721.jpg
meter_seg/images/train/477.jpg
meter_seg/images/train/70.jpg
meter_seg/images/train/820.jpg
meter_seg/images/train/307.jpg
meter_seg/images/train/773.jpg
meter_seg/images/train/405.jpg
meter_seg/images/train/635.jpg
meter_seg/images/train/311.jpg
meter_seg/images/train/240.jpg
meter_seg/images/train/318.jpg
meter_seg/images/train/650.jpg
meter_seg/images/train/175.jpg
meter_seg/images/train/676.jpg
meter_seg/images/train/790.jpg
meter_seg/images/train/400.jpg
meter_seg/images/train/739.jpg
meter_seg/images/train/424.jpg
meter_seg/images/train/633.jpg
meter_seg/images/train/273.jpg
meter_seg/images/train/8.jpg
meter_seg/images/train/404.jpg
meter_seg/images/train/374.jpg
meter_seg/images/train/368.jpg
meter_seg/images/train/154.jpg
meter_seg/images/train/39.jpg
meter_seg/images/train/688.jpg
meter_seg/images/train/794.jpg
meter_seg/images/train/706.jpg
meter_seg/images/train/76.jpg
meter_seg/images/train/201.jpg
meter_seg/images/train/199.jpg
meter_seg/images/train/613.jpg
meter_seg/images/train/698.jpg
meter_seg/images/train/289.jpg
meter_seg/images/train/367.jpg
meter_seg/images/train/293.jpg
meter_seg/images/train/446.jpg
meter_seg/images/train/168.jpg
meter_seg/images/train/146.jpg
meter_seg/images/train/381.jpg
meter_seg/images/train/378.jpg
meter_seg/images/train/772.jpg
meter_seg/images/train/718.jpg
meter_seg/images/train/60.jpg
meter_seg/images/train/237.jpg
meter_seg/images/train/59.jpg
meter_seg/images/train/485.jpg
meter_seg/images/train/119.jpg
meter_seg/images/train/42.jpg
meter_seg/images/train/463.jpg
meter_seg/images/train/668.jpg
meter_seg/images/train/752.jpg
meter_seg/images/train/136.jpg
meter_seg/images/train/389.jpg
meter_seg/images/train/184.jpg
meter_seg/images/train/677.jpg
meter_seg/images/train/287.jpg
meter_seg/images/train/198.jpg
meter_seg/images/train/762.jpg
meter_seg/images/train/12.jpg
meter_seg/images/train/38.jpg
meter_seg/images/train/276.jpg
meter_seg/images/train/18.jpg
meter_seg/images/train/75.jpg
meter_seg/images/train/45.jpg
meter_seg/images/train/257.jpg
meter_seg/images/train/270.jpg
meter_seg/images/train/652.jpg
meter_seg/images/train/759.jpg
meter_seg/images/train/433.jpg
meter_seg/images/train/701.jpg
meter_seg/images/train/437.jpg
meter_seg/images/train/764.jpg
meter_seg/images/train/786.jpg
meter_seg/images/train/432.jpg
meter_seg/images/train/113.jpg
meter_seg/images/train/448.jpg
meter_seg/images/train/254.jpg
meter_seg/images/train/15.jpg
meter_seg/images/train/669.jpg
meter_seg/images/train/250.jpg
meter_seg/images/train/616.jpg
meter_seg/images/train/453.jpg
meter_seg/images/train/253.jpg
meter_seg/images/train/347.jpg
meter_seg/images/train/313.jpg
meter_seg/images/train/429.jpg
meter_seg/images/train/741.jpg
meter_seg/images/train/179.jpg
meter_seg/images/train/208.jpg
meter_seg/images/train/632.jpg
meter_seg/images/train/491.jpg
meter_seg/images/train/50.jpg
meter_seg/images/train/439.jpg
meter_seg/images/train/655.jpg
meter_seg/images/train/323.jpg
meter_seg/images/train/474.jpg
meter_seg/images/train/377.jpg
meter_seg/images/train/137.jpg
meter_seg/images/train/459.jpg
meter_seg/images/train/830.jpg
meter_seg/images/train/317.jpg
meter_seg/images/train/456.jpg
meter_seg/images/train/467.jpg
meter_seg/images/train/85.jpg
meter_seg/images/train/68.jpg
meter_seg/images/train/465.jpg
meter_seg/images/train/124.jpg
meter_seg/images/train/397.jpg
meter_seg/images/train/605.jpg
meter_seg/images/train/133.jpg
meter_seg/images/train/416.jpg
meter_seg/images/train/800.jpg
meter_seg/images/train/475.jpg
meter_seg/images/train/256.jpg
meter_seg/images/train/651.jpg
meter_seg/images/train/123.jpg
meter_seg/images/train/808.jpg
meter_seg/images/train/278.jpg
meter_seg/images/train/205.jpg
meter_seg/images/train/352.jpg
meter_seg/images/train/231.jpg
meter_seg/images/train/742.jpg
meter_seg/images/train/115.jpg
meter_seg/images/train/376.jpg
meter_seg/images/train/67.jpg
meter_seg/images/train/744.jpg
meter_seg/images/train/722.jpg
meter_seg/images/train/355.jpg
meter_seg/images/train/243.jpg
meter_seg/images/train/180.jpg
meter_seg/images/train/671.jpg
meter_seg/images/train/182.jpg
meter_seg/images/train/687.jpg
meter_seg/images/train/466.jpg
meter_seg/images/train/614.jpg
meter_seg/images/train/823.jpg
meter_seg/images/train/163.jpg
meter_seg/images/train/191.jpg
meter_seg/images/train/245.jpg
meter_seg/images/train/412.jpg
meter_seg/images/train/322.jpg
meter_seg/images/train/190.jpg
meter_seg/images/train/212.jpg
meter_seg/images/train/139.jpg
meter_seg/images/train/829.jpg
meter_seg/images/train/709.jpg
meter_seg/images/train/149.jpg
meter_seg/images/train/407.jpg
meter_seg/images/train/61.jpg
meter_seg/images/train/421.jpg
meter_seg/images/train/452.jpg
meter_seg/images/train/607.jpg
meter_seg/images/train/217.jpg
meter_seg/images/train/438.jpg
meter_seg/images/train/781.jpg
meter_seg/images/train/492.jpg
meter_seg/images/train/215.jpg
meter_seg/images/train/361.jpg
meter_seg/images/train/173.jpg
meter_seg/images/train/344.jpg
meter_seg/images/train/606.jpg
meter_seg/images/train/822.jpg
meter_seg/images/train/343.jpg
meter_seg/images/train/723.jpg
meter_seg/images/train/331.jpg
meter_seg/images/train/280.jpg
meter_seg/images/train/622.jpg
meter_seg/images/train/441.jpg
meter_seg/images/train/458.jpg
meter_seg/images/train/771.jpg
meter_seg/images/train/628.jpg
meter_seg/images/train/457.jpg
meter_seg/images/train/271.jpg
meter_seg/images/train/295.jpg
meter_seg/images/train/324.jpg
meter_seg/images/train/281.jpg
meter_seg/images/train/629.jpg
meter_seg/images/train/299.jpg
meter_seg/images/train/197.jpg
meter_seg/images/train/825.jpg
meter_seg/images/train/88.jpg
meter_seg/images/train/642.jpg
meter_seg/images/train/832.jpg
meter_seg/images/train/609.jpg
meter_seg/images/train/138.jpg
meter_seg/images/train/662.jpg
meter_seg/images/train/646.jpg
meter_seg/images/train/354.jpg
meter_seg/images/train/647.jpg
meter_seg/images/train/109.jpg
meter_seg/images/train/234.jpg
meter_seg/images/train/648.jpg
meter_seg/images/train/767.jpg
meter_seg/images/train/290.jpg
meter_seg/images/train/624.jpg
meter_seg/images/train/332.jpg
meter_seg/images/train/219.jpg
meter_seg/images/train/193.jpg
meter_seg/images/train/402.jpg
meter_seg/images/train/726.jpg
meter_seg/images/train/697.jpg
meter_seg/images/train/630.jpg
meter_seg/images/train/172.jpg
meter_seg/images/train/431.jpg
meter_seg/images/train/338.jpg
meter_seg/images/train/308.jpg
meter_seg/images/train/392.jpg
meter_seg/images/train/464.jpg
meter_seg/images/train/415.jpg
meter_seg/images/train/486.jpg
meter_seg/images/train/631.jpg
meter_seg/images/train/73.jpg
meter_seg/images/train/24.jpg
meter_seg/images/train/481.jpg
meter_seg/images/train/301.jpg
meter_seg/images/train/294.jpg
meter_seg/images/train/302.jpg
meter_seg/images/train/728.jpg
meter_seg/images/train/183.jpg
meter_seg/images/train/435.jpg
meter_seg/images/train/144.jpg
meter_seg/images/train/819.jpg
meter_seg/images/train/693.jpg
meter_seg/images/train/220.jpg
meter_seg/images/train/818.jpg
meter_seg/images/train/460.jpg
meter_seg/images/train/286.jpg
meter_seg/images/train/106.jpg
meter_seg/images/train/679.jpg
meter_seg/images/train/719.jpg
meter_seg/images/train/789.jpg
meter_seg/images/train/768.jpg
meter_seg/images/train/420.jpg
meter_seg/images/train/292.jpg
meter_seg/images/train/315.jpg
meter_seg/images/train/700.jpg
meter_seg/images/train/345.jpg
meter_seg/images/train/750.jpg
meter_seg/images/train/114.jpg
meter_seg/images/train/636.jpg
meter_seg/images/train/480.jpg
meter_seg/images/train/730.jpg
meter_seg/images/train/128.jpg
meter_seg/images/train/787.jpg
meter_seg/images/train/90.jpg
meter_seg/images/train/791.jpg
meter_seg/images/train/89.jpg
meter_seg/images/train/733.jpg
meter_seg/images/train/824.jpg
meter_seg/images/train/406.jpg
meter_seg/images/train/710.jpg
meter_seg/images/train/408.jpg
meter_seg/images/train/98.jpg
meter_seg/images/train/349.jpg
meter_seg/images/train/316.jpg
meter_seg/images/train/233.jpg
meter_seg/images/train/807.jpg
meter_seg/images/train/763.jpg
meter_seg/images/train/793.jpg
meter_seg/images/train/242.jpg
meter_seg/images/train/326.jpg
meter_seg/images/train/803.jpg
meter_seg/images/train/153.jpg
meter_seg/images/train/418.jpg
meter_seg/images/train/675.jpg
meter_seg/images/train/384.jpg
meter_seg/images/train/54.jpg
meter_seg/images/train/111.jpg
meter_seg/images/train/325.jpg
meter_seg/images/train/663.jpg
meter_seg/images/train/483.jpg
meter_seg/images/train/353.jpg
meter_seg/images/train/814.jpg
meter_seg/images/train/801.jpg
meter_seg/images/train/747.jpg
meter_seg/images/train/782.jpg
meter_seg/images/train/478.jpg
meter_seg/images/train/691.jpg
meter_seg/images/train/471.jpg
meter_seg/images/train/65.jpg
meter_seg/images/train/649.jpg
meter_seg/images/train/66.jpg
meter_seg/images/train/241.jpg
meter_seg/images/train/656.jpg
meter_seg/images/train/5.jpg
meter_seg/images/train/743.jpg
meter_seg/images/train/806.jpg
meter_seg/images/train/654.jpg
meter_seg/images/train/170.jpg
meter_seg/images/train/745.jpg
meter_seg/images/train/375.jpg
meter_seg/images/train/282.jpg
meter_seg/images/train/227.jpg
meter_seg/images/train/394.jpg
meter_seg/images/train/621.jpg
meter_seg/images/train/639.jpg
meter_seg/images/train/682.jpg
meter_seg/images/train/488.jpg
meter_seg/images/train/681.jpg
meter_seg/images/train/604.jpg
meter_seg/images/train/792.jpg
meter_seg/images/train/33.jpg
meter_seg/images/train/105.jpg
meter_seg/images/train/797.jpg
meter_seg/images/train/346.jpg
meter_seg/images/train/236.jpg
meter_seg/images/train/729.jpg
meter_seg/images/train/756.jpg
meter_seg/images/train/11.jpg
meter_seg/images/train/9.jpg
meter_seg/images/train/388.jpg
meter_seg/images/train/826.jpg
meter_seg/images/train/304.jpg
meter_seg/images/train/298.jpg
meter_seg/images/train/702.jpg
meter_seg/images/train/765.jpg
meter_seg/images/train/695.jpg
meter_seg/images/train/603.jpg
meter_seg/images/train/611.jpg
meter_seg/images/train/751.jpg
meter_seg/images/train/658.jpg
meter_seg/images/train/414.jpg
meter_seg/images/train/615.jpg
meter_seg/images/train/22.jpg
meter_seg/images/train/749.jpg
meter_seg/images/train/58.jpg
meter_seg/images/train/696.jpg
meter_seg/images/train/129.jpg
meter_seg/images/train/383.jpg
meter_seg/images/train/156.jpg
meter_seg/images/train/189.jpg
meter_seg/images/train/145.jpg
meter_seg/images/train/263.jpg
meter_seg/images/train/608.jpg
meter_seg/images/train/334.jpg
meter_seg/images/train/147.jpg
meter_seg/images/train/339.jpg
meter_seg/images/train/34.jpg
meter_seg/images/train/319.jpg
meter_seg/images/train/365.jpg
meter_seg/images/train/195.jpg
meter_seg/images/train/79.jpg
meter_seg/images/train/86.jpg
meter_seg/images/train/99.jpg
meter_seg/images/train/74.jpg
meter_seg/images/train/296.jpg
meter_seg/images/train/653.jpg
meter_seg/images/train/288.jpg
meter_seg/images/train/166.jpg
meter_seg/images/train/204.jpg
meter_seg/images/train/831.jpg
meter_seg/images/train/235.jpg
meter_seg/images/train/612.jpg
meter_seg/images/train/445.jpg
meter_seg/images/train/121.jpg
meter_seg/images/train/659.jpg
meter_seg/images/train/619.jpg
meter_seg/images/train/449.jpg
meter_seg/images/train/423.jpg
meter_seg/images/train/796.jpg
meter_seg/images/train/440.jpg
meter_seg/images/train/188.jpg
meter_seg/images/train/274.jpg
meter_seg/images/train/306.jpg
meter_seg/images/train/620.jpg
meter_seg/images/train/678.jpg
meter_seg/images/train/660.jpg
meter_seg/images/train/727.jpg
meter_seg/images/val/
meter_seg/images/val/380.jpg
meter_seg/images/val/403.jpg
meter_seg/images/val/151.jpg
meter_seg/images/val/6.jpg
meter_seg/images/val/72.jpg
meter_seg/images/val/80.jpg
meter_seg/images/val/419.jpg
meter_seg/images/val/194.jpg
meter_seg/images/val/390.jpg
meter_seg/images/val/64.jpg
meter_seg/images/val/52.jpg
meter_seg/images/val/321.jpg
meter_seg/images/val/17.jpg
meter_seg/images/val/249.jpg
meter_seg/images/val/258.jpg
meter_seg/images/val/371.jpg
meter_seg/images/val/342.jpg
meter_seg/images/val/305.jpg
meter_seg/images/val/167.jpg
meter_seg/images/val/314.jpg
meter_seg/images/val/410.jpg
meter_seg/images/val/348.jpg
meter_seg/images/val/297.jpg
meter_seg/images/val/203.jpg
meter_seg/images/val/216.jpg
meter_seg/images/val/91.jpg
meter_seg/images/val/232.jpg
meter_seg/images/val/143.jpg
meter_seg/images/val/120.jpg
meter_seg/images/val/291.jpg
meter_seg/images/val/131.jpg
meter_seg/images/val/357.jpg
meter_seg/images/val/275.jpg
meter_seg/images/val/283.jpg
meter_seg/images/val/185.jpg
meter_seg/images/val/35.jpg
meter_seg/images/val/238.jpg
meter_seg/images/val/177.jpg
meter_seg/images/val/327.jpg
meter_seg/images/val/110.jpg
3 模型选择
PaddlePaddle提供了丰富的视觉模型,在目标检测中提供了RCNN和YOLO系列模型,在语义分割中提供了DeepLabV3P和BiSeNetV2等模型。

PaddleDetection天梯图
在这里插入图片描述

PaddleSeg天梯图在这里插入图片描述
因最终部署场景是本地化的x86平台部署,算力相对充足,因此在本项目中采用精度和预测性能皆优的PPYOLO进行表计检测。考虑到指针和刻度均为细小区域,我们采用精度更优的DeepLabV3P进行指针和刻度的分割。我们会基于PaddleDetection与PaddleSeg工具套件进行模型训练。可以参考以下链接分别安装这两个工具:

PaddleDetection安装教程

PaddleSeg安装教程

此外也可以下载我们训练好并已经导出成静态图格式的模型进行下面的部署流程(跳过步骤4):

表计检测预训练模型 刻度和指针分割预训练模型
meter_det_model meter_seg_model
通过以下指令可以下载并安装PaddleDetection预PaddleSeg的工程环境:

In [ ]

!pip install -r PaddleSeg/requirements.txt #安装PaddleSeg环境依赖
!pip install -r PaddleDetection/requirements.txt #安装PaddleDetection环境依赖
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: pyyaml>=5.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleSeg/requirements.txt (line 1)) (5.1.2)
Requirement already satisfied: visualdl>=2.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleSeg/requirements.txt (line 2)) (2.2.0)
Requirement already satisfied: opencv-python in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleSeg/requirements.txt (line 3)) (4.1.1.26)
Requirement already satisfied: tqdm in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleSeg/requirements.txt (line 4)) (4.36.1)
Requirement already satisfied: filelock in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleSeg/requirements.txt (line 5)) (3.0.12)
Requirement already satisfied: scipy in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleSeg/requirements.txt (line 6)) (1.6.3)
Requirement already satisfied: prettytable in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleSeg/requirements.txt (line 7)) (0.7.2)
Requirement already satisfied: sklearn in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleSeg/requirements.txt (line 8)) (0.0)
Requirement already satisfied: flask>=1.1.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.1.1)
Requirement already satisfied: Pillow>=7.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (7.1.2)
Requirement already satisfied: six>=1.14.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.16.0)
Requirement already satisfied: flake8>=3.7.9 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (4.0.1)
Requirement already satisfied: protobuf>=3.11.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (3.14.0)
Requirement already satisfied: pre-commit in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.21.0)
Requirement already satisfied: matplotlib in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (2.2.3)
Requirement already satisfied: bce-python-sdk in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (0.8.53)
Requirement already satisfied: shellcheck-py in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (0.7.1.1)
Requirement already satisfied: pandas in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.1.5)
Requirement already satisfied: Flask-Babel>=1.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.0.0)
Requirement already satisfied: numpy in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.20.3)
Requirement already satisfied: requests in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (2.22.0)
Requirement already satisfied: scikit-learn in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from sklearn->-r PaddleSeg/requirements.txt (line 8)) (0.24.2)
Requirement already satisfied: mccabe<0.7.0,>=0.6.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (0.6.1)
Requirement already satisfied: pyflakes<2.5.0,>=2.4.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (2.4.0)
Requirement already satisfied: importlib-metadata<4.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (4.2.0)
Requirement already satisfied: pycodestyle<2.9.0,>=2.8.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (2.8.0)
Requirement already satisfied: itsdangerous>=0.24 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.1.0)
Requirement already satisfied: Werkzeug>=0.15 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (0.16.0)
Requirement already satisfied: click>=5.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (7.0)
Requirement already satisfied: Jinja2>=2.10.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (3.0.0)
Requirement already satisfied: Babel>=2.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (2.8.0)
Requirement already satisfied: pytz in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (2019.3)
Requirement already satisfied: future>=0.6.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from bce-python-sdk->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (0.18.0)
Requirement already satisfied: pycryptodome>=3.8.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from bce-python-sdk->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (3.9.9)
Requirement already satisfied: kiwisolver>=1.0.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.1.0)
Requirement already satisfied: cycler>=0.10 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (0.10.0)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (3.0.8)
Requirement already satisfied: python-dateutil>=2.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (2.8.2)
Requirement already satisfied: identify>=1.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.4.10)
Requirement already satisfied: aspy.yaml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.3.0)
Requirement already satisfied: cfgv>=2.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (2.0.1)
Requirement already satisfied: virtualenv>=15.2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (16.7.9)
Requirement already satisfied: nodeenv>=0.11.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.3.4)
Requirement already satisfied: toml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (0.10.0)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (2019.9.11)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (1.25.6)
Requirement already satisfied: idna<2.9,>=2.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (2.8)
Requirement already satisfied: threadpoolctl>=2.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from scikit-learn->sklearn->-r PaddleSeg/requirements.txt (line 8)) (2.1.0)
Requirement already satisfied: joblib>=0.11 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from scikit-learn->sklearn->-r PaddleSeg/requirements.txt (line 8)) (0.14.1)
Requirement already satisfied: zipp>=0.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from importlib-metadata<4.3->flake8>=3.7.9->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (3.8.0)
Requirement already satisfied: typing-extensions>=3.6.4 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from importlib-metadata<4.3->flake8>=3.7.9->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (4.2.0)
Requirement already satisfied: MarkupSafe>=2.0.0rc2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Jinja2>=2.10.1->flask>=1.1.1->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (2.0.1)
Requirement already satisfied: setuptools in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from kiwisolver>=1.0.1->matplotlib->visualdl>=2.0.0->-r PaddleSeg/requirements.txt (line 2)) (56.2.0)
WARNING: You are using pip version 22.0.4; however, version 22.1.2 is available.
You should consider upgrading via the ‘/opt/conda/envs/python35-paddle120-env/bin/python -m pip install --upgrade pip’ command.
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: tqdm in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleDetection/requirements.txt (line 1)) (4.36.1)
Collecting typeguard
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/9a/bb/d43e5c75054e53efce310e79d63df0ac3f25e34c926be5dffb7d283fb2a8/typeguard-2.13.3-py3-none-any.whl (17 kB)
Requirement already satisfied: visualdl>=2.1.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleDetection/requirements.txt (line 3)) (2.2.0)
Requirement already satisfied: opencv-python in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleDetection/requirements.txt (line 4)) (4.1.1.26)
Requirement already satisfied: PyYAML in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleDetection/requirements.txt (line 5)) (5.1.2)
Collecting shapely
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/d1/ec/3038263d69a0065d3ab6944ae839f5f00896efd29b13ae62d73c00345b95/Shapely-1.8.2-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (2.0 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.0/2.0 MB 6.8 MB/s eta 0:00:0000:0100:01
Requirement already satisfied: scipy in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleDetection/requirements.txt (line 7)) (1.6.3)
Collecting terminaltables
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/c4/fb/ea621e0a19733e01fe4005d46087d383693c0f4a8f824b47d8d4122c87e0/terminaltables-3.1.10-py2.py3-none-any.whl (15 kB)
Requirement already satisfied: Cython in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleDetection/requirements.txt (line 9)) (0.29)
Collecting pycocotools
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/75/5c/ac61ea715d7a89ecc31c090753bde28810238225ca8b71778dfe3e6a68bc/pycocotools-2.0.4.tar.gz (106 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 106.6/106.6 KB 146.6 kB/s eta 0:00:00a 0:00:01
Installing build dependencies … done
Getting requirements to build wheel … done
Preparing metadata (pyproject.toml) … done
Requirement already satisfied: setuptools>=42.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleDetection/requirements.txt (line 12)) (56.2.0)
Collecting lap
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/bf/64/d9fb6a75b15e783952b2fec6970f033462e67db32dc43dfbb404c14e91c2/lap-0.4.0.tar.gz (1.5 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.5/1.5 MB 1.7 MB/s eta 0:00:00a 0:00:01
Preparing metadata (setup.py) … done
Requirement already satisfied: sklearn in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleDetection/requirements.txt (line 14)) (0.0)
Collecting motmetrics
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/45/41/b019fe934eb811b9aba9b335f852305b804b9c66f098d7e35c2bdb09d1c8/motmetrics-1.2.5-py3-none-any.whl (161 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 161.1/161.1 KB 3.6 MB/s eta 0:00:00a 0:00:01
Requirement already satisfied: openpyxl in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from -r PaddleDetection/requirements.txt (line 16)) (3.0.5)
Requirement already satisfied: requests in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (2.22.0)
Requirement already satisfied: matplotlib in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (2.2.3)
Requirement already satisfied: flake8>=3.7.9 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (4.0.1)
Requirement already satisfied: Flask-Babel>=1.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.0.0)
Requirement already satisfied: six>=1.14.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.16.0)
Requirement already satisfied: Pillow>=7.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (7.1.2)
Requirement already satisfied: protobuf>=3.11.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (3.14.0)
Requirement already satisfied: bce-python-sdk in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (0.8.53)
Requirement already satisfied: pre-commit in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.21.0)
Requirement already satisfied: numpy in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.20.3)
Requirement already satisfied: shellcheck-py in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (0.7.1.1)
Requirement already satisfied: flask>=1.1.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.1.1)
Requirement already satisfied: pandas in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.1.5)
Requirement already satisfied: scikit-learn in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from sklearn->-r PaddleDetection/requirements.txt (line 14)) (0.24.2)
Collecting xmltodict>=0.12.0
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/94/db/fd0326e331726f07ff7f40675cd86aa804bfd2e5016c727fa761c934990e/xmltodict-0.13.0-py2.py3-none-any.whl (10.0 kB)
Requirement already satisfied: jdcal in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from openpyxl->-r PaddleDetection/requirements.txt (line 16)) (1.4.1)
Requirement already satisfied: et-xmlfile in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from openpyxl->-r PaddleDetection/requirements.txt (line 16)) (1.0.1)
Requirement already satisfied: pyflakes<2.5.0,>=2.4.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (2.4.0)
Requirement already satisfied: pycodestyle<2.9.0,>=2.8.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (2.8.0)
Requirement already satisfied: mccabe<0.7.0,>=0.6.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (0.6.1)
Requirement already satisfied: importlib-metadata<4.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (4.2.0)
Requirement already satisfied: Jinja2>=2.10.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (3.0.0)
Requirement already satisfied: Werkzeug>=0.15 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (0.16.0)
Requirement already satisfied: itsdangerous>=0.24 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.1.0)
Requirement already satisfied: click>=5.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (7.0)
Requirement already satisfied: pytz in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (2019.3)
Requirement already satisfied: Babel>=2.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (2.8.0)
Requirement already satisfied: cycler>=0.10 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (0.10.0)
Requirement already satisfied: python-dateutil>=2.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (2.8.2)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (3.0.8)
Requirement already satisfied: kiwisolver>=1.0.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from matplotlib->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.1.0)
Requirement already satisfied: future>=0.6.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from bce-python-sdk->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (0.18.0)
Requirement already satisfied: pycryptodome>=3.8.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from bce-python-sdk->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (3.9.9)
Requirement already satisfied: aspy.yaml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.3.0)
Requirement already satisfied: toml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (0.10.0)
Requirement already satisfied: identify>=1.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.4.10)
Requirement already satisfied: nodeenv>=0.11.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.3.4)
Requirement already satisfied: virtualenv>=15.2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (16.7.9)
Requirement already satisfied: cfgv>=2.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (2.0.1)
Requirement already satisfied: idna<2.9,>=2.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (2.8)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (3.0.4)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (1.25.6)
Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (2019.9.11)
Requirement already satisfied: joblib>=0.11 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from scikit-learn->sklearn->-r PaddleDetection/requirements.txt (line 14)) (0.14.1)
Requirement already satisfied: threadpoolctl>=2.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from scikit-learn->sklearn->-r PaddleDetection/requirements.txt (line 14)) (2.1.0)
Requirement already satisfied: zipp>=0.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from importlib-metadata<4.3->flake8>=3.7.9->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (3.8.0)
Requirement already satisfied: typing-extensions>=3.6.4 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from importlib-metadata<4.3->flake8>=3.7.9->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (4.2.0)
Requirement already satisfied: MarkupSafe>=2.0.0rc2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Jinja2>=2.10.1->flask>=1.1.1->visualdl>=2.1.0->-r PaddleDetection/requirements.txt (line 3)) (2.0.1)
Building wheels for collected packages: pycocotools, lap
Building wheel for pycocotools (pyproject.toml) … done
Created wheel for pycocotools: filename=pycocotools-2.0.4-cp37-cp37m-linux_x86_64.whl size=273766 sha256=b42d6b2faa81828db3ff304dfafd90fcc280968d6dcb0bcb777644b0b27ebe52
Stored in directory: /home/aistudio/.cache/pip/wheels/c0/01/5f/670dfd20204fc9cc6bf843db4e014acb998f411922e3abc49f
Building wheel for lap (setup.py) … done
Created wheel for lap: filename=lap-0.4.0-cp37-cp37m-linux_x86_64.whl size=1593888 sha256=a22c67deba025d7dfb229934708383a3d66d595d71b6989256b0b26a349690a5
Stored in directory: /home/aistudio/.cache/pip/wheels/5c/d0/d2/e331d17a999666b1e2eb99743cfa1742629f9d26c55c657001
Successfully built pycocotools lap
Installing collected packages: lap, xmltodict, typeguard, terminaltables, shapely, pycocotools, motmetrics
Successfully installed lap-0.4.0 motmetrics-1.2.5 pycocotools-2.0.4 shapely-1.8.2 terminaltables-3.1.10 typeguard-2.13.3 xmltodict-0.13.0
WARNING: You are using pip version 22.0.4; however, version 22.1.2 is available.
You should consider upgrading via the ‘/opt/conda/envs/python35-paddle120-env/bin/python -m pip install --upgrade pip’ command.
4 表计模型训练
4.1 PPYOLO表计检测训练
本项目中采用精度和预测性能的PPYOLO进行表计检测,在该数据集下实测检测准确性评价指标mAP可以达到99.4%。具体信息可以参考PaddleDetection快速上手教程和PPYOLO介绍

arch epoch resolution Batch size Learning rate Augment mAP
PP-YOLO 200 640x640 4 0.0025 RandomHorizontalFlip,RandomCrop,RandomFlip,RandomDistort 99.4%
4.1.1 修改PaddleDetection训练配置文件
修改PaddleDetection/configs/datasets/coco_detection.yml,调整训练集和验证集路径:
metric: COCO
num_classes: 1

TrainDataset:
!COCODataSet
image_dir: train
anno_path: annotations/instance_train.json
dataset_dir: data/meter_det
data_fields: [‘image’, ‘gt_bbox’, ‘gt_class’, ‘is_crowd’]

EvalDataset:
!COCODataSet
image_dir: test
anno_path: annotations/instance_test.json
dataset_dir: data/meter_det

TestDataset:
!ImageFolder
anno_path: annotations/instance_test.json
修改PaddleDetection/configs/ppyolo/base/optimizer_1x.yml, 修改学习率,如果是单卡训练,建议适当降低base_lr以及steps,不然在训练过程中可能会出现loss消失现象,导致模型无法收敛:
epoch: 405

LearningRate:
base_lr: 0.0005
schedulers:

  • !PiecewiseDecay
    gamma: 0.1
    milestones:
    • 243
    • 324
  • !LinearWarmup
    start_factor: 0.
    steps: 1000

OptimizerBuilder:
optimizer:
momentum: 0.9
type: Momentum
regularizer:
factor: 0.0005
type: L2
4.1.2 开启训练
在训练中交替执行评估, 评估在每个epoch训练结束后开始。每次评估后还会评出最佳mAP模型保存到best_model文件夹下。 如果验证集很大,测试将会比较耗时,建议调整configs/runtime.yml 文件中的 snapshot_epoch配置以减少评估次数,或训练完成后再进行评估。

In [3]
!export CUDA_VISIBLE_DEVICES=0 #windows和Mac下不需要执行该命令
!python PaddleDetection/tools/train.py
-c PaddleDetection/configs/ppyolo/ppyolo_r50vd_dcn_1x_coco.yml
–use_vdl=true
–vdl_log_dir=PaddleDetection/vdl_dir/scalar
–eval
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/tensor/creation.py:125: DeprecationWarning: np.object is a deprecated alias for the builtin object. To silence this warning, use object by itself. Doing this will not modify any behavior and is safe.
Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
if data.dtype == np.object:
Warning: import ppdet from source directory without installing, run ‘python setup.py install’ to install ppdet firstly
loading annotations into memory…
Done (t=0.01s)
creating index…
index created!
W0616 19:44:10.501102 510 device_context.cc:404] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 10.1
W0616 19:44:10.504784 510 device_context.cc:422] device: 0, cuDNN Version: 7.6.
[06/16 19:44:13] ppdet.utils.download INFO: Downloading ResNet50_vd_ssld_pretrained.pdparams from https://paddledet.bj.bcebos.com/models/pretrained/ResNet50_vd_ssld_pretrained.pdparams
100%|████████████████████████████████| 138935/138935 [00:06<00:00, 21875.80KB/s]
[06/16 19:44:21] ppdet.utils.checkpoint INFO: Finish loading model weights: /home/aistudio/.cache/paddle/weights/ResNet50_vd_ssld_pretrained.pdparams
[06/16 19:44:21] ppdet.engine INFO: Epoch: [0] [ 0/90] learning_rate: 0.000000 loss_xy: 1.575869 loss_wh: 5.372811 loss_iou: 5.306030 loss_iou_aware: 0.954967 loss_obj: 13897.547852 loss_cls: 1.656612 loss: 13912.414062 eta: 3:54:29 batch_cost: 0.3860 data_cost: 0.0004 ips: 20.7260 images/s
^C
Traceback (most recent call last):
File “PaddleDetection/tools/train.py”, line 177, in
main()
File “PaddleDetection/tools/train.py”, line 173, in main
run(FLAGS, cfg)
File “PaddleDetection/tools/train.py”, line 127, in run
trainer.train(FLAGS.eval)
File “/home/aistudio/PaddleDetection/ppdet/engine/trainer.py”, line 466, in train
self.ema.update()
File “/home/aistudio/PaddleDetection/ppdet/optimizer.py”, line 430, in update
v = decay * v + (1 - decay) * model_dict[k]
File “/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/dygraph/math_op_patch.py”, line 184, in impl
if self.dtype in supported_int_dtype:
KeyboardInterrupt
4.1.3 VisualDL训练可视化
使用如下命令启动VisualDL查看日志, 下述命令会在127.0.0.1上启动一个服务,支持通过前端web页面查看,可以通过–host这个参数指定实际ip地址

In [ ]
visualdl --logdir PaddleDetection/vdl_dir/scalar/
在浏览器输入提示的网址,效果如下:在这里插入图片描述
4.1.4 模型导出
在模型训练过程中保存的模型文件是包含前向预测和反向传播的过程,在实际的工业部署则不需要反向传播,因此需要将模型进行导成部署需要的模型格式。 在PaddleDetection中提供了 tools/export_model.py脚本来导出模型,如果要使用OpenVINO进行部署需要导出成静态图的模型. PPYOLO的预测模型会导出到inference_model/ppyolo_r50vd_dcn_1x_coco目录下,分别为infer_cfg.yml, model.pdiparams, model.pdiparams.info,model.pdmodel 如果不指定文件夹,模型则会导出在output_inference.

In [ ]
!python PaddleDetection/tools/export_model.py
-c PaddleDetection/configs/ppyolo/ppyolo_r50vd_dcn_1x_coco.yml
–output_dir=./inference_model
-o weights=PaddleDetection/output/ppyolo_r50vd_dcn_1x_coco/model_final/best_model.pdparams
4.2 DeepLabV3P 指针和刻度分割训练
本项目中采用精度更优的DeepLabV3P进行指针和刻度的分割,在该数据集下实测分割准确性评价指标mIoU可以达到86.04%。具体信息可以参考PaddleSeg快速上手与PaddleSeg说明

arch epoch resolution Batch size Learning rate Augment mAP
DeepLabV3P 150 512x512 2 0.0025 RandomHorizontalFlip 86.04%
4.2.1 模型训练配置
在完成数据准备后,我要对模型训练的参数进行配置,对PaddleSeg/configs/quick_start/deeplabv3p_resnet50_os8_optic_disc_512x512_1k_teacher.yml进行如下修改:

更换配置文件中type类型、并按照上文提示修改dataset_root和train_path所对应的路径、补充num_classes,以及模型类别等信息。

batch_size: 2
iters: 200000

train_dataset:
type: Dataset
dataset_root: data/meter_seg
train_path: data/meter_seg/train.txt
num_classes: 3
transforms:
- type: Resize
target_size: [512, 512]
- type: RandomHorizontalFlip
- type: Normalize
mean: [0.5, 0.5, 0.5]
std: [0.5, 0.5, 0.5]
mode: train

val_dataset:
type: Dataset
dataset_root: data/meter_seg
val_path: data/meter_seg/val.txt
num_classes: 3
transforms:
- type: Resize
target_size: [512, 512]
- type: Normalize
mean: [0.5, 0.5, 0.5]
std: [0.5, 0.5, 0.5]
mode: val

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

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

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

model:
type: DeepLabV3P
backbone:
type: ResNet50_vd
output_stride: 8
multi_grid: [1, 2, 4]
pretrained: https://bj.bcebos.com/paddleseg/dygraph/resnet50_vd_ssld_v2.tar.gz
num_classes: 3
backbone_indices: [0, 3]
aspp_ratios: [1, 12, 24, 36]
aspp_out_channels: 256
align_corners: False
pretrained: Null
4.2.2 模型训练
当准备好数据集以及配置文件后,我们可以通过PaddleSeg提供的脚本对模型进行训练。 请确保已经完成了PaddleSeg的安装工作,并且位于PaddleSeg目录下,执行以下脚本:

In [ ]
!export CUDA_VISIBLE_DEVICES=0 # 设置1张可用的卡
!python PaddleSeg/train.py
–config PaddleSeg/configs/quick_start/deeplabv3p_resnet50_os8_optic_disc_512x512_1k_teacher.yml
–do_eval
–use_vdl
–save_interval 500
–save_dir PaddleSeg/output
2022-06-13 17:01:13 [INFO]
------------Environment Information-------------
platform: Linux-4.15.0-140-generic-x86_64-with-debian-stretch-sid
Python: 3.7.4 (default, Aug 13 2019, 20:35:49) [GCC 7.3.0]
Paddle compiled with cuda: True
NVCC: Cuda compilation tools, release 10.1, V10.1.243
cudnn: 7.6
GPUs used: 1
CUDA_VISIBLE_DEVICES: None
GPU: [‘GPU 0: Tesla V100-SXM2-32GB’]
GCC: gcc (Ubuntu 7.5.0-3ubuntu1~16.04) 7.5.0
PaddleSeg: 2.5.0
PaddlePaddle: 2.1.2
OpenCV: 4.1.1

2022-06-13 17:01:13 [INFO]
---------------Config Information---------------
batch_size: 2
iters: 200000
loss:
coef:

  • 1
    types:
  • ignore_index: 255
    type: CrossEntropyLoss
    lr_scheduler:
    end_lr: 0
    learning_rate: 0.0025
    power: 0.9
    type: PolynomialDecay
    model:
    align_corners: false
    aspp_out_channels: 256
    aspp_ratios:
  • 1
  • 12
  • 24
  • 36
    backbone:
    multi_grid:
    • 1
    • 2
    • 4
      output_stride: 8
      pretrained: https://bj.bcebos.com/paddleseg/dygraph/resnet50_vd_ssld_v2.tar.gz
      type: ResNet50_vd
      backbone_indices:
  • 0
  • 3
    num_classes: 3
    pretrained: null
    type: DeepLabV3P
    optimizer:
    momentum: 0.9
    type: sgd
    weight_decay: 4.0e-05
    train_dataset:
    dataset_root: data/meter_seg
    mode: train
    num_classes: 3
    train_path: data/meter_seg/train.txt
    transforms:
  • target_size:
    • 512
    • 512
      type: Resize
  • type: RandomHorizontalFlip
  • mean:
    • 0.5
    • 0.5
    • 0.5
      std:
    • 0.5
    • 0.5
    • 0.5
      type: Normalize
      type: Dataset
      val_dataset:
      dataset_root: data/meter_seg
      mode: val
      num_classes: 3
      transforms:
  • target_size:
    • 512
    • 512
      type: Resize
  • mean:
    • 0.5
    • 0.5
    • 0.5
      std:
    • 0.5
    • 0.5
    • 0.5
      type: Normalize
      type: Dataset
      val_path: data/meter_seg/val.txt

W0613 17:01:13.683022 4595 device_context.cc:404] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 10.1
W0613 17:01:13.683069 4595 device_context.cc:422] device: 0, cuDNN Version: 7.6.
2022-06-13 17:01:17 [INFO] Loading pretrained model from https://bj.bcebos.com/paddleseg/dygraph/resnet50_vd_ssld_v2.tar.gz
Connecting to https://bj.bcebos.com/paddleseg/dygraph/resnet50_vd_ssld_v2.tar.gz
Downloading resnet50_vd_ssld_v2.tar.gz
[] 100.00%
Uncompress resnet50_vd_ssld_v2.tar.gz
[
] 100.00%
2022-06-13 17:01:25 [INFO] There are 275/275 variables loaded into ResNet_vd.
2022-06-13 17:01:33 [INFO] [TRAIN] epoch: 1, iter: 20/200000, loss: 0.2567, lr: 0.002500, batch_cost: 0.3654, reader_cost: 0.00019, ips: 5.4731 samples/sec | ETA 20:17:57
2022-06-13 17:01:37 [INFO] [TRAIN] epoch: 1, iter: 30/200000, loss: 0.2438, lr: 0.002500, batch_cost: 0.3682, reader_cost: 0.00021, ips: 5.4315 samples/sec | ETA 20:27:14
2022-06-13 17:01:41 [INFO] [TRAIN] epoch: 1, iter: 40/200000, loss: 0.2171, lr: 0.002500, batch_cost: 0.3645, reader_cost: 0.00019, ips: 5.4874 samples/sec | ETA 20:14:39
2022-06-13 17:01:44 [INFO] [TRAIN] epoch: 1, iter: 50/200000, loss: 0.1754, lr: 0.002499, batch_cost: 0.3660, reader_cost: 0.00020, ips: 5.4649 samples/sec | ETA 20:19:36
2022-06-13 17:01:48 [INFO] [TRAIN] epoch: 1, iter: 60/200000, loss: 0.1649, lr: 0.002499, batch_cost: 0.3651, reader_cost: 0.00019, ips: 5.4782 samples/sec | ETA 20:16:35
2022-06-13 17:01:52 [INFO] [TRAIN] epoch: 1, iter: 70/200000, loss: 0.1458, lr: 0.002499, batch_cost: 0.3641, reader_cost: 0.00019, ips: 5.4932 samples/sec | ETA 20:13:11
2022-06-13 17:01:55 [INFO] [TRAIN] epoch: 1, iter: 80/200000, loss: 0.1496, lr: 0.002499, batch_cost: 0.3634, reader_cost: 0.00019, ips: 5.5037 samples/sec | ETA 20:10:49
2022-06-13 17:01:59 [INFO] [TRAIN] epoch: 1, iter: 90/200000, loss: 0.1356, lr: 0.002499, batch_cost: 0.3727, reader_cost: 0.00021, ips: 5.3660 samples/sec | ETA 20:41:49
2022-06-13 17:02:03 [INFO] [TRAIN] epoch: 1, iter: 100/200000, loss: 0.1293, lr: 0.002499, batch_cost: 0.3715, reader_cost: 0.00020, ips: 5.3836 samples/sec | ETA 20:37:42
2022-06-13 17:02:06 [INFO] [TRAIN] epoch: 1, iter: 110/200000, loss: 0.1259, lr: 0.002499, batch_cost: 0.3640, reader_cost: 0.00019, ips: 5.4951 samples/sec | ETA 20:12:32
2022-06-13 17:02:10 [INFO] [TRAIN] epoch: 1, iter: 120/200000, loss: 0.1093, lr: 0.002499, batch_cost: 0.3657, reader_cost: 0.00020, ips: 5.4684 samples/sec | ETA 20:18:23
2022-06-13 17:02:14 [INFO] [TRAIN] epoch: 1, iter: 130/200000, loss: 0.1025, lr: 0.002499, batch_cost: 0.3661, reader_cost: 0.00019, ips: 5.4629 samples/sec | ETA 20:19:34
2022-06-13 17:02:17 [INFO] [TRAIN] epoch: 1, iter: 140/200000, loss: 0.1139, lr: 0.002498, batch_cost: 0.3663, reader_cost: 0.00020, ips: 5.4595 samples/sec | ETA 20:20:15
^C
4.2.3 恢复训练:
python PaddleSeg/train.py
–config PaddleSeg/configs/quick_start/deeplabv3p_resnet50_meter.yml
–resume_model PaddleSeg/output/iter_500
–do_eval
–use_vdl
–save_interval 500
–save_dir PaddleSeg/output
4.2.4 训练可视化
PaddleSeg会将训练过程中的数据写入VisualDL文件,并实时的查看训练过程中的日志,记录的数据包括:

loss变化趋势
学习率变化趋势
训练时间
数据读取时间
mean IoU变化趋势(当打开了do_eval开关后生效)
mean pixel Accuracy变化趋势(当打开了do_eval开关后生效)
使用如下命令启动VisualDL查看日志, 下述命令会在127.0.0.1上启动一个服务,支持通过前端web页面查看,可以通过–host这个参数指定实际ip地址

In [ ]
visualdl --logdir PaddleSeg/output/
在浏览器输入提示的网址,效果如下:

在这里插入图片描述
4.2.5 模型导出
模型训练后保存在output文件夹,如果要使用OpenVINO进行部署需要导出成静态图的模型,运行如下命令,会自动在output文件夹下创建一个inference_model的文件夹,用来存放导出后的模型。

In [ ]
!python PaddleSeg/export.py
–config PaddleSeg/configs/quick_start/deeplabv3p_resnet50_os8_optic_disc_512x512_1k_teacher.yml
–model_path PaddleSeg/output/iter_26000/model.pdparams
–save_dir PaddleSeg/output
5 基于OpenVINO进行模型部署
5.1 OpenVINO安装
OpenVINO是是Intel在2018发布的深度学习推理框架,可以提升神经网络模型在Intel硬件平台下的推理性能。近期OpenVINO的最新版本2022.1已经发布,作为版本迭代至今最大的一次升级,今天我们就来可看看新版OpenVINO可以为Paddle模型带来哪些部署和性能优化方案。OpenVINO的Python runtime和工具包可以通过pipy一键完成安装。OpenVINO的其他安装方式可以参考。

pip install openvino-dev
也可以通过requirement.txt直接安装相关依赖:

pip install -r requirements.txt
目前aistudio还无法支持OpenVINO 2022.1版本的直接安装,需要提前将相关推理代码迁移到本地后进行运行。

5.2 测试数据集下载
本案例开放了表计检测数据集,使用该数据集可以测试本次OpenVINO部署的模型精度和识别性能。

表计测试图片
meter_test
5.3 OpenVINO部署
该实例代码将演示如何在通过OpenVINO完成Paddle模型在Intel平台上部署。我们也可以使用训练好的PPYOLO和DeepLabV3P模型对测试用的圆形表计图片进行识别,实现表面缺陷的识别。预训练模型下载地址:

表计检测预训练模型 刻度和指针分割预训练模型
meter_det_model meter_seg_model
以下是本次演示中新版OpenVINO的特性介绍:

直接支持PaddlePaddle模型:目前OpenVINO 2022.1发行版中已完成对PaddlePaddle模型的直接支持,作为国内最受欢迎的深度学习框架之一,之前OpenVINO在对Paddle模型做适配的时候,需要将Paddle模型转化为ONNX格式,再通过MO工具对ONNX模型进行优化和加速部署。现在MO工具已经可以直接完成对Paddle模型的离线转化,同事runtime api接口也可以直接读取加载Paddle模型到指定的硬件设备,省去了离线转换的过程,大大提升了Paddle开发者在Intel平台上部署的效率。经过性能和准确性验证,在OpenVINO™ 2022.1发行版中,会有 13个模型涵盖5大应用场景的Paddle模型将被直接支持,其中不乏像PPYolo和PPOCR这样非常受开发者欢迎的网络。在这里插入图片描述
CPU支持动态输入:为了适配更广泛的模型种类,OpenVINO 2021.1的CPU Plugin已经支持了动态input shape,让开发者以更便捷的方式部署类似NLP或者OCR这样的网络。在不支持动态input shape的情况下,我们往往需要通过Padding ,Model reshape或者是Dimension Partitioning这样的方法对模型或是输入数据进行重构,对性能很准确性都有比较大的影响。虽然通过动态input shape可以减少这部分的影响,但其需要在推理的过程中才能获取输入数据shape,并对模型进行编译,所以综合性能还是不及固定input shape,此时我们建议开发者通过设置upper-bound的方式,为动态维度的数据设置宽度范围,以更高效地进行合理的内存分配,提升性能表现。
OpenVINO runtime api的调用流程可以参考以下链接及示意图:在这里插入图片描述
5.3.1 加载依赖库
In [ ]
import os
import sys
import os.path as osp
import numpy as np
import math
import cv2
import matplotlib.pyplot as plt
from openvino.runtime import Core
5.3.2 参数配置
添加表盘规格等可配置参数,用于计算表盘实际读数

In [ ]
METER_SHAPE = [512, 512]
CIRCLE_CENTER = [256, 256]
CIRCLE_RADIUS = 250
PI = 3.1415926536
RECTANGLE_HEIGHT = 120
RECTANGLE_WIDTH = 1570
TYPE_THRESHOLD = 40
COLORMAP = np.array([[28, 28, 28], [238, 44, 44], [250, 250, 250]])

There are 2 types of meter in test image data-sets

METER_CONFIG = [{
‘scale_interval_value’: 25.0 / 50.0,
‘range’: 25.0,
‘unit’: “(MPa)”
}, {
‘scale_interval_value’: 1.6 / 32.0,
‘range’: 1.6,
‘unit’: “(MPa)”
}]

SEG_CNAME2CLSID = {‘background’: 0, ‘pointer’: 1, ‘scale’: 2}
5.3.3 加载模型
使用OpenVINO进行模型对象初始化

In [ ]

Initialize inference engine

ie_core = Core()

def model_init(det_model_path, seg_model_path):
“”"
Initialize the Detection and Segmentation models

:param: 
        model (str): model path *.pdmodel
:retuns:
        detector: detection compiled model
        segmenter: segmentation compiled model 

"""
if not osp.exists(det_model_path):
    raise Exception("Model path {} does not exist".format(det_model_path))
if not osp.exists(seg_model_path):
    raise Exception("Model path {} does not exist".format(seg_model_path))

# Load the PaddlePaddle detection model directly
det_model = ie_core.read_model(model=det_model_path)
det_model.reshape({'image': [1, 3, 608, 608], 'im_shape': [1, 2], 'scale_factor': [1, 2]})
detector = ie_core.compile_model(model=det_model, device_name="CPU")

# Load the PaddlePaddle segmentation model directly, the input batch size is dynamic
seg_model = ie_core.read_model(model=seg_model_path)
seg_model.reshape({'image': [-1, 3, 512, 512]})
segmenter = ie_core.compile_model(model=seg_model, device_name="CPU")

return detector, segmenter

5.3.4 定义预测器
定义检测网络和分割网络的通用预测器

In [ ]
def predictor(input, compiled_model):
“”"
A predictor to run inference

:param: 
        input: input data
        compiled_model: a IE detector or segmenter
:retuns:
        result (np.array): model output data

"""
output_layer = compiled_model.output(0)
result = compiled_model(input)[output_layer]
return result

5.3.5 定义数据处理模块
为每一个推理任务定义数据的前后处理模块

In [ ]
def det_preprocess(input_image, target_size):
“”"
Pre-proccesing the input data for detection task

:param: 
        input_image (np.array): input data
        size (int): the image size required by model input layer
:retuns:
        img.astype (np.float32): preprocessed image

"""
img = cv2.resize(input_image, (target_size, target_size))
img = np.transpose(img, [2, 0, 1]) / 255
img = np.expand_dims(img, 0)
img_mean = np.array([0.485, 0.456,0.406]).reshape((3, 1, 1))
img_std = np.array([0.229, 0.224, 0.225]).reshape((3, 1, 1))
img -= img_mean
img /= img_std
return img.astype(np.float32)

def segmentation_map_to_image(result, colormap, remove_holes = False) :
“”"
Convert network result of floating point numbers to an RGB image with
integer values from 0-255 by applying a colormap.

:param result: A single network result after converting to pixel values in H,W or 1,H,W shape.
:param colormap: A numpy array of shape (num_classes, 3) with an RGB value per class.
:param remove_holes: If True, remove holes in the segmentation result.
:return: An RGB image where each pixel is an int8 value according to colormap.
"""
if len(result.shape) != 2 and result.shape[0] != 1:
    raise ValueError(
        f"Expected result with shape (H,W) or (1,H,W), got result with shape {result.shape}"
    )

if len(np.unique(result)) > colormap.shape[0]:
    raise ValueError(
        f"Expected max {colormap[0]} classes in result, got {len(np.unique(result))} "
        "different output values. Please make sure to convert the network output to "
        "pixel values before calling this function."
    )
elif result.shape[0] == 1:
    result = result.squeeze(0)

result = result.astype(np.uint8)

contour_mode = cv2.RETR_EXTERNAL if remove_holes else cv2.RETR_TREE
mask = np.zeros((result.shape[0], result.shape[1], 3), dtype=np.uint8)
for label_index, color in enumerate(colormap):
    label_index_map = result == label_index
    label_index_map = label_index_map.astype(np.uint8) * 255
    contours, hierarchies = cv2.findContours(
        label_index_map, contour_mode, cv2.CHAIN_APPROX_SIMPLE
    )
    cv2.drawContours(
        mask,
        contours,
        contourIdx=-1,
        color=color.tolist(),
        thickness=cv2.FILLED,
    )

return mask

def filter_bboxes(det_results, score_threshold):
“”"
filter out the detection results with low confidence

:param:
    det_results (list[dict]): detection results
    score_threshold (float): confidence threshold

:retuns:
    filtered_results (list[dict]): filter detection results

"""
filtered_results = []
for i in range(len(det_results)):
    if det_results[i, 1] > score_threshold:
        filtered_results.append(det_results[i])
return filtered_results

def roi_crop(image, results, scale_x, scale_y):
“”"
crop the area of detected meter of orignal image

:param:
    img (np.array):original image。
    det_results (list[dict]): detection results
    scale_x (float): the scale value in x axis
    scale_y (float): the scale value in y axis

:retuns:
    roi_imgs (list[np.array]): the list of meter images
    loc (list[int]): the list of meter locations

"""
roi_imgs = []
loc = []
for result in results:
    bbox = result[2:]
    xmin, ymin, xmax, ymax = [int(bbox[0] * scale_x), int(bbox[1] * scale_y), int(bbox[2] * scale_x), int(bbox[3] * scale_y)]
    sub_img = image[ymin:(ymax + 1), xmin:(xmax + 1), :]
    roi_imgs.append(sub_img)
    loc.append([xmin, ymin, xmax, ymax])
return roi_imgs, loc

def seg_preprocess(input_images, target_size, interp=cv2.INTER_LINEAR):
“”"
Pre-proccesing the input data for segmentation task

:param:
    input_images (list[np.array]):the list of meter images
    target_size (list|tuple): height and width of resized image, e.g [heigh,width]
    interp (int):the interp method for image reszing

:retuns:
    img_list (list[np.array]):the list of processed images
    resize_img (list[np.array]): for visualization

"""
img_list = list()
resize_list = list()
for img in input_images:
    img_shape = img.shape
    scale_x = float(target_size[1]) / float(img_shape[1])
    scale_y = float(target_size[0]) / float(img_shape[0])
    resize_img = cv2.resize(
        img, None, None, fx=scale_x, fy=scale_y, interpolation=interp)
    resize_list.append(resize_img)
    resize_img = resize_img.transpose(2, 0, 1) / 255
    img_mean = np.array([0.5, 0.5, 0.5]).reshape((3, 1, 1))
    img_std = np.array([0.5, 0.5, 0.5]).reshape((3, 1, 1))
    resize_img -= img_mean
    resize_img /= img_std
    img_list.append(resize_img)
return img_list, resize_list

def erode(seg_results, erode_kernel):
“”"
erode the segmentation result to get the more clear instance of poiner and scale

:param:
    seg_results (list[dict]):segmentation results
    erode_kernel (int): size of erode_kernel

:return:
    eroded_results (list[dict]): the lab map of eroded_results
"""
kernel = np.ones((erode_kernel, erode_kernel), np.uint8)
eroded_results = seg_results
for i in range(len(seg_results)):
    eroded_results[i] = cv2.erode(
        seg_results[i].astype(np.uint8), kernel)
return eroded_results

def circle_to_rectangle(seg_results):
“”"
switch the shape of label_map from circle to rectangle

:param:
    seg_results (list[dict]):segmentation results

:return:
    rectangle_meters (list[np.array]):the rectangle of label map

"""
rectangle_meters = list()
for i, seg_result in enumerate(seg_results):
    label_map = seg_result

    # The size of rectangle_meter is determined by RECTANGLE_HEIGHT and RECTANGLE_WIDTH
    rectangle_meter = np.zeros(
        (RECTANGLE_HEIGHT, RECTANGLE_WIDTH), dtype=np.uint8)
    for row in range(RECTANGLE_HEIGHT):
        for col in range(RECTANGLE_WIDTH):
            theta = PI * 2 * (col + 1) / RECTANGLE_WIDTH
            
            # The radius of meter circle will be mapped to the height of rectangle
            rho = CIRCLE_RADIUS - row - 1
            y = int(CIRCLE_CENTER[0] + rho * math.cos(theta) + 0.5)
            x = int(CIRCLE_CENTER[1] - rho * math.sin(theta) + 0.5)
            rectangle_meter[row, col] = label_map[y, x]
    rectangle_meters.append(rectangle_meter)
return rectangle_meters

def rectangle_to_line(rectangle_meters):
“”"
switch the dimension of rectangle label map from 2D to 1D

:param:
    rectangle_meters (list[np.array]):2D rectangle OF label_map。

:return:
    line_scales (list[np.array]): the list of scales value
    line_pointers (list[np.array]):the list of pointers value

"""
line_scales = list()
line_pointers = list()
for rectangle_meter in rectangle_meters:
    height, width = rectangle_meter.shape[0:2]
    line_scale = np.zeros((width), dtype=np.uint8)
    line_pointer = np.zeros((width), dtype=np.uint8)
    for col in range(width):
        for row in range(height):
            if rectangle_meter[row, col] == SEG_CNAME2CLSID['pointer']:
                line_pointer[col] += 1
            elif rectangle_meter[row, col] == SEG_CNAME2CLSID['scale']:
                line_scale[col] += 1
    line_scales.append(line_scale)
    line_pointers.append(line_pointer)
return line_scales, line_pointers

def mean_binarization(data_list):
“”"
binarize the data

:param:
    data_list (list[np.array]):input data

:return:
    binaried_data_list (list[np.array]):output data。

"""
batch_size = len(data_list)
binaried_data_list = data_list
for i in range(batch_size):
    mean_data = np.mean(data_list[i])
    width = data_list[i].shape[0]
    for col in range(width):
        if data_list[i][col] < mean_data:
            binaried_data_list[i][col] = 0
        else:
            binaried_data_list[i][col] = 1
return binaried_data_list

def locate_scale(line_scales):
“”"
find out the location of center of each scale

:param:
    line_scales (list[np.array]):the list of binaried scales value

:return:
    scale_locations (list[list]):location of each scale

"""
batch_size = len(line_scales)
scale_locations = list()
for i in range(batch_size):
    line_scale = line_scales[i]
    width = line_scale.shape[0]
    find_start = False
    one_scale_start = 0
    one_scale_end = 0
    locations = list()
    for j in range(width - 1):
        if line_scale[j] > 0 and line_scale[j + 1] > 0:
            if not find_start:
                one_scale_start = j
                find_start = True
        if find_start:
            if line_scale[j] == 0 and line_scale[j + 1] == 0:
                one_scale_end = j - 1
                one_scale_location = (
                    one_scale_start + one_scale_end) / 2
                locations.append(one_scale_location)
                one_scale_start = 0
                one_scale_end = 0
                find_start = False
    scale_locations.append(locations)
return scale_locations

def locate_pointer(line_pointers):
“”"
find out the location of center of pointer

:param:
    line_scales (list[np.array]):the list of binaried pointer value

:return:
    scale_locations (list[list]):location of pointer

"""
batch_size = len(line_pointers)
pointer_locations = list()
for i in range(batch_size):
    line_pointer = line_pointers[i]
    find_start = False
    pointer_start = 0
    pointer_end = 0
    location = 0
    width = line_pointer.shape[0]
    for j in range(width - 1):
        if line_pointer[j] > 0 and line_pointer[j + 1] > 0:
            if not find_start:
                pointer_start = j
                find_start = True
        if find_start:
            if line_pointer[j] == 0 and line_pointer[j + 1] == 0 :
                pointer_end = j - 1
                location = (pointer_start + pointer_end) / 2
                find_start = False
                break
    pointer_locations.append(location)
return pointer_locations

def get_relative_location(scale_locations, pointer_locations):
“”"
match the location of pointer and scales

:param:
    scale_locations (list[list]):location of each scale
    pointer_locations (list[list]):location of pointer

:return:
    pointed_scales (list[dict]): a list of dict with:
                                 'num_scales': total number of scales
                                 'pointed_scale': predicted number of scales
        
"""
pointed_scales = list()
for scale_location, pointer_location in zip(scale_locations,
                                            pointer_locations):
    num_scales = len(scale_location)
    pointed_scale = -1
    if num_scales > 0:
        for i in range(num_scales - 1):
            if scale_location[
                    i] <= pointer_location and pointer_location < scale_location[
                        i + 1]:
                pointed_scale = i + (
                    pointer_location - scale_location[i]
                ) / (scale_location[i + 1] - scale_location[i] + 1e-05
                        ) + 1
    result = {'num_scales': num_scales, 'pointed_scale': pointed_scale}
    pointed_scales.append(result)
return pointed_scales

def calculate_reading(pointed_scales):
“”"
calculate the value of meter according the type of meter

:param:
    pointed_scales (list[list]):predicted number of scales

:return:
    readings (list[float]): the list of values read from meter
        
"""
readings = list()
batch_size = len(pointed_scales)
for i in range(batch_size):
    pointed_scale = pointed_scales[i]
    # find out the type of meter according the total number of scales
    if pointed_scale['num_scales'] > TYPE_THRESHOLD:
        reading = pointed_scale['pointed_scale'] * METER_CONFIG[0][
            'scale_interval_value']
    else:
        reading = pointed_scale['pointed_scale'] * METER_CONFIG[1][
            'scale_interval_value']
    readings.append(reading)
return readings

5.3.6 主函数
基于OpenVINO进行模型部署推理,并通过OpenCV的传统CV方法计算表计实际读数

In [ ]
def meter_reader(
img_file=“image/meter.jpg”,
det_model_path=“model/meter_det_model/model.pdmodel”,
seg_model_path=“model/meter_seg_model/model.pdmodel”,
erode_kernel=4,
score_threshold=0.5,
seg_batch_size=2
):
“”"
Main function of meter reader

:param: img_file (string): path of test image
        det_model_path (string): path of Paddle detection model
        seg_model_path (string): path of Paddle segmentation model
        erode_kernel (int): kernel size of OpenCV erode function
        score_threshold (float): threshold to filter out the detection box with low confidence
        seg_batch_size (int): input batch size of segmentation model
:retuns:
        image (np.array): original input image
        roi_imgs (list[np.array]): the list meter images detected
        mask (np.array): a segmented meter image
        result_image (np.array): result image show the value read from the meter

"""
detector, segmenter = model_init(det_model_path, seg_model_path)

# Prepare the input data for meter detection model
image = cv2.imread(img_file)
im_shape = np.array([[608, 608]]).astype('float32')
scale_factor = np.array([[1, 2]]).astype('float32')
input_image = det_preprocess(image, 608)
inputs_dict = {'image': input_image, "im_shape": im_shape, "scale_factor": scale_factor}

# Run meter detection model
det_results = predictor(inputs_dict, detector)

# Filter out the bounding box with low confidence
filtered_results = filter_bboxes(det_results, score_threshold)

# Prepare the input data for meter segmentation model
scale_x = image.shape[1] / 608 * 2
scale_y = image.shape[0] / 608

# Create the individual photo for each detected meter
roi_imgs, loc = roi_crop(image, filtered_results, scale_x, scale_y)
roi_imgs, resize_imgs = seg_preprocess(roi_imgs, METER_SHAPE)
seg_results = list()
num_imgs = len(roi_imgs)

# Run meter segmentation model on all meters detected
for i in range(0, num_imgs, seg_batch_size):
    batch = roi_imgs[i : min(num_imgs, i + seg_batch_size)]
    seg_result = predictor([batch], segmenter)
    seg_results.extend(seg_result)
results = []
for i in range(len(seg_results)):
    results.append(np.argmax(seg_results[i], axis=0)) 
    #results.append(seg_results[i]) 可以根据模型的实际输出shape做调整
seg_results = erode(results, erode_kernel)

# Find out the pointer location in scale map and calculate the meters reading 
rectangle_meters = circle_to_rectangle(results)
line_scales, line_pointers = rectangle_to_line(rectangle_meters)
binaried_scales = mean_binarization(line_scales)
binaried_pointers = mean_binarization(line_pointers)
scale_locations = locate_scale(binaried_scales)
pointer_locations = locate_pointer(binaried_pointers)
pointed_scales = get_relative_location(scale_locations, pointer_locations)
meter_readings = calculate_reading(pointed_scales)
for i in range(len(meter_readings)):
    print("Meter {}: {}".format(i + 1, meter_readings[i]))

# Create the photos of detection and segmentation results
if len(resize_imgs) == 2:
    roi_stack = np.hstack([resize_imgs[0], resize_imgs[1]])
    mask_stack = np.hstack([segmentation_map_to_image(seg_results[0], COLORMAP), 
                            segmentation_map_to_image(seg_results[1], COLORMAP)])
else:
    roi_stack = resize_imgs[0]
    mask_stack = segmentation_map_to_image(seg_results[0], COLORMAP)

# Create final result photo with meter value
result_image = image.copy()
for i in range(len(loc)):
    cv2.rectangle(result_image,(loc[i][0], loc[i][1]), (loc[i][2], loc[i][3]), (0, 150, 0), 3)
    font = cv2.FONT_HERSHEY_SIMPLEX
    cv2.rectangle(result_image, (loc[i][0], loc[i][1]), (loc[i][0] + 100, loc[i][1] + 40), (0, 150, 0), -1)
    cv2.putText(result_image, "#{:.3f}".format(meter_readings[i]), (loc[i][0],loc[i][1] + 25), font, 0.8, (255, 255, 255), 2, cv2.LINE_AA)

return image, roi_stack, mask_stack, result_image

5.3.8 结果展示
展示每一个模型预测阶段的输入和输出图片

In [ ]

Run meter_reader to get the meter photo in different inference step

image, roi, mask, result_image = meter_reader()
data = {“Base Photo”: image, “Detection”: roi, “Segmentation”: mask, “Result Photo”: result_image}

Create subplot to visualize images

fig, axs = plt.subplots(1, len(data.items()), figsize=(60, 40))

Fill subplot

for ax, (name, image) in zip(axs, data.items()):
ax.axis(‘off’)
ax.set_title(name, fontsize=32)
ax.imshow(image)

Display image

plt.savefig(‘workflow.png’)
if (cv2.imwrite(“result_image.jpg”, result_image)):
print(“The result image has been saved as “result_image.jpg””)
最终效果如图所示:
代码执行后,会分别在本地存储两张图片,result_image.jpg用于展示最后的读数结果,workflow.png则会记录识别过程中每一个步骤的模型结果输出。

在这里插入图片描述
读数效果
在这里插入图片描述

识别过程

更多基于OpenVINO的示例代码可以查阅:OpenVINO notebook

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐