本章节主要对赛题背景以及使用的数据进行讲解,并给出解题思路。
赛题链接:https://tianchi.aliyun.com/competition/entrance/531795/information
赛题以计算机视觉中字符识别为背景,预测真实场景下的字符识别,这是一个典型的字符识别问题。通过这道赛题可以引导大家走入计算机视觉的世界,上手视觉赛题,提高对数据建模能力。
赛题来源自Google街景图像中的门牌号数据集(The Street View House Numbers Dataset, SVHN),并根据一定方式采样得到比赛数据集。该数据来自真实场景的门牌号。训练集数据包括3W张照片,验证集数据包括1W张照片,每张照片包括颜色图像和对应的编码类别和具体位置。
*数据集样本展示
所有的数据(训练集、验证集和测试集)的标注使用JSON格式,并使用文件名进行索引。如果一个文件中包括多个字符,则使用列表将字段进行组合。
对于训练数据每张图片将给出对于的编码标签,和具体的字符框的位置(训练集、测试集和验证集都给出字符位置),可用于模型训练:
Field | Description |
---|---|
top | 左上角坐标X |
height | 字符高度 |
left | 左上角坐标Y |
width | 字符宽度 |
label | 字符编码 |
字符的坐标具体如下所示:
注:数据集来源自SVHN(http://ufldl.stanford.edu/housenumbers/)。一共五个文件,2个json文件,3个数据集的zip文件。分别为train.json, val.json, train.zip, val.zip, test_a.zip train为训练集,用于训练模型;val为验证集,用于验证模型的效果;test_a为最终测试集。
原始图片 | 图片JSON标注 |
---|---|
评价标准为准确率,结果与实际图片的编码进行对比,以编码整体识别准确率为评价指标,结果越大越好,具体计算公式如下:
s c o r e = 编 码 识 别 正 确 的 数 量 测 试 集 图 片 数 量 score=\frac{编码识别正确的数量}{测试集图片数量} score=测试集图片数量编码识别正确的数量
import pandas as pd
import requests
import zipfile
data=pd.read_csv('data/mchar_data_list_0515.csv')
output='./data/'
#下载数据
for i,file in enumerate(data['file']):
link=data['link'][i]
response = requests.get(link, stream=True)
with open( output+file, 'wb') as f:
for chunk in response.iter_content(chunk_size=1024):
f.write(chunk)
#解压数据
zip_list = ['mchar_train.zip', 'mchar_test_a.zip', 'mchar_val.zip']
for zips in zip_list:
zip_file = zipfile.ZipFile(output + zips , 'r')
zip_file.extractall(path = output )
import json
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 数据标注处理
def parse_json(d):
arr = np.array([
d['top'], d['height'], d['left'], d['width'], d['label']
])
arr = arr.astype(int)
return arr
inpass='./data/mchar_train/'
pic='000000.png'
#读取json
train_json = json.load(open('./data/mchar_train.json'))
#读取图片和标签
#img = cv2.imread(inpass + pic) #cv2.imread读取中文路径下的图像为空
img=cv2.imdecode(np.fromfile(inpass + pic,dtype=np.uint8),-1)
arr = parse_json(train_json[pic])
#plt.figure(figsize=(10, 10))
plt.subplot(1, arr.shape[1]+1, 1)
plt.imshow(img)
plt.xticks([]); plt.yticks([])
for idx in range(arr.shape[1]):# 多个标注字符
plt.subplot(1, arr.shape[1]+1, idx+2)
plt.imshow(img[arr[0, idx]:arr[0, idx]+arr[1, idx],arr[2, idx]:arr[2, idx]+arr[3, idx]])
plt.title(arr[4, idx])
plt.xticks([]); plt.yticks([])
plt.show()
结果:
000000.png | 000100.png | 001000.png |
---|---|---|
本质是分类问题,需要对图片的字符进行识别。但给定的数据图片中不同图片中包含的字符数量不等,如下图所示。有的图片的字符个数为2,有的图片字符个数为3,有的图片字符个数为4。
字符属性 | 图片 |
---|---|
字符:42 字符个数:2 | |
字符:241 字符个数:3 | |
字符:7358 字符个数:4 |
本次赛题的难点是需要对不定长的字符进行识别。我们提供了一些解题思路供大家参考: