OCR加正则实现读取健康码内容

OCR加正则实现读取健康码内容,第1张

目录

简介

导入OCR和re等库

读取当前文件所有截图的函数

正则部分

写入excel

执行结果

测试用例(室友的健康码):

 输出结果:


简介

这几天看到复旦博士做了这个项目,就寻思自己能不能做个这样的东西复刻下,结果没想到一中午还真的搞出来了

当然自己搞出来的由于测试用例不够多,可能有许多的bug

主要功能是读取健康码内的截图日期,上次接种日期,接种次数,接种日期和核酸检测结果,并在当前目录下生成一个excel文件并导入

以下为源码和注释

导入OCR和re等库
# author = 'L1Sta2'
# ver = 1.0
# name = '健康码信息提取'

import pytesseract # ocr库, 已经完成训练
from PIL import Image # 用于打开图片
import re
import os
import pandas as pd
# 提交健康码的时候需要用姓名命名
# 原因是由于健康码调整,去掉了显示自己身份z和姓名的功能(小眼睛没了)
# 功能是 将当前列表中的所有截图中信息提取 并在当前目录新建excel来保存结果

其中的pytesseract需要自己下载 并安装对应的语言包和配置环境变量

PIL 是用来读取照片的库

re是正则表达式库

os是系统库 这里用来判断当前目录和获取当前目录的所有图片

pandas库用来写入excel

读取当前文件所有截图的函数
def files_get() -> list:
    '''返回当前目录下所有的截图和姓名'''
    names = os.listdir(os.getcwd())
    pics = []
    users = []
    for file in names:
        if os.path.basename(file).endswith('.png'):
            # 找到后缀名为png的截图名称并保存到新列表
            user_name = file.replace('.png', '')
            pics.append(file)
            users.append(user_name)
    return pics, users

分别用os.getcwd和listdir读取了当前文件夹名称和当前文件夹内的文件

再用

os.path.basename(file).endswith('.png')

来得到所有png文件,当然有可能出现jpg文件,这里可以修改

然后读取文件名作为姓名, 这里要注意,提交照片的时候要修改照片名为学生姓名,因为从3月之后,根据国家规定,健康码当中的小眼睛不再可用,即健康码当中无法展示出个人姓名和身份z号,所以需要自行修改名称

正则部分
def ocr_scaning(pics, users) -> list:
    '''主循环,把当前列表所有的图片信息读取并转化为列表返回'''
    pytesseract.pytesseract.tesseract_cmd = 'C://Program Files (x86)/Tesseract-OCR/tesseract.exe'
    # 对ocr进行初始化
    ls_of_person = []
    for x, picture in enumerate(pics):
        image = Image.open(picture)
        what = pytesseract.image_to_string(image, lang='chi_sim')
        # 开始识别 设置语言为中文
        # 训练好的库需要自己下载
        name = users[x]
        # print(name, what)
        date_feature = re.compile(r"(\d{4}-\d{1,2}-\d{1,2})")
        match_lists = date_feature.findall(what)

        try:
            screen_date, test_date, vacine_date = match_lists[:]
            # 可能有人的没有完成
        except:
            screen_date, test_date = match_lists[:]
            vacine_date = "数据同步中"
            # 获取三个日期 截图日期 上次检测时间 接种时间
            # 部分人可能只有两个日期 因为非本省接种疫苗,所以会少第三个报错

        try:
            bool_vac = re.search(
                r"(阴?)(阳?) 性( ?)[0-9]", what.replace("E", "阴 性"))
            # 这个正则用于识别当前为阴性或者阳性 并找到接种次数
            bool_test_result = bool_vac.group().replace(" ", '')
            result, times = bool_test_result[:2], bool_test_result[-1] if 1 <= int(
                bool_test_result[-1]) <= 3 else 3
        except:
            if "阴" in what:
                result = '阴性'
                times = vacine_date
                # 部分人可能识别不到阴性 这个时候直接判断是否含有串
                # 当然也可以修改面的匹配,让[0-9]? 但是就需要匹配最后一个结果了

        ls_of_person.append([name, screen_date, test_date,
                            vacine_date, result, times])
    return ls_of_person

可以看到大多数的判断都用了try-excep语句,这是因为识别的精度其实并不是很高,不同的图片识别出来的格式不太一样,并且还有特殊情况

比如部分学生在省外接种的疫苗,就无法显示接种次数和时间

把所有的结果分别添加到列表中并返回二位列表

写入excel
def build_excel(ls_of_people) -> None:
    '''将数据保存到excel'''
    writer = pd.ExcelWriter('健康码.xlsx')
    # 当前文件夹新建文件
    data = pd.DataFrame(ls_of_people)
    data.columns = ['姓名', '截图日期', '核酸检测日期', '上次接种日期', '核酸结果', '疫苗接种次数']
    data.to_excel(writer, sheet_name='表格1')
    writer.save()
    print(data)

先将数据转化为dataframe格式,再对其添加列标

最后直接写入当前文件夹下 并打印一个表单出来看看结果

执行结果
if __name__ == '__main__':
    pics, users = files_get()
    ls_of_people = ocr_scaning(pics, users)
    build_excel(ls_of_people)

测试用例(室友的健康码):

 (直接上传健康码好像会违规 淦)

 

 输出结果:

最后一个同学由于接种都在省外,所以健康码上无数据

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/589761.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-13
下一篇 2022-04-13

发表评论

登录后才能评论

评论列表(0条)

保存