基於 Serverless 的人工智慧相冊小程式
- 2020 年 4 月 9 日
- 筆記
日常生活中,我們常常會想要「搜索照片」。每當尋找很久遠的照片時,記憶模糊,檢索照片時只能想起大致的時間,然後一張張查看。這樣不僅效率低下,還經常會漏掉我們想找的照片。
近幾年微信小程式發展迅速,如果有這麼一款軟體,我們只需要用文字簡單描述,就能實現圖片的快速檢索,豈不是很棒!
本項目將以小程式為例,在 Serverless 架構上進行開發。該小程式在保留相冊基礎功能(新建相冊、刪除相冊、上傳圖片、查看圖片、刪除圖片)上,增加人工智慧搜索 —— 即用戶上傳圖片之後,基於 Image Caption 技術,自動對圖片進行描述,實現 Image to Text 的過程。這樣,當用戶進行搜索時,通過文本間的相似度,就可以返回最貼近的圖片。
基礎設計

基礎設計
該項目設計主要擁有登錄、相冊、圖片上傳和預覽功能,以及搜索功能。如圖所示:

相冊功能
- 註冊功能的主要作用是 通過獲取用戶的唯一 id(微信中的 OpenId),來將用戶資訊存儲到資料庫中,之後的所有操作,都需要以該 id 作為區分;
- 相冊功能 主要包括相冊的增刪查改等功能;
- 圖片功能 包括圖片上傳、刪除和查看;
- 搜索功能 主要是可以查看指定標籤對應的圖片列表,以及指定搜索內容對應的列表。
當然這四個主要功能和模組是和前端關係緊密的部分,除此之外還有後端非同步操作的兩個模組,分別是影像壓縮和影像描述功能。
1. 註冊功能:
註冊功能是用戶點擊註冊帳號之後,執行的動作。
該動作需要注意,註冊之前需先判斷用戶是否已經註冊過。如果已註冊則默認登陸,否則進行註冊並登陸。當用戶不想註冊時,可以點擊體驗程式,對程式大部分頁面進行預覽。但是不能實現有關資料庫的增刪改查。登錄功能頁面如圖所示:

登錄功能頁面
2. 相冊功能:
當用戶註冊登錄之後,可以在相冊管理頁面進行相冊相關的管理,包括編輯、刪除和新建。在進行添加和修改的時候,需要注意相冊名稱是否已經存在;在進行刪除、修改相冊等操作時要判斷用戶是否有操作該相冊的許可權等。相冊功能原型如圖所示:

相冊功能原型
3. 圖片功能:
圖片功能主要包括圖片列表以及圖片獲取、上傳和刪除。在圖片獲取與刪除的過程中,要對用戶是否有該項操作的許可權進行判斷,上傳時也要判斷是否有上傳到指定相冊的許可權。圖片功能相關原型圖如所示。

圖片功能相關原型圖
圖片功能部分除了用戶側可見的功能,還有定時任務。當用戶上傳圖片之後,系統會在後台非同步進行影像壓縮、影像描述和關鍵詞提取等。整體流程如圖所示。

圖片功能系統後台流程
4. 搜索功能:
搜索功能指的是通過關鍵詞或使用者的描述,得到目標數據的過程。這一功能原型圖如圖所示。

搜索原型
這一部分的難點在於通過用戶的描述,搜索到目標數據的過程。這個過程的基本流程如圖所示。

搜索流程
項目開發
1. 資料庫建立

資料庫部分主要對相關的表和表之間的關係進行建立。首先需要創建項目所必須的表:
CREATE DATABASE `album`; CREATE TABLE `album`.`tags` ( `tid` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(255) NOT NULL , `remark` TEXT NULL , PRIMARY KEY (`tid`)) ENGINE = InnoDB; CREATE TABLE `album`.`category` ( `cid` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(255) NOT NULL , `sorted` INT NOT NULL DEFAULT '1' , `user` INT NOT NULL , `remark` TEXT NULL , `publish` DATE NOT NULL , `area` VARCHAR(255) NULL , PRIMARY KEY (`cid`)) ENGINE = InnoDB; CREATE TABLE `album`.`users` ( `uid` INT NOT NULL AUTO_INCREMENT , `nickname` TEXT NOT NULL , `wechat` VARCHAR(255) NOT NULL , `remark` TEXT NULL , PRIMARY KEY (`uid`)) ENGINE = InnoDB; CREATE TABLE `album`.`photo` ( `pid` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(255) NOT NULL , `small` VARCHAR(255) NOT NULL , `large` VARCHAR(255) NOT NULL , `category` INT NOT NULL , `tags` VARCHAR(255) NULL , `remark` TEXT NULL , `creattime` DATE NOT NULL , `creatarea` VARCHAR(255) NOT NULL , `user` INT NOT NULL , PRIMARY KEY (`pid`)) ENGINE = InnoDB; CREATE TABLE `album`.`photo_tags` ( `ptid` INT NOT NULL AUTO_INCREMENT , `tag` INT NOT NULL , `photo` INT NOT NULL , `remark` INT NULL , PRIMARY KEY (`ptid`)) ENGINE = InnoDB;
創建之後,逐步添加表之間的關係以及部分限制條件:
ALTER TABLE `photo_tags` ADD CONSTRAINT `photo_tags_tags_alter` FOREIGN KEY (`tag`) REFERENCES `tags`(`tid`) ON DELETE CASCADE ON UPDATE RESTRICT; ALTER TABLE `photo_tags` ADD CONSTRAINT `photo_tags_photo_alter` FOREIGN KEY (`photo`) REFERENCES `photo`(`pid`) ON DELETE CASCADE ON UPDATE RESTRICT; ALTER TABLE `photo` ADD CONSTRAINT `photo_category_alter` FOREIGN KEY (`category`) REFERENCES `category`(`cid`) ON DELETE CASCADE ON UPDATE RESTRICT; ALTER TABLE `photo` ADD CONSTRAINT `photo_user_alter` FOREIGN KEY (`user`) REFERENCES `users`(`uid`) ON DELETE CASCADE ON UPDATE RESTRICT; ALTER TABLE `category` ADD CONSTRAINT `category_user_alter` FOREIGN KEY (`user`) REFERENCES `users`(`uid`) ON DELETE CASCADE ON UPDATE RESTRICT; ALTER TABLE `tags` ADD unique(`name`);
2. 讓 Code 飛起來
- 在使用之前您需要有一個騰訊雲的帳號,並且開通了 SCF、COS、APIGW 以及 CDB 等相關產品許可權;
- 將項目 clone 到本地,配置自己的密鑰資訊、資料庫資訊。配置文件在
cloudFunction目錄下的serverless.yaml中:
# 函數們的整體配置資訊 Conf: component: "serverless-global" inputs: region: ap-shanghai runtime: Python3.6 handler: index.main_handler include_common: ./common mysql_host: gz-c************************.com mysql_user: root mysql_password: S************************! mysql_port: 6************************0 mysql_db: album mini_program_app_id: asdsa************************dddd mini_program_app_secret: fd340c4************************8744ee tencent_secret_id: AKID1y************************l1q0kK tencent_secret_key: cCoJ************************FZj5Oa tencent_appid: 1256773370 cos_bucket: 'album-1256773370' domain: album.0duzahn.com
由於我目前使用的是 Serverless Components,沒有全局變數等。所以在此處增加了全局變數組件,在這裡設置好全局變數,在之後的 Components 中可以直接引用,例如:
# 創建存儲桶 CosBucket: component: '@serverless/tencent-website' inputs: code: src: ./cos region: ${Conf.region} bucketName: ${Conf.cos_bucket}- 安裝必備工具:Serverless Framework、小程式雲開發 IDE。由於本項目後台開發語言是 Python,您也需要一些 Python 的開發工具以及包管理工具(Python 版本不低於 3.6)
- 在部分文件夾下安裝相對應的依賴:
cloudFunction/album/prdiction需要安裝 Pillow, opencv, tensorflow, jiebacloudFunction/album/getPhotoSearch需要安裝 gensim, jieba 以及 collectionscloudFunction/album/compression需要安裝 Pillow (注意,在安裝的時候一定要用 CentOS 作業系統。如果沒相對應系統,可以在這裡打包對應的依賴:http://serverless.0duzhan.com/app/scf_python_package_download/)
- 將項目部署到雲端,只需要通過指令
serverless --debug即可:
DEBUG ─ Resolving the template's static variables. DEBUG ─ Collecting components from the template. DEBUG ─ Downloading any NPM components found in the template. DEBUG ─ Analyzing the template's components dependencies. DEBUG ─ Creating the template's components graph. DEBUG ─ Syncing template state. DEBUG ─ Executing the template's components graph. DEBUG ─ Starting API-Gateway deployment with name APIService in the ap-shanghai region ... ... DEBUG ─ Updating configure... DEBUG ─ Created function Album_Get_Photo_Search successful DEBUG ─ Setting tags for function Album_Get_Photo_Search DEBUG ─ Creating trigger for function Album_Get_Photo_Search DEBUG ─ Deployed function Album_Get_Photo_Search successful DEBUG ─ Uploaded package successful /Users/dfounderliu/Documents/code/AIAlbum/.serverless/Album_Prediction.zip DEBUG ─ Creating function Album_Prediction DEBUG ─ Updating code... DEBUG ─ Updating configure... DEBUG ─ Created function Album_Prediction successful DEBUG ─ Setting tags for function Album_Prediction DEBUG ─ Creating trigger for function Album_Prediction DEBUG ─ Trigger timer: timer not changed DEBUG ─ Deployed function Album_Prediction successful Conf: region: ap-shanghai ... ... - path: /photo/delete method: ANY apiId: api-g9u6r9wq - path: /album/delete method: ANY apiId: api-b4c4xrq8 - path: /album/add method: ANY apiId: api-ml6q5koy 156s › APIService › done
這個過程,只用了 156s 便部署了所有函數。然後打開小程式的 id 帶入 miniProgram 目錄,並且填寫自己的 appid 在文件 project.config.json 的第 17 行,同時也要配置自己項目的基礎目錄,就是 API 網關給我們返回的地址,寫在 app.js 的第 10 行,此時項目就可以運行起來了。
小結
Serverless 架構憑藉著按量付費、低成本運維和高效率開發等眾多優點於一身,幫助我們的項目快速開發和迭代。而 Serverless Framework 則是一個非常高效的工具,兼容 Tencent Cloud, AWS, Google Cloud 等多家廠商的 Serverless 架構。
本項目以騰訊雲 Serverless Framework 為例,詳細資訊可以移步 官方說明。
參考:
- GitHub: github.com/serverless
- 官網:serverless.com
歡迎訪問:Serverless 中文網,您可以在 最佳實踐 里體驗更多關於 Serverless 應用的開發!
Serverless Framework 免費試用計劃
Serverless Framework 免費試用名額已開放,我們誠邀您來試用和體驗最便捷的 Serverless 開發和部署方式。包括服務中使用到雲函數 SCF、API 網關、對象存儲 COS 等產品,均在試用期內提供免費資源,並伴有專業的技術支援,幫助您的業務快速、便捷實現 Serverless !
Serverless Framework 落地 Serverless 架構的全雲端開發閉環體驗,覆蓋編碼、運維、調試、部署等開發全生命周期。使用 Serverless Framework 即可在幾秒鐘內將業務部署至雲端。

具體免費詳情可查閱:https://cloud.tencent.com/document/product/1154/38792

