说说具体技术之前的一些曲折吧,如果想看技术直接向后翻即可。
车牌识别项目的大致功能我们已经完成:手动读取一张图片最终输出图中的车牌号。接着就是搭建一个网页,我们小组目标的功能是:用户可以向该网页上传图片,一经上传,我们的程序就开始工作,最终输出识别出的车牌号。计划用python flask实现。说得很理想,但是其实我们小组的成员python flask的知识储备基本为0。
Web的搭建由我和周延霖负责,周延霖认为上述功能要求过高,应该做成静态网页输出识别结果即可。其实一开始想的也比较难,做出一个可以上传图片的网页,把图片存储到本地文件夹确实没什么问题,但是怎么让我们的pyhton程序能够主动调用这张图片进行识别呢,这个逻辑说起来很简单但是其实我们不知道怎么实现。林筠皓建议设置一个控件用于启动python程序,这似乎可行。
关于Web搭建的准备,系统地学习Python Flask不仅没有必要(在人工智能的项目里面学习Web知识?)而且也很难实现(基本课时都在八小时以上),看老师给的PPT也很不好学。只好直接看别人的代码了。
正式开始Web的搭建之路,还请读者注意,本篇文章不是系统地教学,只是记录自己短期内在完全没有相关知识储备的情况下,怎么利用Python Flask迅速搭建起一个满足需求的网页。
刚开始只是打算一点一点地实现目标功能罢,先从上传图片做起,这个的参考资源的获取也是比较容易的。此处参考bilibili网站【谷雨课堂】Python干货实战【030】 网站开发之-上传图片或文件,链接:https://www.bilibili.com/video/BV1Rh41117yy?share_source=copy_web&vd_source=a903512a82ff2959ba4cac987f40e02a。
1.先介绍一下基本的工作环境配置:
2.先看upload.html文件,这个主要就是相当于设计你的网页要长什么样。
1 2 3 4 5 6 7 8 9 10 11 <html > <head > <title > File Upload</title > </head > <body > <form action ="/api/upload" method ="POST" enctype ="multipart/form-data" > <input type ="file" name ="file" /> <input type ="submit" value ='上传' /> </form > </body > </html >
title就是网页的名称了,只需要一个上传文件的表单即可,非常简单,不必赘述。效果如图所示。
3.app.py文件,运行网页的根本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 from flask import Flask, url_for, redirect, render_template, requestimport timeimport osimport character import my_cnn_predict app = Flask(__name__) BASE_DIR = os.path.dirname(os.path.abspath(__file__)) STATIC_DIR = os.path.join(BASE_DIR, 'static' ) UPLOAD_DIR = os.path.join(STATIC_DIR, 'upload' ) def upfile (field='' , dir ='' ): if len (request.files) < 1 : return "" if field == '' : for k in request.files: field = k break f = request.files[field] if f == None : print ("没有上传的字段" + field) return "" fname = f.filename if fname == '' : return '' ext = fname.rsplit('.' , 1 )[1 ] unix_time = int (time.time()) new_filename = str (unix_time) + '.' + ext now = int (time.time()) timeStruct = time.localtime(now) str_ymd = time.strftime("%Y-%m-%d" , timeStruct) if dir == '' : dir = str_ymd if not os.path.exists(UPLOAD_DIR+'/' +dir ): os.makedirs(UPLOAD_DIR+'/' +dir ) print (UPLOAD_DIR+'/' +dir +'/' +new_filename) f.save(UPLOAD_DIR+'/' +dir +'/' +new_filename) return dir +'/' +new_filename, new_filename @app.route("/" ) def index (): return render_template('upload.html' ) @app.route("/api/upload" , methods=['POST' ] ) ''' 网页原本的思路是: 上传一个文件|图片,一个if-else语句,如果没有上传文件则提示没有上传文件,否则创建一个文件夹(根据时间)存储该文件 那么修改的可能就出现了,完全不需要实现之前想的那么复杂的逻辑 只需要在有上传文件的情况下调用存储好的图片和车牌识别的API即可 首先修改张龑的API,原本是以文件夹为单位处理(逐个处理该文件夹下所有图片),现在只需要以图片为单位处理即可,怎么修改下一小节再描述 切分的结果存储在results文件夹下,以该图片命名的文件夹 接着向字符识别网络传输切分后的图片存储路径,识别结果作为字符串直接打印即可 ''' def uploader (): upload_file, new_filename = upfile() if upload_file == '' : return "您没有上传文件 <a href='/'>返回</a>" else : character.split("static/upload/2022-07-18" , new_filename, "results" ) result = my_cnn_predict.predict("results/" + new_filename.rstrip(".jpg" )) return "<a href='/static/upload/" + upload_file + "'>" + result + "</a> <a href='/'>返回</a>" if __name__ == '__main__' : app.run()
图片存储情况如下图所示。
4.最后就是修改切分字符的API了
原本是一个文件夹下遍历所有图片,现在只需要对传入的图片做处理即可,取消循环,比较简单。
最后让大家看看效果吧
可以重复多次上传图片进行识别,这里不过多进行演示,完美。