序言
本文主要介绍一个仪表数据生成思路和python程序,主要用于仪表识别中图像数据量过少,不能支撑数据集制作和编程的情况。如下图,一种仪表数据可能只有几十张甚至几张相应图像。可以通过本文程序进行生成相应数据,进行数据的扩充。也可以对图像进行旋转、对比度增强、裁切、增加噪点、模糊等提升数据集的多样性,本文未作相关工作。
最终生成效果如下:
1.准备工作
需要准备一张透明指针图像和一张无指针的表盘图像,操作步骤如下:
1.1 指针图像
可以通过PS实现(当然也可以通过AI绘画工具进行生成,不过效果可能不佳),大致实现步骤如下:
(1)通过PS选择工具选择出指针
(2)利用Ctrl+C复制选择的指针,并选择指针图层,取消勾选背景图层
(3)在工具栏选择裁切,并继续选择基于透明像素
然后保存图像(必须为png格式,jpg不支持透明背景),即可得到相应指针图像。
1.2 无指针的表盘图像
(1)将表盘指针涂掉,选择仿制图章工具,按住Alt并鼠标左键点击表盘黑色部分,然后松开Alt,用鼠标涂抹指针位置,指针就消失了。
(2)制作刻度,选择矩形选框工具,框选刻度,使用Ctrl+C复制,使用Ctrl+T选择刻度并拖动到相应位置,进行旋转调整,0刻度的方法同上,就得到了表盘图像。
2 生成指针旋转图像
程序运行步骤如下:
(1)读取表盘图像和指针图像
(2)旋转指针图像,得到指针不同角度的图像
(3)将旋转的指针和表盘进行合并,得到生成表盘图像
(4)循环以上步骤
主程序如下所示,注释比较详细,不再赘述。
import math
import os
from PIL import Image
def rote(img_path, temp_path, level, output, exclude, R=18):
"""
生成表指针数据
Args:
img_path: 表盘图像(无指针)
temp_path: 指针图像
level: 间隔
output: 保存文件夹
exclude: 排除角度(左边为0度,逆时针旋转)[开始角度, 结束角度]
R: 表中心圆陀陀半径,如无则填 0
Returns:
"""
os.makedirs('output', exist_ok=True)
n = 0
if len(exclude) == 2:
exclude_ = range(exclude[0], exclude[1], 1)
else:
exclude_ = []
for i in range(0, 360, level):
if i in exclude_:
continue
try:
# 表盘图像
bg = Image.open(img_path)
# 指针图像
temp = Image.open(temp_path).convert('RGBA')
# 旋转指针图像
r_image = temp.rotate(i, resample=Image.BICUBIC, expand=True)
x, y = int(bg.width / 2 - R * math.cos(i / 180 * math.pi)), int(bg.height / 2 + R * math.sin(i / 180 * math.pi))
if i < 90:
x1, y1 = x - r_image.width, y
x2, y2 = x, y + r_image.height
elif 90 < i < 180:
x1, y1 = x, y
x2, y2 = x + r_image.width, y + r_image.height
elif 180 < i < 270:
x1, y1 = x, y - r_image.height
x2, y2 = x + r_image.width, y
else:
x1, y1 = x - r_image.width, y - r_image.height
x2, y2 = x, y
# x1,y1 为头像左上角的位置
# x2,y2 为头像右下角的位置
# 将图片设置为我们需要的大小
r_image = r_image.resize((x2-x1, y2-y1))
bg.paste(r_image, (x1, y1, x2, y2), r_image)
# 保存图片
bg.save(f'{output}/r_img_{i}.png')
n += 1
print(f'正在生成旋转角度为{i+1}的图像')
except Exception as e:
print(f'旋转角度为{i+1}的图像生成失败,原因:{e}')
print(f'----------------------------')
print(f'共生成图像{n}张,保存于:{output}')
if __name__ == '__main__':
img_path = 'image/image.png'
temp_path = 'image/temp.png'
rote(img_path, temp_path, level=2, output='output', exclude=[30, 155], R=18)
3 生成效果
生成效果图如下,效果还是很棒的