复旦博士使用代码快速搞定核酸统计,我复现并开源了!

科技   2022-04-18 09:00  

🔺点击上方第二个“负雪明烛”关注公众号

围观一个互联网职场人 + 知识分享博主的日常

经验 / 代码 / 提高效率
本文 2600 字,约需 6 分钟
前几天看到一个新闻:人工核查核酸报告太费事费力,复旦大学博士使用 130 行代码快速搞定核酸统计:800 幅核酸检测截图,只需要 2 分钟就能核对完成。
这是人民日报的报道:

新闻的背景是在当前疫情防控的需要下,复旦大学要求辅导员定期地、逐一检查所有学生的“健康码”中核酸检测报告,要求不遗漏一人。

01. 思路
对于这种需求,我有 3 种想法:
上策:个人可以授权指定机构查询自己的健康码与核酸检测结果,机构可以看到隶属于自己的所有用户的健康码状态、核酸检测结果、检测时间;
中策:所有个人给自己的“健康码”的核酸检测报告截图并上报,使用程序识别和检查;
下策:所有个人给自己的“健康码”的核酸检测报告截图并上报,人工核验。


毫无疑问,复旦大学的辅导员们最开始使用的是下策,靠人工核查。人工核查的缺点是慢、容易出错、而且还累
那有没有可能使用上策,通过授权、接口获取“健康云”的信息呢?这样获取的信息最准确,也不用麻烦所有学生天天截图了。
理论上只要“健康码”提供这样的功能、或开放相关接口就能实现。可实际上,考虑到信息安全等问题,现在是没有相关的功能或接口的
所以,复旦大学的博士使用了中策,使用程序校验每个学生截图。这种方法解放了校验时的人力,但是依然无法减少收集截图的辛苦

02. 主要技术
根据新闻中所说,博士使用的编程语言是 Python,技术是 OCR + 正则表达式


Python 是近几年比较流行的编程语言,特点是实现一项功能的代码往往比较短,但是运行速度比较慢。可以调用的各种各样的库都比较多,很适合搞一些小型的项目。
OCR 就是图片中的文字识别技术。这几年得益于深度学习的发展,OCR 的能力也在大幅提高。长按 iPhone 的相册、微信中的图片,都会有「提取文字」的功能,背后就是 OCR 技术。
正则表达式就是一种寻找字符串中特定模式的技术。比如 ^[A-Za-z0-9]+$ 这段正则表达式能匹配所有的英文和数字。现在的编程语言中基本都已经内置了正则表达式的模块,使用时只要根据你需要匹配的模式,设计出对应的正则表达式即可。
所以,我们可以使用 OCR 技术识别核酸检测报告中的所有文字;使用正则表达式提取姓名、核酸检测结果、核酸检测时间。

03. 实现
正如博士所说的,有现成的库,import 一下就行。对于会编程的人来说,这不是很难的工作。
我从网上找了一张北京“健康宝”核酸检测界面的样图。
把截图命名为“张三五.JPG”,以此作为检验的示例。
项目的主要难点在于 OCR 识别文字的准确率上。
我最开始使用的是轻量级的中文 OCR 开源解决方案 CnStd + CnOcr,代码很简短、运行速度很快,但是这个识别效果……真的一言难尽。
oooo。北京经信令 1:21 AM 100% 健康服务预约查询 O 【通知】这里是通知内容. 核酸检测 疫苗接种 张** 姓 名: 身份证号: 大大大大大大 大*22 43** 阴性 距离本次检测已过5天 核酸检测机构 XXXX医院 核酸检测时间 2020.06.23 导出或打印检测报告 历史检测结果查询 本电子报告与医院或其他检测机构提供的纸质报告具有同等效力 品奇 点击这里 F“核酸检测”服务,您可通 打开 主本服 进行大规模筛查检测预约、 、预 约码展示及采样信息绑定、预约记录查 预约 询、检测结果查询。 (? 留言反馈(
识别出来的姓名 “张**”  放在了 “姓 名:” 的前面,身份证号中的 “***” 被识别成了“大大大” 
然后我就把 OCR 的库换成了 PaddlePaddle,这次识别的效果出奇的好。
1:21 AM 100% D 健康服务预约查询 【通知】这里是通知内容... 核酸检测 疫苗接种 姓 名: 张** 身份证号:43**************22 阴性 距离本次检测已过5天 核酸检测机构 XXXX医院 核酸检测时间 2020.06.23 导出或打印检测报告 历史检测结果查询 本电子报告与医院或其他检测机构提供的纸质报告具有同等效力 可o 点击这里打“核酸检测”服务,您可通 可2 过本服务进大规模筛查检测预约、预 约码展示及采样信息绑定、预约记录查 预约 询、检测结果查询。①
至此,我们就把图片中的文字都识别出来了
下一步就是通过正则表达式把姓名、结果、核酸检测时间等信息提取出来。
  • 提取姓名:姓\s*名:\s*(\S*)
  • 提取阴性/阳性结果:(\S性)
  • 提取核酸检测时间:核酸检测时间\s*(\S*)
把提取的内容打印出来看下结果:
OK,内容提取出来了,我们用程序做校验吧!
我这里校验了三个条件:
  • 核酸检测时间与当前日期不超过 2 天
  • 识别出的姓名的汉字个数与截图文件名中姓名汉字字数相等
  • 识别出的姓名的汉字个数与截图文件名中姓名汉字第一个字(姓)相同
如果这三个条件都满足,就认为没问题。
最后,遍历文件夹下所有的截图,逐一运行上面的代码,把结果输出成 Excel 里。
运行的命令是:
python main.py --date=2020.06.24
打开生成的 Excel 是这样的:
是不是大大解放了生产力?
我写的这份代码的总行数只有 82 行,比复旦博士的代码要简短一些。
但是代码的运行时间比较慢:检验两张截图的时间需要 12 秒,也就是平均 6 秒检验一张截图
假如一个辅导员检查 60 个学生的话,上面的程序需要跑 10 分钟出检查结果。(但是收集、下载、重命名 60 个人的核酸检测截图需要多长时间?)
运行比较慢的是 OCR 识别部分,真需要优化运行速度的时候再说吧!
我已经把代码开源了,代码仓库地址是:
https://github.com/fuxuemingzhu/NucleicAcidCheck

04. 总结
本文使用 OCR + 正则表达式实现了一个核酸检测报告的核查功能。
我已经把代码开源,所有人都可以拿上面的代码免费使用,希望能对疫情防控一线的人员提供一些帮助。
但是,上面的做法无法防止 P 图,也无法防止使用别人的截图。
对于健康码核查最理想方案是采用上策:个人授权给机构,机构统一核查。对于上千、上万人的企业和单位来说,将大大提高疫情信息收集能力。
希望未来可以把疫情防控更加信息化,让防疫工作者把精力投入到更有价值的工作上,释放防疫生产力。
愿疫情早日结束!


参考资料:
  1. https://mp.weixin.qq.com/s/2CRSasqvRJAiu3sAPXhiXA

  2. https://mp.weixin.qq.com/s/JiQUfc9rOPmPXJpVx0CK-Q

  3. http://sh.people.com.cn/n2/2022/0408/c176739-35213856.html

  4. https://github.com/PaddlePaddle/PaddleOCR


负雪明烛」,来自于“苍山负雪,明烛天南”,乐于分享与帮助别人。

我坚持刷算法题 7 年,写了 1000 多篇题解,博客累计阅读量 400 万+。

关注我,你可以获得优质算法题解、求职技巧、大厂内推、工作经验。

这是一个用心在做的公众号,欢迎点击关注+星标!


历史文章推荐:
  1. 面试最常考的 100 道算法题分类整理!

  2. LeetCode 最经典的 100 道题

  3. 直播分享:LeetCode 应该怎么刷?

  4. 我的爆款算法题解是怎么创作出来的?

  5. 写了 1000 篇算法题解是什么体验?

  6. 为什么「执行代码」正确,「提交」出错?

  7. 我最近的工作状态

  8. 如何保持好的工作状态?

负雪明烛
1000 篇算法题解的作者,国内互联网大厂程序员,技术分享爱好者。 爱好算法题解写作,擅长深入浅出讲解计算机知识,乐于分享大厂见闻。和读者一起刷算法题,拿 Offer,交朋友!