最近用Bootstrap+Flask+hnsw近邻搜索算法+人脸识别算法,实现了人脸相似度检索的Web应用,最后利用Apache部署了这个web应用。
下面是建立索引页的关键,也就是body部分。其中第一个row是为了传递给用户交互信息,当索引建立完成后,这个地方会显示建立成功或失败的信息。之后的row部分是输入框组和按钮组。每点击一个button,会向Flask后台返回该button的value值,这时,只要根据返回的value,确定执行什么函数就可以了。
<div class="container">
<div class="row">
<div class="col-md-12">
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="flashes alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×span>
button>
{% for message in messages %}
{{ message }}
{% endfor %}
div>
{% endif %}
{% endwith %}
div>
div>
<div class="row">
<div class="col-md-4 col-md-offset-5">
<h1>Create Indexh1>
div>
div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="" enctype='multipart/form-data' method='POST'>
<div class="form-group">
<label for="exampleInputEmail">Input Images' Pathlabel>
<input type="text" name="img_path" class="form-control" id="exampleInputEmail" placeholder="Input Images' Path">
div>
<div class="form-group">
<label for="exampleM">Input Mlabel>
<input type="text" name="M" class="form-control" id="exampleM" placeholder="Input M">
div>
<div class="form-group">
<label for="exampleMax">Input max elementslabel>
<input type="text" name="Max" class="form-control" id="exampleMax" placeholder="Input Max Elements">
div>
<div class="form-group">
<input type="submit" name="create_index" value="创建索引" class="btn btn-primary btn-lg btn-block button-new" onclick="" style="margin-top:50px;"/>
div>
<div class="form-group">
<input type="submit" name="add_items" value="增量索引" class="btn btn-primary btn-lg btn-block button-new" onclick="" style="margin-top:20px;"/>
div>
<div class="form-group">
<input type="submit" name="search" value="检索" class="btn btn-success btn-lg btn-block button-new" style="margin-top:20px;"/>
div>
<div class="form-group">
<input type="submit" name="delete" value="删除索引" class="btn btn-danger btn-lg btn-block button-new" onclick="" style="margin-top:20px;"/>
div>
form>
div>
div>
div>
根据点击button返回的value执行相应的函数
if request.method == 'POST':
create_index = request.form.get('create_index')
add_items = request.form.get('add_items')
search_yes = request.form.get('search')
delete = request.form.get('delete')
config = configparser.ConfigParser()
config.read('config')
feature_dim = int(config.get('hnsw', 'dimension'))
index_path = 'index.idx'
if create_index:
flash('')
# 初始化变量
imgDir = request.form.get('img_path')
m = int(request.form.get('M'))
max_elements = int(request.form.get('Max'))
# 调用函数
info = createIndex_function(feature_dim, max_elements, m, index_path, imgDir, config)
flash(info)
return redirect('/create')
if add_items:
flash('')
imgDir = request.form.get('img_path')
info = addIndex(feature_dim,index_path,imgDir)
flash(info)
return redirect('/create')
if search_yes:
return redirect('/upload')
if delete:
flash('')
if os.path.exists(index_path):
os.rename(index_path, 'index_backup.idx')
# os.remove(self.index_path)
flash('Already removed.')
return redirect('/create')
return render_template('create_index.html')
检索页一共分为两个页面,一个是初始页,另一个是返回检索结果的页面。两者唯一的不同就是检索成功页多了一个img区域。
以下是检索初始页的container 部分(upload.html)
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-5">
<h1>图像检索h1>
div>
div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="" enctype='multipart/form-data' method='POST'>
<div class="form-group">
<label for="exampleInputEmail">Input Klabel>
<input type="number" name="K" class="form-control" id="exampleInputEmail" placeholder="Enter K">
div>
<div class="form-group">
<input type="file" name="file" style="margin-top:20px;"/>
div>
<div class="form-group">
<input type="submit" value="上传" class="btn btn-primary btn-lg btn-block button-new" style="margin-top:50px;"/>
div>
form>
div>
div>
div>
下面是检索成功页面的container部分,其实只是多了img标签里的内容,用于返回检索结果。(upload_ok.html)
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-5">
<h1>图像检索h1>
div>
div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="" enctype='multipart/form-data' method='POST'>
<div class="form-group">
<label for="exampleInputEmail">Input Klabel>
<input type="number" name="K" class="form-control" id="exampleInputEmail" placeholder="Enter K">
div>
<div class="form-group">
<input type="file" name="file" style="margin-top:20px;"/>
div>
<div class="form-group">
<input type="submit" value="上传" class="btn btn-primary btn-lg btn-block button-new" style="margin-top:50px;"/>
div>
form>
div>
div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<img src="{{ url_for('static', filename= './images/results.jpg',_t=val1) }}" width="100%" height="100%" alt=""/>
div>
div>
div>
def upload():
if request.method == 'POST':
f = request.files['file']
k = request.form.get('K')
# print('*************************************************',k)
if not (f and allowed_file(f.filename)):
return jsonify({"error": 1001, "msg": "请检查上传的图片类型,仅限于png、PNG、jpg、JPG、bmp"})
user_input = request.form.get("name")
basepath = os.path.dirname(__file__) # 当前文件所在路径
upload_path = os.path.join(basepath, 'static/images', secure_filename(f.filename)) # 注意:没有的文件夹一定要先创建,不然会提示没有该路径
# upload_path = os.path.join(basepath, 'static/images','test.jpg') #注意:没有的文件夹一定要先创建,不然会提示没有该路径
f.save(upload_path)
# print(upload_path)
print('*************************************************',k)
k = int(k)
search(upload_path,k)
return render_template('upload_ok.html', userinput=user_input, val1=time.time())
return render_template('upload.html')
apache部署的时候遇到了很多问题,在试过了网上各大教程后,这篇最靠谱(从头到尾都很靠谱)!
How To Deploy a Flask Application on an Ubuntu VPS