1.案例概述
1.1 背景
實現一個人臉識別進行開鎖的功能,用在他的真人實景遊戲業務中。總的來說,需求描述簡單,但由於約束比較多,在架構與選型上需要花些心思。
1.2 部署效果
由於該遊戲還在線上服務中,此處就不放出具體操作的視訊了。
1.3 玩家體驗
玩家發現並進入空間後,在顯示屏看到自己在當前場景出鏡的實時畫面。玩家靠近觀察時,捕獲當前幀進行人臉識別,實時畫面中出現水印字幕“認證中”人臉認證失敗時,實時畫面水印字幕變更為“認證失敗”,字幕維持 2 秒後消失,恢復初始狀態。玩家繼續尋找遊戲線索,重新進行認證。人臉認證成功時,實時畫面水印字幕變更為“認證成功”,並彈開保險箱門。進入後續遊戲環節。2.產品要求2.1 需求說明
需求提出時比較明確,核心邏輯不復雜。
人臉識別:通過人臉識別進行鑑權。開鎖管理:通過鑑權則開啟箱門,未通過則保持鎖定。反饋提示:需要有實時視訊反饋,指引明確,便於優化玩家體驗。2.2 約束說明
畢竟是生意,所以在商言商,對實用性和成本要求很高,關鍵是不要影響遊戲過程,同時保證玩家體驗。
低成本:需要低建設成本,低維護成本。易維護:對維護人員技術水平要求低,出現軟硬體故障時,任意店員可以快速恢復。高可靠:識別準確率高,容錯能力強,系統持續執行中故障率低。有限空間:整套系統在去除顯示屏、電磁鎖、保險箱後,其它結構實施空間不能超過 20cm*15cm*15cm 體積。採光不足:實景空間小,有頂光無側光,曝光時間較長。通用供電:只提供 5V、12V 兩種直流電介面。並行處理:鑑權流程與反饋流程並行,鑑權過程中,反饋系統不能出現中斷、阻塞等情況,使玩家有明顯的中斷、卡死體驗。弱網路環境:由於房間隔斷多,網路共用,所以網速有限,有突發延遲情況。2.3 功能設計
可能的架構方案有多種(不同方案間的比較,在文末進行),下面展開說明一下最終上線的方案。
2.3.1 設定流程
流程與效果,請參考 1.3 玩家體驗 部分
2.3.2 可配置內容
騰訊雲金鑰對修改配置檔案,用於適配騰訊雲賬號切換功能(測試賬號/正式賬號)。
人員庫 ID修改配置檔案,用於指定不同人員庫(測試庫/正式庫)。
水印提示更換對應圖片,實現更換水印。使用圖片管理,而不是文字配置的原因,是由於圖片配置模式無需字型檔支援,無需配置顯示大小,易於圖案嵌入。由於所見即所得,對維護人員要求低。
關機選項可配置任務完成後,是否自動關機。用於遊戲環境復位準備,減少復位工作量。
2.3.3 運營與維護
系統運營管理場景啟動時,統一上電。認證通過後,自動關機,完成復位。
故障處理軟硬體故障:無法開機、可開機無顯示、可開機顯示系統異常,可開機未知異常等等,更換樹莓派或其它硬體。
網路故障:正常執行,無法認證,可查網路+查雲日誌,解決網路問題;
雲產品異常:執行 4 個月,未發生過,可以忽略,如發生則聯絡雲售後;
2.3.4 成本分析
硬體成本:500 ~ 600 元。備件成本:按 1:1 備件,500 ~ 600 元。執行成本:雲端 0 元,使用免費額度;電費網費,忽略不計。3.技術實現3.1 系統架構
3.1.1 硬體組成:
樹莓派:終端主控攝像頭:視訊輸入感測器:超聲波測距顯示屏:視訊輸出繼電器:控制電磁鎖電磁鎖:控制保險箱門
3.1.2 關鍵特性
圖片識別:使用圖片識別,而非視訊流,減少對網路頻寬要求。識別要求低:欠曝光照片也有高識別率。觸發識別:玩家在場景內活動時間長,觸發模式避免了高頻認證、誤開鎖情況,同時降低認證成本。測距選型:超聲波感測器技術成熟,成本低(3 元);鐳射感測器成本高(30 元)多程序:視訊處理與監測鑑權由兩個程序實現,避免了阻塞等情況,同時使用程序間通訊,實現可靠互動。3.2 系統搭建
3.2.1 騰訊雲配置
註冊賬號按文件指引獲取 API 金鑰
配置人臉識別訪問官網控制檯,通過“新建人員庫->建立人員->上傳照片”,建立認證基礎。
其中所使用的“人員庫 ID”是關鍵資訊,用於後續 API 呼叫識別時,指定認證動作匹配的人員庫。
注:由於此案例只識別一個人員,無需對人員 ID 進行匹配,故不用指定人員 ID。
3.2.2 樹莓派配置
安裝系統訪問 www.raspberrypi.org 獲取映象,並進行安裝。注意必須安裝桌面版,否則需要單獨管理 HDMI 輸出。
配置網路進入命令列,執行 “raspi-config”,選擇"Network Options",配置 WiFi 接入點。為了固定 IP,編輯 /etc/dhcpcd.conf 檔案,新增配置資訊。
# 具體內容請參考你的本地網路規劃interface wlan0static ip_address=192.168.0.xx/24static routers=192.168.0.1static domain_name_servers=192.168.0.1 192.168.0.2
安裝騰訊雲 SDK參考指引文件,安裝呼叫騰訊雲 API 的依賴庫。
sudo apt-get install python-pip -ypip install tencentcloud-sdk-python
安裝影象處理庫
系統預設安裝 python2.7,但沒有 opencv 庫,需要安裝。(下載包體積較大,預設源為國外站,比較慢。樹莓派改國內源方法,請自行百度,並挑選離自己近的源站)
sudo apt-get install libopencv-dev -ysudo apt-get install python-opencv -y
部署程式碼
訪問github獲取原始碼,將 src 資料夾內容,複製到 /home/pi/faceid 下。
更改 /home/pi/faceid/config.json 中的配置資訊,必須改為你的雲 API 金鑰(sid/skey)、人員庫 ID(facegroupid),其它配置按需調整。
配置自啟動需要配置圖形介面自啟動,保證視訊輸出由 HDMI 介面輸出至顯示屏,編輯/home/pi/.config/autostart/faceid.desktop 寫入如下內容
Type=ApplicationExec=python /home/pi/faceid/main.py
3.2.3 硬體接線
樹莓派 GPIO 圖示
攝像頭
CSI 介面超聲波感測器
TrigPin:BCM-24 / GPIO24EchoPin:BCM-23 / GPIO23VCC :接 5VGND :接 GND繼電器
4 引腳側 接 樹莓派 GPIO 引腳
VCC :接 5VGND/RGND :接 GNDCH1 : BCM-12 / GPIO123 埠側 接 電磁鎖
初始狀態為電磁鎖接常閉端。繼電器原理請參考 3.3.4 硬體相關 部分。3.2.4 測試執行
完成上述工作後,接電啟動系統,本地反饋檢視顯示屏,雲端識別結果可檢視系統日誌。
3.3 程式碼邏輯與涉及技術
3.3.1 流程虛擬碼
# 監測鑑權程序-主程序獲取應用配置(API ID/Key 等)初始化GPIO引腳(準備控制 感測器、繼電器)啟動視訊管理程序(輔程序)迴圈開始: if not 測距達到觸發標準: continue 與輔程序通訊(捕獲當前幀,並存入指定路徑,並新增“認證中”水印) 呼叫雲API,使用該幀圖片人臉識別 if 識別成功: 與輔程序通訊(變更水印為“認證成功”) 等待5秒 關機 或 繼續執行(由config.json中 su2halt 欄位指定) else: 與輔程序通訊(變更水印為“認證失敗”) 等待2秒 與輔程序通訊(清除水印)# 視訊管理程序-輔程序初始化攝像頭迴圈開始: 取幀 取程序間共享佇列 按訊息進行不同操作(幀影象儲存/加不同水印/不處理) 輸出幀3.3.2 視訊與識別
實時視訊如上文虛擬碼所示,通過逐幀處理,並連續輸出,顯示實時視訊。
觸發識別測距感測器確認物體靠近,且 0.3 秒內距離變化小於 2cm,確認為待認證狀態。再延時 0.3 秒,進行影象幀捕獲。再次延時的原因是物體停止時,會有扭轉、微調等動作,若直接取幀,會由於採光不足(上文提到的約束)出現模糊情況,所以再次延時,確保捕獲穩定影象。
人臉識別請參考文件介紹(https://cloud.tencent.com/product/facerecognition)。
3.3.3 影象水印
水印原理opencv 中,提供了多種影象處理函式,如:圖文處理(圖加字)、圖圖處理(圖間加/減/乘/除/位運算)等等。通過不同的處理方式,可以實現底圖加字、底圖加圖、掩膜處理等等多種效果。本案例中使用的是基於位運算的掩膜處理方式。
水印圖片為了便於維護和更新,本案例中使用圖片做為水印來源,避免字型檔約束,也增大了靈活性,易於在水印中增加圖形,並以解析度直接定義水印大小,所見即所得。
預設水印圖片為白底黑字。
水印處理邏輯為突出水印的浮動效果,將水印圖片中的黑色區域透明化後,疊加到原始圖片中。由於字型透明效果,水印字型顏色隨基礎視訊變化,效果比較明顯。
原始碼說明
# img1為當前視訊幀(底圖),img2為已讀取水印圖def addpic(img1,img2): # 關注區域ROI-取底圖中將被水印圖編輯的影象 rows, cols = img2.shape[:2] roi = img1[:rows, :cols] # 圖片灰化-避免水印圖非純黑純白情況 img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # 生成掩膜-過濾淺色,位運算取非 ret, mask = cv2.threshold(img2gray, 220, 255, 3) #cv2.THRESH_BINARY mask_inv = cv2.bitwise_not(mask) # 生成水印區影象-底圖裁出字型部分,生成水印區最終影象,替換原圖水印區 img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv) dst = cv2.add(img1_bg, img2) img1[:rows, :cols] = dst return img1水印效果示意圖(示意圖擴大了水印區,用於突出效果,實際應用方案中水印區較小)
3.3.4 硬體相關
超聲波測距超聲波感測器(4 引腳:VCC、Trig、Echo、GND),Trig 端輸出一個大於 10μs 的高電平,啟用發出超聲波,並在收到反射波後,Echo 端會輸出一個持續高電平,持續時間就是“發波至收波”的時間。
即:測距結果(米)=Echo 端高電平時長*340 米/2
繼電器使用的 5V 繼電器模組有雙側接線,一側為供電與訊號(4 引腳,相容 3.3V 訊號),一側為通路開閉管理(3 埠)。
繼電器在“通路管理側”實現了一個“單刀雙開關”的模式,通過“供電與訊號”側“CH1 引腳”的高低電平,控制單刀的方向。
在安裝過程中,電磁鎖供電預設接繼電器常閉端,對繼電器給出訊號後,繼電器切換到常開端,則電磁鎖斷電開鎖.
GPIOGPIO(General-purpose input/output 通用輸入輸出),以引腳方式提供硬體間的聯絡能力。樹莓派 3B+,有 40 個 GPIO 引腳(請參考 3.2.3 硬體接線 中的參考圖示),樹莓派官方作業系統 Raspbian 下,可以使用系統預設安裝的 python 中 RPi.GPIO 庫,進行操作。
4.其它4.1 方案選型對比
設計的核心在於人臉鑑權模組,這裡直接影響成本和穩定性,最後選擇了上文方案(平衡成本、維護性及可靠性)。曾經的其它幾種備選人臉識別方案:
4.1.1 本地識別 A 方案:
使用 ESP-EYE 晶片,均由晶片完成,依賴 ESP-IDF、ESP—WHO,使用 C 進行開發。
低硬體成本(模組成本 189*2),高開發維護成本(C 開發)。
問題:難於更新配置與故障分析處理。適用於大量部署場景。
4.1.2 本地識別 B 方案:
使用樹莓派直接進行人臉識別,方案成熟,開原始碼豐富。
中硬體成本,低開發成本,高維護成本。
問題:樹莓派負載高,即使用間隔幀演算法,也僅維持在 20fps 以下,卡頓明顯。如進一步調優,受限於個人經驗問題,恐難以保持長期穩定執行。
4.1.3 本地識別 C 方案:
使用 BM1880 邊緣計算開發板 或其它影象處理板,社群口碑不錯,有框架支援。
問題:高硬體成本(模組成本 1000*2),高開發維護成本(C 開發)。如果使用算力棒,需要 X86_64 做基礎平臺,成本降低有限,複雜度不變。適用於擴充套件能力場景。
4.1.4 雲端識別 A 方案:
使用騰訊雲的視訊智慧分析產品(https://aivideo.cloud.tencent.com/list.html),簡化終端架構,使用樹莓派 zero 推流上雲(後續放出實現方案),即可獲取識別結果,且支援高頻多次檢索等特性。
部署成本低(終端視訊相關模組 150 元),運營成本低(當前 0.28 元/分鐘,按該場景下單次執行 20 分鐘計算,單次遊戲成本 5.6 元)
問題:對網路穩定性依賴大,斷流等情況影響體驗。在本案例的網路約束下,影響使用效果,更適於網路條件較好、高頻檢索的應用場景。