概述
本文描述一個基于人工智能2D圖像識別算法實現的繪本閱讀方案,應用于繪本閱讀機器人和繪本閱讀手機App。主要內容包括:基礎算法,方案架構及工程化,項目遇到的坑及解決方案。為了更容易理解,本文重點描述項目的工程化,對于算法也做一定程度的闡述、但不做深入,相關算法資料及論文在互聯網可方便搜到。
基礎算法
算法方案選型:
本項目要解決的核心問題是:在低算力的硬件上通過普通攝像頭(2D)采集圖像快速(<1s)定位到是哪一本繪本的哪一頁,即需要通過計算機視覺算法來評估當前攝像頭圖像幀是否存在一個預置的特有FLAG。項目技術方案評估過方法主要有:
1) 基于目標分類算法,可以看作是一種圖像分類的問題。先對繪本封面圖像進行分類定位,找到對應繪本后,再對繪本內頁圖像分類定位。這個方法理論是可行的,但分布封面的分類過多(可能有超過兩萬本繪本),而且算法復雜度高,實際并不可行。
2)另外還有目標檢測的算法,但對于繪本圖像來說,并沒有相對固定的特征(例如人,動植物等),所以這個方法也不可行。
3)基于圖像特征匹配的圖像識別,即對兩個圖像的特征進行匹配來預測是否為相同圖像,這個算法復雜度較低,算法魯棒性強,且繪本圖像天然有較多的圖像特征,這個方法與項目需求是非常匹配的,其實在技術選型時,就很快確定了這個算法基礎。、
基礎算法描述
圖像特征匹配中算法基礎是特征因子算法,如SIFT, SURF, FAST, ORB等,綜合算法的魯棒性和復雜度,項目主要采用的是SURF和SIFT算法因子。以下是基于SURF算法因子匹配對兩個圖像進行匹配的代碼片段,可以大概感受下:
... img1 = cv2.imread(imgname1) img1 = cv2.resize(img1, (600, 400)) kp1, des1 = surf.detectAndCompute(img1,None) #des是特向量 img2 = cv2.imread(imgname2) img2 = cv2.resize(img2, (600, 400)) kp2, des2 = surf.detectAndCompute(img2,None) matches = flann.knnMatch(des1,des2,k=2) ...
算法層面上,實現了圖像特征匹配還是不夠,因為還有解決一個問題:在大數量的圖像中(如10000+的繪本封面圖像)快速定位到目標圖像,如果程序是一張一張圖像的比較匹配,時效是非常低,完全達不到秒識別的要求。這時需要引用圖像檢索的算法,項目實現兩種圖像檢索算法,建立圖像索引,大概如下:
1)KD-tree, 基于樹型布局的索引分為向量空間和度量空間。向量空間使用歐式距離來比較特征相似度,度量空間不使用歐式距離來比較特征相似度,KD-Tree是典型的基于二叉樹的索引結構。
2)K-means,其首先通過聚類方法構建聚類中心,將圖像特征庫分成許多簇(類)。檢索時,查詢圖像的特征向量先和聚類中心向量比較,計算向量間的距離,然后只需在距離較近的簇中進行檢索。
總的來說,繪本圖像的識別與查字典類似:先通過圖像檢索定位到少量的目標圖像,然后再通過特征匹配預測出目標圖像。
工程化
確定了算法基礎,接下來就是充滿荊棘的項目開發和落地的過程。
攝像頭方案
首先是攝像頭方案選定。攝像頭是產品的“眼睛”,攝像頭方案對于識別的效果是有關鍵作用的,主要目的是保證攝像頭有效成像區域覆蓋絕大部分尺寸繪本翻開后的尺寸,而有效成像區域是攝像頭采集到的、可用于視覺分析的圖像,邊角圖像畸變大、失真屬于無效成像區域。攝像的方案主要考慮以下因素:
1)因為攝像頭是固定安裝的且與采集圖像的距離是相對固定,因此攝像頭需要時定焦的,避免對焦過程,圖像不清晰影響到識別效果。
2)FOV(攝像頭視場角度),FOV越大,成像區域越廣,但也會帶來畸變,FOV的選定要結合產品結構。本項目攝像頭的FOV是110°
3)攝像頭的高度(H)和傾斜角(α)直接影響到有效成像區域,在符合“有效成像區域覆蓋絕大部分尺寸繪本翻開后的尺寸”的產品需求下,根據結構綜合決定。本項目中,H是13cm,α是40°
軟件架構
整體軟件架構是經過不斷設計,驗證和優化得出的。
軟件主要分三部分:
1、繪本SDK,包括Android 和 linux SDK,核心算法部分是C++寫的,在Android中通過NDK融合到SDK中。SDK包含本地識別和云識別模塊。本地識別主要包括:檢索和識別算法,不同系統的交互邏輯;云識別模塊:云服務器交互的客戶端部分功能(如各種HTTP Client)。
2、云識別服務,核心算法部分是C++寫的單獨程序,在云上部署方式非常靈活,結合集群、均衡負載、緩存等可提升云服務性能和穩定性。前后端通過HTTP POST 圖像數據為主要接口。
3、繪本訓練管理系統,是C++寫的程序,實現繪本數據自動批量上線:包括繪本資源數據上傳到CDN存儲服務器,繪本封面圖典文件(圖典下面詳述)上傳,每一本繪本圖典文件上傳,數據更新上線。
云服務器部署:
云識別服務器是單獨高計算服務,對于服務器的高并發、高可用的追求,可用從集群、均衡負載、算法輕量化、圖像信息壓縮傳輸、熱點數據緩存等方面考慮。以下是一個部署方案的參考:
圖典
是實現是算法工程化的重要一步,解決的問題是將所有繪本的圖像特征和圖像索引按特定數據結構描述并存儲,而且圖典支持疊加更新。
主要數據結構
1、indexedDescriptors 特征向量描述列表,保存所有圖像特征向量的列表,相似的特征向量會唯一元素存儲。
2、wordToObject特征向量ID和圖像ID的map,存儲obj(即預存圖像)與向量特征列表的ID的對應關系
3、scene是攝像頭采集當前幀的圖像特征向量列表,vocabulary是圖典索引,數據結構跟圖像檢索算法有關:KD-Tree是二叉樹;K-means是n叉樹,具體樹的結構暫不展開。下圖描述scene的特征向量從vocabulary索引中檢索到最有可能匹配的特征向量以及在indexedDescriptors中的id,檢索出來后,根據wordToObject算出最有可能匹配的圖像。
存儲方式
1、本項目中,圖典是保存成文件,所有繪本的封面圖像保存成一個圖典文件,每一本繪本的封面和所有內頁圖像保存為一個圖典文件。對于此類部分結構化數據,可以保存數據庫中(NoSQL)。存儲為文件,主要考慮到開發和運維便利。
項目方案
實施方案
結合產品需求,實施方案有以下兩種:
1、離在線結合方案:
1)封面在云服務識別,服務器性能和存儲可根據性能要求伸縮,支持大數量圖像準確檢索(數萬繪本封面);
2)識別到封面后,本地SDK下載并加載對應封面繪本的圖典文件,本地實時識別當前翻到對應內頁圖像。
2、離線方案
1)封面和所有繪本圖典文件預先下載到本地,本地進行繪本封面和繪本內頁圖像檢索識別。這個方案在算力和存儲較低的設備上,支持繪本的數量有限。
繪本訓練上線
繪本訓練上線是通過繪本訓練管理系統完成的,工作原理和流程是:
1、制作繪本數據:包括繪本封面和內頁圖像 以及 封面和每一內頁對應的音頻
2、將繪本數據圖片和音頻按特定目錄文件命名存放,如下圖是my dad繪本的命名例子,圖片和音頻命名一一對應,如圖片沒有對應音頻,則空缺。
3、繪本訓練管理系統根據命名讀取圖像生成所有繪本封面圖典和每一繪本的圖典文件,同時將圖典文件、繪本圖片和音頻上傳到CDN靜態存儲服務器,將靜態文件URL以及繪本信息(ID,書名,ISBN號等)上線到數據庫。
工作流程
以下以離在線結合方案描述繪本閱讀程序一個正常基本的流程,通過云服務識別繪本封面,識別到封面定位到繪本后,加載對應繪本的圖典,繪本SDK本地識別繪本內頁圖像,識別到一頁播放對應頁的音頻,實現 放置哪一步繪本,讀那一本繪本;翻哪一頁,讀那一頁內容。
項目經驗分享
繪本訓練
繪本訓練的方案確定、開發、實施經歷一些曲折,這里也分享下。
1、雖然SIFT等特征因子算法具備方向、尺度等不變性,考慮識別效果,最初繪本訓練的方案是通過繪本機器人攝像頭來采集繪本圖像進行訓練,保持訓練圖像和實際使用采集圖像的角度一直性。但這個方案需要繪本書本,且需要人力一本一本地訓練,不具備大批量操作的可行性。
2、繪本訓練方案必須自動化、大批量進行,所以把出版社的繪本高清掃描圖作為訓練數據似乎是唯一的方案,但這個方案還需解決圖像視角不一致的問題以提高識別率,如下圖,一張是繪本機器人攝像頭采集的圖像(灰度化),另一張是出版社繪本掃描圖,兩者視角有差異。解決訓練圖像與采集圖像的視角差異的方法是:將采集圖像通過透視變換將視角轉換與訓練圖像一致后,再做特征提取。
圖像處理優化
每一幀采集圖像的處理(特征提取和檢索)都需要一定算力,提高計算資源效率一個方法是圖像采集后預測圖像是否包含繪本圖像,預測到有繪本圖像才進行特征提取和檢索。通過圖像熵值可以比較有效預測當前圖像是否有繪本圖像(具體方法參考代碼)。
圖像前后端傳輸
前端攝像頭采集的圖像可以直接將圖像信息完整發送到后端進行識別,比較好的方法是將圖像灰度化,去除無效數據后、再壓縮傳輸。
云服務數據存儲
在繪本數量不大的情況下,服務器上的繪本數據可以都從redis緩存獲取,提高性能。