手把手教你使用pytorch+flask搭建草圖檢索系統(三)

手把手教你使用pytorch+flask搭建草圖檢索系統(三)



一、提要與預告

  • 準備工作 -> 鏈接
  • 後端搭建 -> 鏈接
  • 前端搭建
  • 前後端交互
  • demo -> 本篇內容

實話說,我是絕對沒有學過前端的,所以就在網上淘了幾個樣例然後拼接在一起,無法保證我寫的是不是對的,至少跑起來是符合預期的,但是否有隱患我無法保證。

二、畫板 頁面

本畫板是魔改自@zhoushuozh的畫板。我希望畫板擁有如下幾個功能:

  1. 能夠繪圖
  2. 有按鈕保存圖案,最好是opencv的可讀格式
  3. 有回退功能,能夠對草圖進行修改
  4. 如果用戶並不想親自手畫,畫板能提供上傳按鈕將已繪製好的草圖上傳
  5. 草圖畫好後,有按鈕將頁面從畫板跳轉到結果展示

所以,UI界面與畫板的功能應該如下圖所示:
在這裏插入圖片描述
前4個按鈕沿用了@zhoushuozh的畫板中的內容,從左至右分別是繪製按鈕,顧名思義就是可以在畫布上繪製線條;橡皮擦按鈕,當選擇橡皮擦後,可以再次選擇繪製按鈕後切換成繪筆;清屏按鈕,點了就可以清空屏幕;撤回按鈕,撤銷上一筆畫;保存按鈕,點了的話就可以將繪製的草圖上傳到後端;最後一個按鈕是上傳按鈕,用於用戶本地上傳已繪製好的草圖。

保存按鈕

當用戶在畫板頁面繪製好草圖後,點擊這個按鈕就可以把繪製好的草圖上傳至服務端。在html代碼中,我使用保存按鈕下方再疊一層文本的方式

<form action="" enctype='multipart/form-data' method='POST'>
    <button id="save" title="保存"><i class="iconfont icon-fuzhi"></i></button>
    <input type="text" name="sketchUpload" id="sketchUpload" value="" style="display:none"/>
</form>

把文本的id設爲id="sketchUpload",然後在後端controller.py處得到綁定的這個id,它會將繪製的草圖按base64進行編碼,不要問我原理,問就是不知道,我沒學過無法解釋。

@app.route('/canvas', methods=['POST', 'GET'])
def upload():
    if request.method == 'POST':
        sketch_src = request.form.get("sketchUpload")

        # ...
        basepath = os.path.dirname(__file__)
        upload_path = os.path.join(basepath, 'static/sketch_tmp', 'upload.png')
        if flag == 1:
        	# base64 image decode
            sketch = base64.b64decode(sketch_src[22:])
            user_input = request.form.get("name")
            file = open(upload_path, "wb")
            file.write(sketch)
            file.close()

在後端,通過base64.b64decode把傳來的代碼解碼,得到手繪圖像,然後再保存下來。

上傳按鈕

用戶不想親自畫,剛好本地就有畫好的草圖,那麼就可以通過這個按鈕進行本地上傳。同樣地,這裏我先建立了一個button屬性的圖標,然後參考網上教程,在下面綁定了一個action?學過html的一定覺得這是小兒科,對於我來說就比較難了。

<button id="upload" title="upload">
    <div align="center" style="margin:10px 0px 0px 3px">
        <embed src="static/css/upload.svg" type="image/svg+xml" width="30" height="30"/>
    </div>
</button>

<form action="" enctype='multipart/form-data' method='POST' id="upload_form">
    <input type="file" name="uploadSketch" id="uploadSketch" style="display:none" accept="image/png, image/jpg">
    <input type="text" name="uploadFlag" id="uploadFlag" value="0" style="display:none"/>
</form>

在後端,就通過下列代碼獲取這個uploadSketch的動作id

sketch_src_2 = request.files["uploadSketch"]
sketch_src_2.save(upload_path)
user_input = request.form.get("name")

三、結果展示 頁面

這是我從網上扒的一個gallery代碼,然後根據自己的需求進行了修改。我希望能夠在左側顯示草圖,右側顯示檢索內容,並且按每行6張、每頁3行、共5頁的規則進行展示,如下圖所示。
在這裏插入圖片描述
調整圖像的位置折騰了我很久很久。

四、前後端交互

我們在後端拿到了用戶上傳的圖像後,就可以像一般pytorch模型的inference過程來得到檢索結果了,例如下面的代碼,得到了檢索結果後,我們需要將這些東西都回傳給前端,這裏我使用了json來保存,在retrieval這個函數裏,就已經將路徑集合處理成了json格式,使用json.dumps就可以進行解析了。

# for retrieval
retrieval_list, real_path = retrieval(retrieval_net, upload_path)
real_path = json.dumps(real_path)
return render_template('panel.html', userinput=user_input, val1=time.time(), upload_src=sketch_src,
                        retrieval_list=retrieval_list,
                        json_info=real_path)

最後通過render_template命令將路徑、輸入草圖等數據傳給前端的panel.html,整個鏈路就打通了。

五、demo

在這裏插入圖片描述
我將整份代碼已經上傳到了github中,整個項目是可以在cpu下跑的,我測試的版本是pytorch1.4.1+cpu、python3.6、flask 0.12.2,通過運行download_prerequisites.sh應該就可以將項目的所有依賴全部下載下來了。

執行python controller.py,然後在瀏覽器中輸入http://localhost:5000/canvas,就可以進入到本系統中了。

六、總結

解釋前端部分完全是噩夢,因爲我沒學過,很多地方都無從下手,我只能把我想要的功能、行爲寫下來,實際上還有js和css需要講的,但我實在說不清楚,所以就把後面的內容全砍掉了,直接看我的代碼要好些吧。拖了這麼久,終於可以把這個坑填掉了,萬幸。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章