Datawhale零基础入门CV赛事(街景字符编码识别)-Task1 赛题理解

赛题理解:

  • 这个赛题是CV入门级赛题,通过街景字符识别来熟悉CV建模思路和竞赛流程。
  • 赛题任务:识别图片中的数字
  • 评测标准:准确率 s c o r e = 编 码 识 别 正 确 的 数 量 测 试 集 图 片 数 量 score = \frac{编码识别正确的数量}{测试集图片数量} score=
  • 结果提交:sample_submit.csv:提交结果需要保证预测结果的格式与其一致,以及提交文件后缀名为csv。

file_name, file_code
0010000.jpg,451
0010001.jpg,232
0010002.jpg,45
0010003.jpg,67
0010004.jpg,191
0010005.jpg,892

数据理解:

  • 数据获取地址
  • 赛题数据采用公开数据集SVHN,并且进行了匿名和降噪处理,减小了比赛的难度。
  • 训练集数据包括3W张照片,验证集数据包括1W张照片,每张照片包括颜色图像和对应的编码类别和具体位置;为了保证比赛的公平性,测试集A包括4W张照片,测试集B包括4W张照片。

mchar_test_a:4w张图片的测试集A
mchar_train:3w张图片的训练集
mchar_val:1w张图片的验证集
mchar_train.json:存放的是训练数据集的label数据;
mchar_val.json:存放的是验证数据集的label数据。
Datawhale零基础入门CV赛事(街景字符编码识别)-Task1 赛题理解_第1张图片

  • 可以发现有的图片中不止包含一个数字,相应的json文件中就包含了多个数字的位置信息
  • 以下是json文件中存储的内容,包含了样本集中各个图片对应的label以及位置等信息,相当于确定了图片中数字的边框,表示如下:
Field Description
top 左上角点到图片顶端的距离
height 字符高度
left 左上角点到图片左端的距离
width 字符宽度
label 字符编码
"000000.png": {"height": [30.0], "label": [5], "left": [43.0], "top": [7.0], "width": [19.0]}, 
"000001.png": {"height": [23, 23, 23], "label": [2, 1, 0], "left": [99, 114, 121], "top": [5, 8, 6], "width": [14, 8, 12]}, 
"000002.png": {"height": [16.0], "label": [6], "left": [61.0], "top": [6.0], "width": [11.0]}, 
"000003.png": {"height": [17.0], "label": [1], "left": [32.0], "top": [6.0], "width": [14.0]}, 
"000004.png": {"height": [28.0], "label": [9], "left": [97.0], "top": [28.0], "width": [19.0]}, 
"000005.png": {"height": [23.0], "label": [1], "left": [40.0], "top": [11.0], "width": [7.0]}, 
"000006.png": {"height": [21, 21, 21], "label": [1, 8, 3], "left": [44, 51, 62], "top": [7, 6, 6], "width": [9, 11, 10]}, "000007.png": {"height": [23, 23], "label": [6, 5], "left": [62, 80], "top": [16, 17], "width": [14, 14]}

Datawhale零基础入门CV赛事(街景字符编码识别)-Task1 赛题理解_第2张图片
如图000000.png:
000000.png
以下是官方给的示例:
Datawhale零基础入门CV赛事(街景字符编码识别)-Task1 赛题理解_第3张图片

数据读取:

json格式的label数据以及图片读取:

import matplotlib.pyplot as plt
import json
import numpy as np
import cv2
# 读取json文件---》json包读取
train_json = json.load(open('C:/Users/Administrator/Downloads/CVdataset/train.json'))

# 数据标注处理
def parse_json(d):
   arr = np.array([
       d['top'], d['height'], d['left'],  d['width'], d['label']
   ])
   arr = arr.astype(int) # 强制转换类型为int
   return arr

# CV2读取图片,返回类型:ndarray:(height,width,channels)
img = cv2.imread('C:/Users/Administrator/Downloads/CVdataset/test/000000.png') 
arr = parse_json(train_json['000000.png'])

plt.figure(figsize=(10, 10)) # 创建画布
# 显示原图的子图,subplot表示将位置划分为1*4的子图,该子图占第一个位置;arr.shape[1] = 1表示图中有一个数字
plt.subplot(1, arr.shape[1]+1, 1) 
plt.imshow(img) # 展示原图,imshow的参数就是img矩阵
plt.xticks([]); plt.yticks([]) # 不显示坐标

for idx in range(arr.shape[1]): 
   plt.subplot(1, arr.shape[1]+1, idx+2) # 为图片中的数字创建画布子图
   # 通过arr中标注好的数字的位置,将img切片并展示为图片形式。相当于是img[top:top+height, left:left+width]
   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([])

此处读取了第2张图片,有三个数字,所以代码中arr.shape = (5,3)

# arr的结果:分别表示top、height、left、width、label
[[ 7]
 [30]
 [43]
 [19]
 [ 5]]
# img.shape的结果:height=47 width=99 channels=3
(47, 99, 3)

cv2.imread(path,读取方式):读取方式分为:cv2.IMREAD_COLOR:读入一副彩色图片;cv2.IMREAD_GRAYSCALE:以灰度模式读入图片;cv2.IMREAD_UNCHANGED:读入一幅图片,并包括其alpha通道。
返回值:(height,width,channels),其类型是numpy.ndarray。参考
图片展示结果如下:
Datawhale零基础入门CV赛事(街景字符编码识别)-Task1 赛题理解_第4张图片

解题思路:

Datawhale零基础入门CV赛事(街景字符编码识别)-Task1 赛题理解_第5张图片
观察上图,可以发现,在给定数字位置之后,类似于MINIST数据集,是对图片中的数字进行识别;与之不同的是,该图片中可能不止有一个数字,因此可以将赛题理解为是一个不定长字符识别的问题。
参考datawhale提供的思路如下:

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

环境配置

基本流程和赛题大概了解之后,就需要配置相应的环境了,本次使用OpenCV和pytorch进行学习。首先,我安装了anaconda集成环境,在anaconda中本来可以直接install需要的包,但是有时候得看运气,这次我的安装路程就非常艰辛;网上也有用conda和pip安装的方法,最终我通过pytorch官网上生成的命令安装成功。我的安装简记

相应的小知识点

关于matplotlib学习:subplot创建子画布

import matplotlib.pyplot as plt
import numpy as np

def f(t):
    return np.exp(-t) * np.cos(2 * np.pi * t)

if __name__ == '__main__' :
    t1 = np.arange(0, 5, 0.1)
    t2 = np.arange(0, 5, 0.02)

    plt.figure(12)
    plt.subplot(221)
    plt.plot(t1, f(t1), 'bo', t2, f(t2), 'r--')

    plt.subplot(222)
    plt.plot(t2, np.cos(2 * np.pi * t2), 'r--')

    plt.subplot(212)
    plt.plot([1, 2, 3, 4], [1, 4, 9, 16])
    plt.xticks( np.arange(5), ('Tom', 'Dick', 'Harry', 'Sally', 'Sue') ) # 坐标定义

    plt.show()

Datawhale零基础入门CV赛事(街景字符编码识别)-Task1 赛题理解_第6张图片

你可能感兴趣的:(机器学习之路)