一、介绍
数据集示例:
分割gt示例:
数据集说明:
训练集生成字母混乱分布在图片上部1/4区域,测试集生成在下部1/4区域;
字母包含若干T,一个L,及一个E,一个F等。目标是L,做检测或分割任务。
二、思路
整个图像长宽相等,所以生成区域长宽比为4:1,当前总字母数为12,所以在生成区域划分2x8=16个正方形区域,从这16个区域中随机选出12个放置字母,且字母在该区域中的位置也是随机的。
这样既可以保证字母的分布足够随机,同时避免字母重叠严重。
正方形区域信息用数组保存,二维数组先依序记录每个正方形的左下角坐标,然后使用random.shuffle()
方法打乱正方形信息的顺序。
字母使用plt.text()
方法,参数可以确定字母的坐标,尺寸,旋转角度和颜色等。
三、填坑
坑点主要来自制作检测任务的gt时,笔者遇到以下问题:
(1)只有字母的起点坐标和fontsize,不知道字母的具体长宽
在搜索多次无果后准备放弃时,笔者通过谷歌pyplot text size pixel(重点是加上pixel),找到了有用的答案:
https://stackoverflow.com/questions/5320205/matplotlib-text-dimensions
f = plt.figure()
r = f.canvas.get_renderer()
t = plt.text(0.5, 0.5, 'test')
bb = t.get_window_extent(renderer=r)
width = bb.width
height = bb.height
绘图程序中没有使用这段代码,但是通过这段代码输出的 width 和 height,我们可以大致了解字母具体长宽与参数 fontsize 的关系。
(2)给定生成字母的起点坐标和旋转角度后,起点位置、旋转中心都很让人困惑:
经笔者分析,起点位置大约在字母的左下,而旋转中心经过分析在字母的中心偏右处。且每个字母似乎都不一样,幸好这里只需要确定L的规律。
因bounding box足够宽容,笔者不再区分字母中心和旋转中心,用起点坐标估算中心坐标,并经过不断调试得出合适的bounding box尺寸(直接借用fontsize):
center_x = place_means[0, 0] + fontsize * 0.9
center_y = place_means[0, 1] + fontsize * 0.3
center = [center_x, center_y]
x_t_l = center_x - fontsize * 0.8
y_t_l = center_y + fontsize * 0.8
x_b_r = center_x + fontsize * 0.8
y_b_r = center_y - fontsize * 0.8
x_t_r = center_x + fontsize * 0.8
y_t_r = center_y + fontsize * 0.8
x_b_l = center_x - fontsize * 0.8
y_b_l = center_y - fontsize * 0.8
最后,贴一下正方形网格划分代码:
# 2x8 网格
margin = 40
grid = (width - margin * 2) // 8
grid_list = []
for row in range(2):
if flag == 1:
grid_height = margin + grid * row
if flag == 0:
grid_height = margin + grid * ( row + 6)
for column in range(8):
grid_width = margin * 0 + grid * column # 不对称,左边不加margin反而更好
grid_list.append([grid_width,grid_height])
random.shuffle(grid_list)
以及字母生成代码:
# 生成字母坐标
place_means = []
margin = margin * 0.6
for i in range(n_cells):
rs = np.random.RandomState()
place_means1 = rs.uniform([grid_list[i][0] + margin, grid_list[i][1] + margin],
[grid_list[i][0] + grid - margin, grid_list[i][1] + grid-margin], size=(1, 2))
place_means.append(place_means1)
place_means = np.reshape(np.array(place_means), (-1, 2)).astype(np.int)
# 生成随机旋转角度
angle = []
for i in range(0, n_cells):
tmp = random.randint(0, 360)
angle.append(tmp)
# draw target letter L,F
for i in range(target_number):
ax.text(place_means[i, 0], place_means[i, 1], letter[i],
fontsize=fontsize, rotation=angle[0], color=letter_color)