“ 老罗:这应该是东半球最好用的识别二维(条形)码的浏览器插件!(ALMOST 梅开二度) ”
一、它是什么!
只需要轻轻的点一下,它就会识别你当前Tab里的所有二维(条形)码,识别结束后还会贴心的自动回显到对应的位置上 !(以下gif图经过压缩,颜色不对劲,忽略它哈)
除了以上自动识别外,也补齐了同行 ”可能“ 有的 “右键一键识别” 的功能,来覆盖识别不成功的场景:
二、怎么获取呢?
-
1、使用谷歌插件商店来获取,后期更新更方便!❤️ 推荐!
2、如果你没有科学上网,可以点击下面链接下载zip安装包,按网上的教程安装即可!
下载地址:https://bj-mutou-1301404888.cos.ap-beijing.myqcloud.com/awsome-qr-code/awsome-code-sanner.zip
安装教程:https://www.cnplugins.com/zhuanti/newinstall.html
三、听听实现它的心路历程吧(有点坎坷)
下面简单记录了一周多的时间,心情上的大悲大喜,也涉及一些优化方案思路,是如何一步一步优化到最终效果的,大家可以酌情食用~
1、第一行想法
自己装过很多识别二维码的插件,发现都不如想象中的好用(有的甚至傻乎乎的)😶,工作之余想象了一下我想要的功能究竟是什么样的?怎么设计才是更好用的?
带着以上问题,在一个周三的晚上,我默默地打开了小笔记,记录下了第一行想法:
“自动”?嗯... 想象起来挺简单,好像是:先这样,再这样,就好了...
不过浏览器可不是一个聪明人,它没有意识,又怎么知道当前页面中的二维码在哪里呢?不对... 它又怎么知道什么是二维码呢?
2、知识是有价的
我们小学二年级就学过,四周有三个大方块儿、中间都是像素点的一个方形的码就是二维码,不过计算机可不知道,它所看到的就是一个一个像素点,所以,如何让它知道什么是二维码,是摆在眼前的第一个问题。
让计算机掌握这门认识二维码的能力,就需要让它不断去学习,这就是高大上且酷酷的 “ 机器学习 ”。
可是... 大学本科毕业后我就从事了前端岗位,对机器学习相关概念了解的少之又少,em... 应该是完全不了解,只听过一两个名词:神经、训练...
不懂怕什么,不懂就去学好了😀,打开梦工厂网站,惊奇的发现真的有相关课程,有点小贵不过也还好,买它!
3、不懂就问
经过一晚上的学习,有了简单的知识基础后,带着相关问题,请教了正在读研的同学,得到了一个大致准确的方向:“目标检测”。
4、成功识别,人生里程碑!
有了大致的方向,就有了不少动力!
周六日两天,放弃了睡懒觉、午休、发呆、看电视🙂,经历了无数次的调参、崩溃、转化、买会员后,终于成功识别出了人生第一张图片:
这是一个好的开始!
5、略显枯燥的准备阶段
接着我尝试去各种寻找已有的分好类的二维码的训练集,可惜没有找到比较合适的...
em... 没有合适的怎么办?只能自己造了!一张一张图进行截图保存,并进行标注、分类、归集,眼都花了...
最终成功得到标注后的资源集标签,密密麻麻...
这时我才意识到训练模型不是一件容易的事(后知后觉),有一个门槛就是... 你需要有一台有比较不错GPU的电脑,看着我的笔记本我又陷入了沉思...
6、柳暗花明第一村
运气真好,找了不久就发现了谷歌提供一个平台:Colaboratory ,该平台提供python环境,并且...提供免费的GPU,你可以在这里愉快的训练你的模型啦!
经过不断的失败...报错...修复后,终于开始训练了!
老父亲流下了一行热泪... 看着正确率的不断提升,心里还是非常高兴的,仿佛自己的好大儿开始慢慢懂事了...
训练结束后,经过转化、优化、更换模型、导出等操作后,最终得到了满意的权重文件,终于可以在浏览器里识别二维码了!
先写个demo测试一下!
7、晴天大霹雳
兴冲冲的搞好浏览器插件,加载权重文件后,发现了一个晴天大霹雳!
tfModel.executeAsync(input)
是一个异步方法,在加载权重预热的时候,会使UI页面卡死!
google了一番后,发现无解,由于webgl的问题(没有深究,看其他人的解释是这样),所以一定会阻塞当前线程。
最终的现象就是打开插件,页面会卡死5-6s,然后在1-2s内可以渲染出来结果,总耗时在8s左右,体验非常不好。
这结果让我很失望,差点放弃...
8、柳暗花明第二村
吃个午饭冷静下来后想了一下优化方案,发现可以尝试使用web worker嘛,既然一定会阻塞主线程,那么我就在其他的线程里去做这个加载权重的操作,不就不会卡死页面了嘛!
大刀阔斧重构了代码,因为web worker和主线程之间的通讯不可以传递不可序列化对象,只能传递可被序列化的数据,就导致需要在两边进行图片数据的转换,适配代码写了一大堆...
最终优化后,效果如下,可以发现,在loading过程中按钮也可以点击,证明主线程没有被卡死:
不过聪明的你也发现了,加载权重花费的时间有些长,不,简直是太长了,而且这个插件的定位是一个一次性的工具,几乎不会存在只打开(加载)一次,识别多次的情况,所以怎么减少这个首次加载(预热)时间,是比较头疼的问题...
9、柳暗花明第三村
后来在周四的午休时间,正在梦中,忽然惊醒发现可以在background.js中做加载啊!而且有两点好处:
- 1、天然的其他线程,不影响主线程
- 2、background.js在安装插件的一瞬间就会执行,这个时候就去预热模型,后面都使用该预热后的模型对象去识别图片的,时间就会大大减少!粗略计算了一下,每次打开插件到识别完毕,时间大部分都在1s内,极少数会在2-3s,完全符合预期!
优化之后的效果大致如下:
可以看到,速度是非常的快了,终于符合了心里预期(一个随用随取的插件场景)。
10、Happy Ending
至此,从构思插件到其落地实现,大致经过了一周多的时间,期间不止有以上记录的试错流程,经过其他同学的提醒,还添加了一键复制按钮、条形码支持、右键菜单一键识别,还尝试使用electron来实现了桌面端的开发,使其识别功能不局限在浏览器里,最终因为打包体积过于庞大(100MB+),不符合自己的预期(10MB以内),就忍痛放弃掉了。
😌 过程比最初开始计划做的时候预想的要痛苦得多,踩的坑实在是太多了,不堪回首,如果最初知道要踩那么多坑,可能当时就放弃了
不过好在最后的效果还是不错的,比较符合期望,也是蛮开心的!😎
四、结束才是真正的开始
因为只使用了250张图片来训练识别模型,可能部分场景识别不到,还请大家谅解,给它一个慢慢进步的空间~
OK!回到文章开头,这应该是东半球最好用的识别二维(条形)码的浏览器插件!😉 装上试试看!