Max Jaderberg用於生成合成樣本的腳本解析

博主十分青睞於使用合成樣本來訓練模型,因爲這種方法非常簡單可依賴,而在text detection領域裏,提到合成樣本不得不說一下VGG組的工作,有關利用合成樣本(Synthetic Data)來訓練模型的文章大家可以去http://www.robots.ox.ac.uk/~vgg/research/text/下查找。其中一作Max Jaderberg把他們合成樣本的工具公開在了https://bitbucket.org/jaderberg/text-renderer/downloads 上面

裏面word_renderer.py就是用於生成合成樣本的主要腳本。這個腳本寫的非常長,但是閱讀起來並沒有太大的難度。這裏主要介紹一下運行這個腳本需要安裝什麼樣的依賴庫以及這個腳本的原理。


安裝

這個腳本是建立在pygam這個遊戲引擎基礎上的,大家下載pygame的時候一定要注意一點!——“一定不要在官網下源碼安裝,一定不要用apt-get install,一定要從bitbucket上下載,地址是

https://bitbucket.org/pygame/pygame

因爲官網給的源碼有庫丟失的情況!坑了個爹!

pygame的依賴庫有這麼幾個 freetype,以及sdl,sdl-image,sdl-ttf,sdl還有其他擴展庫可以不用安裝。

把pygame的幾個依賴庫安裝好了就可以編譯pygame了,一般大家自己安裝的時候都會遇到找不到pygame.freetype的情況,原因就是官網給的坑爹的源碼缺少freetype,大家可以去src文件夾去查看便知。


原理

挖個坑,之後寫

---------------------------------------------------------------1229 分割線-----------------------------------------------------------------------------

OK,開始填坑

1. main函數中,generate_sample()是關鍵的函數,所以下面我們要詳細講這個函數

2. generate_sample()中有如下幾步

2.1 生成一個隨機的字符串display_text,用來規定繪製的文字內容,label爲display_text的長度

2.2 聲明fs (Font State)用來聲明字體的大小,加粗程度,是否傾斜,是否有下劃線等等屬性

2.3 聲明bg_surf (pygame.Surface類) 用來做畫板,畫板初始化爲純黑畫板,也就是全0矩陣

2.4 下面是將display_text的每個字符按照從中間到兩邊的順序依次繪製到bg_surf上面。

字符繪製的方法如下:首先聲明rect用來記錄繪製字符的bounding box大小,然後用render_to函數以及被繪製文字的bounding box rect變量把文字繪製到bg_surf上面,並順帶將單字的bounding box放到數組char_bbs

字符繪製過程中會假如各種擾動,諸如curve以及rotation對字符串進行扭曲旋轉

2.5 繪製完文字,我們得到的bg_surf可以認爲是一個白底黑字的圖像。但是在這裏我要狠狠的指明的是,其實bg_surf在聲明的時候是RGBA通道,而經過2.4步的繪製之後,只有alpha通道是有非0值的,與繪製的文字對應,而RGB通道還是全0的

2.6 現在bg_surf還是一個pygame.Surface類,並不是數組類,利用get_ga_image函數把bg_surf轉爲bg_arr. 這裏着重講一下get_ga_image函數。裏面的pixels_red(), pixels_alpha() 我不解釋,我重點解釋一下n.concatenate((r,a), axis=2).swapaxes(0,1).    concatenate((r,a), axis=2) 是將R通道與Alpha通道疊成兩層,我們看到,R通道是放在前面的,而這個通道的值其實是全0的。swapaxes(0,1)的作用是將圖像轉置,因爲現在的圖像並不是我們所想的水平文本行,而是豎直的鏡像文本行。

2.7 bg_arr[...,0] = cs['colours'][0] 意思是給前景的文字灰度賦值,而cs是colour_state類,是通過灰度值聚類得到的。隨機選一個灰度中心給前景文字(後面會有操作把另一個灰度中心給背景)

2.8 'border' 關鍵字對應的是文字是否有陰影效果,這個效果是通過膨脹腐蝕得到的,陰影的部分也會有自己的cs值

2.9 下面就是做擾動了,affine與perspective

2.10 現在的文字是繪製在一個大的背景上的,我們只需要文字區域,所以需要把無用的背景給crop掉

2.11 canvas變量,這個變量是背景,灰度值取自cs

2.12 下面的操作是add_fillimage() 用來把前景l1_arr, 陰影l2_arr以及背景canvas與實際的背景圖像分別融合。

2.13 剩下的就是把前景l1_arr, 陰影l2_arr以及背景canvas融合。然後做一些模糊擾動什麼的。global_distortion() 函數裏面有一個坑是,爲了得到低分辨率的字,故意做了一次縮小放大的操作。所以如果你如果後期對圖像做一些改動,比如說不做crop,獲取含有大量背景的樣本,這步縮小放大操作會讓你得到根本認不出東西的樣本。

3. 需要提及的一個坑是:這個代碼給出的bounding box是極其不準的,大家需要針對固定字母固定大小寫調整相應的bounding box,當然這個僅僅是我給出的處理方法,並不是完全之策,校正了還是會出一些單字bounding box不準的現象

好歹是把坑填了……

有興趣的可以改一下代碼,比如生成下面這樣的樣本→ →(請忽略水印)











發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章