零基础入门CV(一)

Task1 赛题理解

本章节主要对赛题背景以及使用的数据进行讲解,并给出解题思路。
赛题链接:https://tianchi.aliyun.com/competition/entrance/531795/information

1、赛题背景

赛题以计算机视觉中字符识别为背景,预测真实场景下的字符识别,这是一个典型的字符识别问题。通过这道赛题可以引导大家走入计算机视觉的世界,上手视觉赛题,提高对数据建模能力。

2、赛题数据

赛题来源自Google街景图像中的门牌号数据集(The Street View House Numbers Dataset, SVHN),并根据一定方式采样得到比赛数据集。该数据来自真实场景的门牌号。训练集数据包括3W张照片,验证集数据包括1W张照片,每张照片包括颜色图像和对应的编码类别和具体位置。
零基础入门CV(一)_第1张图片
*数据集样本展示

2.1、数据标签

所有的数据(训练集、验证集和测试集)的标注使用JSON格式,并使用文件名进行索引。如果一个文件中包括多个字符,则使用列表将字段进行组合。
对于训练数据每张图片将给出对于的编码标签,和具体的字符框的位置(训练集、测试集和验证集都给出字符位置),可用于模型训练:

Field Description
top 左上角坐标X
height 字符高度
left 左上角坐标Y
width 字符宽度
label 字符编码

字符的坐标具体如下所示:
零基础入门CV(一)_第2张图片
注:数据集来源自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标注中,会有两个字符的边框信息:
原始图片 图片JSON标注
零基础入门CV(一)_第3张图片 零基础入门CV(一)_第4张图片

3、评测标准

评价标准为准确率,结果与实际图片的编码进行对比,以编码整体识别准确率为评价指标,结果越大越好,具体计算公式如下:
s c o r e = 编 码 识 别 正 确 的 数 量 测 试 集 图 片 数 量 score=\frac{编码识别正确的数量}{测试集图片数量} score=

4、下载数据

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 )

5、读取数据

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
零基础入门CV(一)_第5张图片 零基础入门CV(一)_第6张图片 零基础入门CV(一)_第7张图片

6、解题思路

本质是分类问题,需要对图片的字符进行识别。但给定的数据图片中不同图片中包含的字符数量不等,如下图所示。有的图片的字符个数为2,有的图片字符个数为3,有的图片字符个数为4。

字符属性 图片
字符:42 字符个数:2 零基础入门CV(一)_第8张图片
字符:241 字符个数:3 零基础入门CV(一)_第9张图片
字符:7358 字符个数:4 零基础入门CV(一)_第10张图片

本次赛题的难点是需要对不定长的字符进行识别。我们提供了一些解题思路供大家参考:

  1. 简单入门思路:定长字符识别
    可以将赛题抽象为一个定长字符识别问题,在数据集中大部分图像中字符个数为2-4个,最多的字符个数为6个。因此可以将所有的图像都抽象为6个字符的识别问题,字符23填充为23XXXX,字符231填充为231XXX。
    零基础入门CV(一)_第11张图片
    经过填充之后,原始赛题简化为6个字符的分类问题。在每个字符的分类中会进行11个类别的分类,假如分类为填充字符,则表明该字符为空。
  2. 专业字符识别思路:不定长字符识别
    零基础入门CV(一)_第12张图片
    在字符识别研究中,有特定的方法来解决此种不定长的字符识别问题,比较典型的有CRNN字符识别模型。本次赛题中给定的图像数据都比较规整,可以视为一个单词或者一个句子。
  3. 专业分类思路:检测再识别
    在赛题数据中已经给出了训练集、验证集中所有图片中字符的位置,因此可以首先将字符的位置进行识别,利用物体检测的思路完成。此种思路需要构建字符检测模型,对测试集中的字符进行识别。可以参考物体检测模型SSD或者YOLO来完成。
    零基础入门CV(一)_第13张图片

你可能感兴趣的:(零基础入门CV(一))