主題 達人專欄

[Python+ CV ] 修圖軟體製作:GUI框架, JS事件, 縮放拖拉, based64轉numpy

%%鼠 拒收病婿 | 2022-06-21 00:00:11 | 巴幣 7466 | 人氣 398

前言:
課堂小專,不到半學期的時間要做個修圖軟體。
老師評分比較高,所以得肝一點o( ̄┰ ̄*)ゞ

不過倒是學到很多js操作。

操作畫面


關於詳細功能介紹,請看這篇功能介紹
關於本文主要內容與程式碼,請看這篇 製作過程
內部程式可在github上看。
軟體下載連結: 下載



Python UI介面選擇

一開始課堂上是教預設的Qt軟體,但我覺得Qt醜醜的,所以忍不住去嘗試其他框架。

Tkinter

跟以前做window form很像,用程式碼掛載與編排UI物件。

Qt Designer

在Anaconda預設功能, Anaconda資料夾下找到designer.exe啟動。
排版檔案會取為.ui附檔名,操作邏輯與Tk類似。
範例: 讀取圖片、變暗處理。


Eel


內部使用Bottle Server框架,可以用網頁技術寫介面,但不像flask能直接host在線上。




Flask / Django

使用Python編寫的輕量級Web應用框架。
範例: flask基本頁面,但其網頁模板概念跟Django雷同。

範例: Django網頁
創個views.py檔案,裡面定義Hello頁面內容

在urls.py定義Hello頁面的網址


綜合比較下來,我選擇開發桌面應用程式的eel,若小專題在展示的時候因為網路問題lag那可就掉渣了。( ̄┰ ̄*)
框架名稱
優點
缺點
Tkinter
像是用Python程式碼撰寫介面的Qt Designer
邏輯與QtDesigner類似,同樣無法解決程式碼攏長、難做排版等問題。
Flask/Django
較完整且可部屬網頁的web應用框架。
Python與前端邏輯溝通較複雜,需使用ajax等呼叫方式。
eel
旨在於結合前端技術開發桌面應用程式,前後端邏輯串接容易。
我試著包在docker環境下部屬但失敗多次,雖然文獻不多但似乎eel不支援網站部屬。










EEL基本使用

我是觀看他的影片:

python 呼叫js方法

python 方法上加@eel.expose 讓js端可以呼叫。

func.js檔案:


Async方法使用


按下按鈕後,js端等待python處理結果後出現alert。

JS-EEL圖檔傳輸

跨語言開發首先遇到的問題便是如何傳遞圖片資訊? 由於處理後的圖片需轉換成前端html可顯示的based64編碼,其跟openCV imread讀取進來的圖片格式之間的關係又是如何? 為此我必須先了解從HTML的input 標籤輸入的圖片至python端之間的格式與轉換。我整理出如下圖這個流程:
(1.) 由input標籤開啟的圖片為大型二進位檔物件(Binary Large Object ,blob),代表了一個相當於檔案(原始資料)的不可變物件。
(2.) 需實作js的FileReader物件,將blob轉碼成based64字串。
(3.) 透過eel框架傳送字串至Python端。
(4.) 使用based64處理套件將字串解析成byte陣列。
(5.) 透過numpy將byte陣列轉成uint8陣列。
(6.) 透過cv2套件將uint陣列解碼成圖片,此時得到的檔案形同於imread進來的圖片。
(7.) 使用圖片資料進行影像處理操作。
(8.) 將處理完的圖片回傳至前端作顯示時,逆著遵循前述的轉碼步驟,先將圖片轉成byte陣列,再以based64編碼成字串透過eel框架溝通回前端,由js接收並設定img標籤的src。


JS讀取圖片

使用jQuery偵測input標籤Change事件,搭配fileReader轉成base64字串。


Python接收圖片

將base64字串透過轉碼,轉程opencv可使用的格式。


搭配OpenCV

範例: 將圖片轉灰階





Python傳回圖片




直方圖

直方圖常常用在檢視圖片顏色趨勢、集中位置等等。
一開始使用Chart.js插件:
js端

Python端
注意np array無法直接傳輸,所以要轉成一般array。



瀏覽器無法像Python的numpy與的plot套件快速做統計與圖表,加上本身也不支援多線程(Multi-threading),因此當圖片解析度大,需要統計的數變多,前端直方圖生成便會延遲,除了採用異步執行避免程序卡死外,我還試過多個輕量圖表套件如Chart.js、dygraphs、EChart.js,尋找對資料最友善的解決方案,雖然目前前端直方圖生成仍有延遲存在,是日後需想辦法解決的問題(目前已是在Python生成直方圖數據,再傳輸至前端表現,理論上只需處理255*3個顏色資料,我認為會卡的點在於繪製與自動尋找最小至最大值區間)。

等化功能
等化是將像素顏色拉得平均一點。



操作Hot Key

註冊document事件,並藉由array紀錄各步驟的base64字串。



JS寫出圖片




拖拉圖片


JS事件

在修改圖片時觸發事件,如此便能最後續處理,例如圖片縮圖僅需在圖片有更動時才須更新。


顏色通道

圖片RGB拆成可以分別開關的通道,在P圖的時候常會從通道中選一張二值化效果最好的通道做遮罩,不過目前本軟體的通道只能顯示、不能編輯(;´༎ຶД༎ຶ`)  (時間不夠..)。



在地化

加上為了降低開發環境複雜度,本軟體前端使用較原生的JQuery輔助,沒有用如React.js等完整的web生態系統,能使用的工具較為受限,最後使用行之有名的i18n在地化解決方案應付小需求翻譯。




後紀:
與全班做法不同,在學習的路上總是有些孤獨、無助。所幸社群的力量,每當我遇到困難時總是能在StackOverflow等平台找到方法。也感謝eel團隊釋出這個便捷的框架,我也想盡力將所學知識、概念紀錄並分享下來回饋社群。

這個專案少說也陪伴我快半個學期,每天埋頭在打程式、修BUG,最後也算是來到個Ending,就像小孩子畢業一般,想盡力寫好文件、交代擴充方法等等送它最後一程,儘管我總是會有點自卑的覺得「某某功能太基本不值得介紹」所以少寫在文件裡,也希望各位能多看看這學期的努力結晶。



附錄:

主要功能與對應選單做成表格整理如下:

功能名稱
套用結果
選單
調整大小
旋轉
*旋轉操作可即時預覽,按下套用後自動補齊邊界。
等化
*等化後自動更新直方圖結果
顏色調整
*貼心提供色彩對照表方便調整
色彩分割
*範例:抓取藍色頭髮。
曝光校正
對比校正
高斯模糊
去除雜訊
美肌
銳化
邊緣抽取
*有做彩色/灰階圖兩種處理,若只要白線需先使用「灰階」功能。
邊緣保留
鉛筆風格
特色
毛邊模糊
魚眼
波紋模糊
放射像素模糊
漣漪效果
扭轉效果
運動模糊
放射模糊
標示人臉


送禮物贊助創作者 !
0
留言

創作回應

Ctrl+Shift+W
這什麼硬到爆炸的課?看成果已經可以在我學校的畢業專題裡過關了...
2022-06-21 00:18:05
%%鼠 拒收病婿
資工的課好像都很硬
2022-06-21 10:58:58
⊰⊱求出處學術用⊰⊱
真猛
2022-06-21 00:45:31
%%鼠 拒收病婿
強健的肝[e5]
2022-06-21 10:59:18
Lykoi
蠻有趣的作業~另外推薦一個我自己覺得還不錯看的 GUI框架 Dear ImGUI,在 Python的話好像叫做 DearPyGui。因為是電腦應用,所以支援多執行緒,也不用特別轉成 base64,在執行速度上應該會有不錯的提升,並且支援跨平台編譯,我認為會是不錯的選擇?
2022-06-21 01:14:57
%%鼠 拒收病婿
感謝推薦! 看起來概念跟QT類似,但是使用GPU渲染UI[e17]
不過好像不能用html做排版
2022-06-21 10:58:41
NA-23
我看不懂 但我大受震撼
2022-06-21 02:43:02
%%鼠 拒收病婿
沒關係,看都看[e5]
2022-06-21 10:59:57
偷偷做不會被發現
這半學期??,大佬
2022-06-21 09:11:29
%%鼠 拒收病婿
期中前在教OpenCV,期中後交代一下期末就開始自由發揮了[e5]
2022-06-21 11:03:10
追蹤 創作集

作者相關創作

相關創作

更多創作