说实话,对于我这种菜鸟,让我在一周内课还不少的情况下挤时间完全靠自己搭个车牌系统还是十分困难的。毕竟车牌识别这种东西,也是人家一个毕设的工作量,有些公司拿这个吃饭。同时根据实现方法的不同,工作量也不一样。如果自己用从零开始去实现车牌识别确实工作量蛮大的,而且效果也不一定好(膜拜班里其他自己从头写轮子的大神)。
所以我就打算在网上找现成的车牌识别,能大概理解一下流程就不错了。然后精力主要放在整个系统的整合和前端框架的搭建,虽然前端和视频处理这门课没有多大关系(这很树莓)。
下面就是我的爬坑日记。主要讲述前端和整个系统的搭建过程。
在网上找车牌识别,一般习惯github,其次csdn的(csdn的积分对于我这种伸手党确实不友好)。最后找到两个比较好的选择。一个是liuruoze很多星星很多fork的开源车牌识别系统easyPR,另外一个是小众一些的HyperLPR。easyPR是基于window环境下开发的,不适合mac,虽然有源代码也可以cmake,但是还是选择了HyperLPR,因为后者用了python,更加方便也跨平台。同时也便于后期开发搭建一些cnn框架。(在这感谢这些大佬的分享,钦佩这些大佬们的开源精神)
前端的话,如果用python自带的tk界面感觉很复古,跟window下的mfc,java的swing包差不多的风格。不够树莓。虽然也有用pygame去搭的python界面的,也可以省很多接口之类的问题。
但我还是想试试前后端分离的整合方式。所以我甚至想到用opengl或者unity去做。可以,这很树莓。
emmm,mfc风格的界面(来自百度图片)
qt也是个跨端框架。但是它太大就放弃了。 (用校园网下完qt的包我们的课设都结束了吧)最后采用流行的前端框架—尤大的vue.js。这样的好处不仅可以体会一下前后端分离的方式,也方便系统的发布,到时后直接build成app到pc或者移动设备,或者放在云服务器,都很方便。选择vue.js主要是因为之前网站开发的课设也试过一点,而另外一个著名的react却没用过。
但这次还要基于桌面开发。单纯的vue+webpack是不够的。所以还多采用了一个框架electron。electron是现在pc轻量级应用开发的小清新。本来是为了google为atom编辑器开发出的开源框架,基于nodeJS,后来大家感觉哎呦不错,然后用的人多了一点。熟知的vscode也是它写的。
接下来就是如何整合electron和vue了。这个过程因为不熟悉,搞了好多bug。
第一个想法是先把vue写好,build出来,然后再按照electron的方式去运行。但是它们之间的交互呢?前端对系统的调用怎么办呢?比如我要选择一个本地文件怎么操作?改了vue怎么hot-loading?vue怎么去通过electron调用本地呢?webpack是不支持require electron的。。。。。。(省略一堆问题)
main.html引入
当时也调了很多bug,然后我就有点想单纯用electron了。
后来发现了一个脚手架electron-vue,webpack.config配置好了electron和vue,支持他俩同时hot-loading,用vue-cli就可以构建工程。主要是学校网太差,vue-cli弄了好久都没装下来,更不用说后来还要npm install。设置成淘宝源都巨慢。好在物有所值,不枉老夫重下几十次的苦心。比如vue调用electron的ipcRenderer(用于主副进程的通信)只要操作this.$electron.ipcRenderer。省了很多功夫。
electron-vue把electron框架也用webpack来进行打包。进行了两次打包。electron作为Main,vue作为Renderer。
hot-loading时的dev-runner程序
然后就开始编写前端。
首先遇到的问题就是路径问题。build和dev模式下的路径问题。之前一直都有混乱。为什么有些地方要加@,有些不用。有些是用绝对路径,有些是用相对路径。下面会总结。
vue里图片的引入
比如vue里的路径,“@”是一个alias,定义在renderer的config里。
在webpack之前,带@的路径将会被自动替换成上图的路径去搜索。这个路径并不是最终路径,最终路径会被webpack自动替换。可以用dev模式的调试器去检查一下图片就可以明白了。
另外时dev模式下的整个系统的路径。dev模式下webpack出来的东西会被加载在内存中。所以你在dist看不到。而且会被webpack当作放在contentbase下。如下图,默认设置在根目录了。
dev-runner.js的server
下一个问题,做了一个loading主界面时的时候会显示的的html小界面,路径应该怎么设置呢?
主界面的路径
loading界面路径
我把loading的html放在了static文件夹里。放在static文件夹的文件都会通过一个plugin被打包。然后模仿主界面的方式去写三元表达式去加载。主要是处理dev下和打包后的路径。
用于打包static的plugin
然后是页面路由问题。这里路由用的是vue-router。要注意路由的正确嵌套,不然的话就会页面跳转时显示错误。
最终renderer的结构如下:
vscode内截图renderer
路由设置
一个主页面MainPage,下面有4个组件,有3个页面,1个选择栏。
通过选择栏触发选择栏下部函数进行跳转。注意,这些组件共用一个router。所以不用父子通信。
toolpage中处理router的method
webpack中引入
main.js引入jquery并extendanimate.css插件的案例
最终界面的效果如下,左边是选择栏,进行路由跳转。(自己ps了个丑丑的图标)
aboutpage界面
toolpage界面
有些部分采用了饿了么的elementsUI。(感谢饿了么不仅送外卖还送ui)虽然我做的还是很简陋,但是不知比python自带的tk高到哪里去了。
vue的框架基本搭好后,就需要考虑python的车牌识别系统的接口了。
车牌识别的文件都放在了static下。通过electron的ipc通信以及nodeJS的exec来进行接口调用。统一用ipcmain来进行系统接口的调用来保证安全性。
ipc通信流程图
有个问题就是在vue里ipc回调函数中的this代表的含义。很长一段时间因为这个问题一直调不通一脸懵逼。最后通过在里面调vue的method来对vue的data进行修改。
ipc回调并不直接处理
实例的method来处理
另外一个很关键的问题就是,调用python的文件的js文件(即main.js)的当前路径也是python的当前路径。就是“./”代表的目录。所以要注意修改python系统里的相对路径。
还有一个路径的问题就是,上传图片的路径。系统是以文件夹作根目录的。比如“/User”,它就会在当前文件夹下寻找"User",当然是找不到的。上传图片最好还是electron去进行fs操作。但是python后端不需要,那个是本地的。所以我们上传的图片的本地路径python直接就可以执行。
在踩了无数坑之后,前端基本搭建完成。下面就来看看后端的python车牌识别系统。
后端的pipline总结如下。
pipeline的流程(已经写在aboutpage里)
其中算法主要涉及opencv的HAAR Cascade、cnn卷积神经网络、一些图像处理算法:基于方向场的车牌矫正算法、使用RANSAC的车牌精定位等。但不是自己写的也没有啥好说的。。。也有别的算法,其他使用比较多方法的垂直水平投影去分割,svm分类器、ann进行车牌识别等。
另外接口通过对路径进行正则分析后缀来区分是该分析视频还是分析图片。
正则判断
另外注意对视频是否正确读取进行判断。不然容易出错。
ret的判断对强迫症来讲很重要
总的来说,接口这些东西最好先在其他地方试好再组装进系统里,不然容易很多bug,也不好调试。
最后例行总结。
7天前3天都在学习并搭建前端(vue和electron)在github看大牛的源码,值得参考的不少,后几天就在搭python和前端的交互,同时也分析python的代码。做点界面的优化神马的。最后还有develop界面没做,这里需要开放一些数据的接口让用户可以输入图片训练cnn或者设置些参数等等功能。
这段时间也恰逢元旦假,课设直接导致不能出去玩。每天都要经常肝的很晚(绝对不是因为白天要上课补作业并且和朋友玩王者荣耀和荒野行动),最后验收前一天还跟同样被课设折磨的H同学一起去刷夜。高兴的是找到一个环境不错适合刷夜的咖啡厅。(但是我已立flag不再刷夜)一进去很多信院的小伙伴,25元可以通宵到6点,有电有wifi。(这里吐槽学校什么时候能体会程序猿的刷夜需求)。
刷夜的收获满满,我们在这写了一晚上的bug,H同学甚至因此燃起敲代码的兴趣。
领取专属 10元无门槛券
私享最新 技术干货