OCR在轉轉游戲的應用
1.什么是OCR?
OCR(optical character recognition)是將圖片進行掃描,提取其中的文字的技術。如今,不少業務領域都用到了OCR技術。比如某些快遞軟件支持識別包含地址信息的圖片,解析出用戶地址。
2.游戲業務引入OCR的背景
在用戶發布游戲商品時,我們希望用戶將參數填得越全越好,這樣有助于搜索、個性化推薦、統計數據。但是,以王者榮耀為例,目前王者榮耀有400+皮膚,將所有擁有的皮膚填寫一遍非常麻煩,所以我們希望通過用戶上傳圖片或商品封面,提取其中的參數信息,填入商品信息中,以達到補全參數、減少用戶操作的目的。
3.問題
目前騰訊、百度、58等公司都提供了OCR識別API,轉轉也有自研的OCR能力,對一張用戶上傳的圖片進行OCR識別可以得到一個文本集合。
結合OCR識別結果我們可以發現一些問題
- 圖中有10個皮膚,但是用戶只擁有5個皮膚,灰色的皮膚是未擁有的,我們不希望將用戶未擁有的皮膚也識別出來。
- 對復雜文字支持不是很好,比如把“李信一念神魔”識別為了“李信一念神度”,把“橘右京楓霜盡”識別為了“椅右京楓霜盡”,所以在進行參數匹配時,我們希望有一定容錯性。
由此產生了兩個要解決的問題
- 只識別擁有的皮膚
- 匹配時有一定容錯
4.如何只識別擁有的皮膚
通過觀察用戶上傳的圖片我們可以發現:
- 圖片可以分為10個皮膚區域以及背景區域,我們只關注皮膚區域,所以需要先想辦法將皮膚區域與背景區域分離。
- 劃分完皮膚區域后,我們可以對10個區域依次進行判斷,區分出這到底是一個未擁有的皮膚區域還是已擁有的皮膚區域。
4.1.劃分皮膚區域
如何將皮膚區域和背景區域分離呢?通過觀察我們能看到:
- 背景區域的顏色比較單調,大部分大都是藍色、灰色以及右側的一些白色絲帶。
- 皮膚區域色彩會豐富一些,有各種炫酷的色彩和藝術字。
所以是否能嘗試使用色彩數來區分皮膚區域和背景區域呢?
對用戶上傳圖片的色彩數量進行統計,得到以下趨勢:
上圖為從橫向開始遍歷,使用Set對縱向所有像素的顏色進行去重,得到的顏色數量變化趨勢。可以看出,五個較為明顯的凸起即對應了圖上的5列皮膚。
上圖為從縱向開始遍歷,使用Set對橫向所有像素的顏色進行去重,得到的顏色數量變化趨勢??梢钥闯觯瑑蓚€較為明顯的凸起即對應了圖上的2行皮膚。
因此,如果某個點附近顏色數量發生劇烈變化就可以認為這是一個邊界點,相鄰兩個邊界點相連可以組成線段,橫向的線段和縱向的線段相連可以組成矩形。按照這個思路對圖片進行劃分后效果如下。
這樣就初步實現了將皮膚區域和背景區域分離
4.2保留擁有的皮膚
對于已擁有的皮膚和未擁有的皮膚,他們的顏色數量都很豐富,繼續用顏色數量區分的效果不是很理想,那如何進行區分呢?
- 已擁有的皮膚區域:整體比較鮮艷,所以飽和度高、亮度高的像素占比更高
- 未擁有的皮膚區域:整體比較暗淡,所以飽和度高、亮度高的像素占比低
所以,我們可以在劃分矩形后,首先對矩形的長寬比進行初次過濾,然后提取矩形中像素的顏色,計算亮度和飽和度大于閾值的像素占比,保留占比高的矩形
在對閾值進行一些調優后,最終保留結果如下。
這樣,在進行OCR識別時,就不會把未擁有的皮膚也識別出來了。
5.解決匹配時的容錯
要將“李信一念神度”匹配為“李信一念神魔”這個參數,基本思路是計算兩個文本的重復度,如果高于一個閾值即可認定是相同的文本,目前文本相似度計算有兩種大致方向:
- 基于NLP
提取兩個文本的特征向量,計算向量空間兩個向量夾角的余弦相似度。
- 基于串匹配
將字符串進行分割,統計子串是否相同。
為了方便我們采用了第二種方法,在串匹配算法中我們選擇了Rabin-Karp算法,其具體思路是使用滑動窗口得出文本的哈希集合,對兩個哈希集合進行比對,計算出相似度。
例如:我們使用窗口大小為2,每次滑動1對“李信一念神魔”和“李信一念神度”進行分割,可以得到:
[ "李信" , "信一" , "一念" , "念神" , "神魔" ]
[ "李信" , "信一" , "一念" , "念神" , "神度" ]
而對窗口中元素計算哈希的操作我們可以交給String類的hashCode()方法,所以兩個文本計算相似度方法大致如下:
在上述過程中,向HashSet中增加元素,以及使用contains方法判斷HashSet中是否包含元素時,都是基于String類自帶的hashCode()方法進行的:
由于我們的文本量比較小,對于這種哈希計算方式,是完全滿足我們的需求的。
而Rabin-Karp算法認為,在文本量非常大的情況下,先分割窗口然后每次對窗口中的元素單獨計算哈希效率是低下的,可以通過改良計算方式,使下一個窗口的哈希與
- 上一個窗口的哈希
- 離開窗口的元素
- 進入窗口的元素
產生關聯,加快運算速度,所以給出了一種更快分割窗口并且計算哈希的方式:
如果一個業務場景需要匹配的文本量非常大,可以嘗試選用這種方式。
最終,我們的匹配流程大致如下,在系統啟動時,會拉取我們的參數庫,使用上面的方式對每個參數進行預處理,得到它們的哈希集合,存到本地,當一個OCR識別結果產生時,計算它的哈希集合,與本地進行匹配,如果發現相似度大于閾值,即認為匹配成功。
這樣,我們就保證了一定的容錯性。
6.效果
當我們解決了:只識別擁有的皮膚、匹配時有一定容錯,這兩個問題后就可以線上部署了。
目前OCR只應用在王者榮耀、和平精英兩款游戲,上線后每日可為我們的商品補充上千參數。后續會逐步擴展到其他游戲品類。
作者簡介:
常睿,轉轉訂單業務Java研發工程師。