【第3天】资料前处理-YOLOv4与自动框选中文字

现况

  1. 观察主办单位提供的资料集(约7万张图档),发现图档大致分为下列几种。
    1.1 图档内只有1个中文字

    1.2 图档内中文字有其他字迹或只有半个字

    1.3 图档内含2个以上中文字

    1.4 图档内无文字(仅有空白背景)

  2. 为了分类上述图档,决定采用one-stage物件侦测演算法-YOLOv4,小量抽样建模後,自动框选中文字。

  3. 此次抽样建模的资料集较小(3000张),适合部署到Colab上以免费GPU训练。若资料集过大,不建议以Colab训练模型,曾经遇到VMware硬碟空间不足、上传资料时间过久、模型训练到一半Colab断线或提示GPU用量额满的惨痛经验。


工具/套件

  1. LabelImg
  2. YOLOv4
  3. Google Colab

内容

  1. LabelImg

    1.1 Windows环境-安装与执行

    • <方法一> 以Python执行

      ※注:详细步骤或其他环境的安装,可参考官方文件

    • <方法二> 以EXE档执行
      官方I/O下载解压缩後,即可执行。

    1.2 操作过程

    • 执行LabelImg後,分别点选Open Dir与Change Save Dir,设定训练集图档路径及标记Annotations(XML档)的储存路径。

    • 勾选选单中View的Auto Save

    • 框选中文字体(Bounding box),并标记为word (快捷键:W拉框框、D下一张、A上一张)

    • 每标记完一张图档 都会产出一个对应的XML档案(切记!档名尽量不要使用中文字)

  2. YOLOv4部署到Colab训练

    2.1 在Colab上训练YOLOv4,可以避免Windows+YOlOv4,在呼叫本地端GPU时出现异常。若有Windows+YOlOv4的稳定训练方法,也欢迎大家留言告诉我。

    2.2 事前准备

    • 按此下载 train.rar,并解压缩成train资料夹。

    • 将资料集(3000张)放进train下的\VOCdevkit\VOC2021\JPEGImages

    • 将LabelImg标记产生的XML档(3000个),放进train底下\VOCdevkit\VOC2021\Annotations

    • 执行train资料夹中的gen_train_val.py,将资料集以8:2比例分配train与val。

    import os, random
    from os.path import join, splitext
    
    base = 'VOC2021'
    source = join('VOCdevkit',base, 'JPEGImages/')
    train_txt = join('VOCdevkit',base, 'ImageSets/Main/train.txt')
    val_txt = join('VOCdevkit',base, 'ImageSets/Main/val.txt')
    
    files = os.listdir(source)
    random.shuffle(files)
    
    f_train = open(train_txt,'a')
    f_val = open(val_txt,'a')
    
    for i, file in enumerate(files):
        name = splitext(file)[0]
        if (i >=len(files)*0.2):
            f_train.write(name+'\n')
        else:
            f_val.write(name+'\n')
    
    f_train.close()
    f_val.close()
    
    • 执行gen_train_val.py後,得到train.txt与val.txt

    • train资料夹中voc_label.py,用於YOLOv4训练模型前的datasets预处理(标记Train / Test/Val资料集),将在部署到Colab之後执行。

      ※注:如果想增加YOLOv4辨识的标签种类(classes),需修改train资料夹中档案的参数设定,请参阅下图。

    • 接下来是将整个train资料夹压缩成train3.zip

    2.3 部署到Colab训练:最後一步是将train3.zip上传到Colab训练,完成模型训练後,压缩成train3_finished.tar.gz,再下载到本地端。考量到篇幅过长,详细过程请参阅我的Github

  3. 模型成效
    3.1 将train3_finished.tar.gz解压缩後,train资料夹中predit.py,执行後可自动框选中文字。

    import cv2
    import numpy as np
    import os
    
    #读取模型与训练权重
    def initNet():
        CONFIG = 'yolov4-tiny-myobj.cfg'
        WEIGHT = 'yolov4-tiny-myobj_last.weights'
        net = cv2.dnn.readNet(CONFIG,WEIGHT)
        model = cv2.dnn_DetectionModel(net)
        model.setInputParams(size=(416, 416), scale=1/255.0)
        model.setInputSwapRB(True)
        return model
    
    #物件侦测
    def nnProcess(image, model):
        classes, confs, boxes = model.detect(image, 0.4, 0.1)
        return classes, confs, boxes
    
    #框选侦测到的物件
    def drawBox(image, classes, confs, boxes):
        new_image = image.copy()
        for (classid, conf, box) in zip(classes, confs,boxes):
         x, y, w, h = box
            if x - 2 < 0:
                x = 2
            if y - 2 < 0:
                y = 2
            cv2.rectangle(new_image, (x - 2, y - 2), (x + w + 2, y + h + 2), (0, 255, 0), 2)
        return new_image
    
    if __name__ == '__main__':
        # 主办单位提供的资料集(约7万张)
        source = './01_origin/'
        files = os.listdir(source)
        # 依照正整数排序
        files.sort(key=lambda x:int(x[:-6]))
        model = initNet()
        for file in files:
            img = cv2.imdecode(np.fromfile(source+file,dtype=np.uint8), -1)
            classes, confs, boxes = nnProcess(img, model)
            try:
                frame = drawBox(img, classes, confs, boxes)
                frame = cv2.resize(frame, (240, 200), interpolation=cv2.INTER_CUBIC)
                # 显示框选後的图片
                cv2.imshow('img', frame)
                cv2.waitKey()
            except:
                continue
        print('程序执行完毕')
    

    3.2 框选中文字效果

    • 图档内只有1个中文字

    • 图档内中文字有其他字迹或只有半个字

    • 图档内含2个以上中文字

    • 图档内无文字(仅有空白背景)


小结

  1. 从3.2的结果得知,训练後的YOLOv4模型,可以正确地框选出中文字。唯一美中不足的地方,大概是「体」被模型当成2个字框选。

  2. 承上,推测可能是小量抽样(3000张)中,「体」这种情况的样本出现频率较低。增加抽样数量、重新训练模型後,应该可改善框选表现。

  3. 考量到:「正式比赛时,每张图档内只会有一个最正确的中文字」。因此,下一章的目标是:「从7万张图档中,取出YOLOv4模型框选为1个中文字的图档,再将物件侦测框(绿色边界框)内的中文字裁切、另存图档,做为新的资料集」。

让我们继续看下去...


参考资料

  1. LabelImg详细说明-tzutalin
  2. YOLOv4详细说明-AlexeyAB

<<:  菜鸡的机器学习入门

>>:  [Day3]Rock pi 4「扑街」学到的教训 (°Д°)╯╯︵┴┴

[Day1][笔记] 主题规划

前言 其实 React 众观这几届其实已经有很多大神写过文章,那为何我还要出来写呢?其实就是两个目的...

[Day30] GCP云端部属说明(前後端)

How - 部属MongoDB 登入以下网址 https://www.mongodb.com/clo...

[Day 12] 资料产品生命周期管理-加工资料(一)

加工资料泛指各种处理资料的行为,这部分要一篇文章写完真滴难,所以就也只能蜻蜓点水的各介绍一点,让大家...

Day17 Grafana (gRPC, Go Processes, Redis)

昨天已经介绍过,透过 grafana 监控 matching 的品质 ,今天来介绍一下,透过 gra...

[Day19] Flutter with GetX something else

这篇主要讲GetX所提供, 自己有接触过的额外功能 为大家介绍 多国语系, 萤幕长宽, snackb...