繼續影像處理專題,這次寫的是影像旋轉。若要說小解析度的影像旋轉倒也簡單,直接將原始影像儲存在BRAM中,然後按照旋轉後的位置關係取出便是。但是對於高分辨的影像(720P及以上)就必須得用DDR3或者DDR4快取了,而DDR是突發傳輸,對連續視訊流十分友好。所以在旋轉180°時倒也問題不大,但是若旋轉90°或者270°的話,每取出一個資料,
就要跨行一次,而DDR跨行傳輸的效率極低,經測量大概是10%左右,根本無法滿足實時性要求。
那麼,又該怎麼解決旋轉90°或者270°DDR傳輸效率低的問題呢?我查閱了大量資料,有一種方法是改用sram儲存影像,這樣便沒有跨行傳輸效率低下的問題。但是現在FPGA的開發板普遍帶的是DDR,也沒有必要為了影像旋轉這個功能重新設計電路,增加sram晶片。另一種方法則是改變DDR讀寫影像的方式,這裡也有兩種方案。方案1是對DDR進行分塊,DDR的一塊儲存一行有效影像資料,這樣就使得DDR跨行次數減少。同時由於DDR位寬大於畫素資料位寬,所以每讀取一個資料就能獲得數個畫素點,可供幾次旋轉90°或者270°使用。
方案2是對影像進行分塊,寫入DDR時按照分塊尺寸對應關係,每一行寫入一個分塊,這個方法同樣會使得旋轉操作後讀取DDR跨行變少。有些人或許就會疑問,連續的視訊流怎麼分塊呢?視訊的確是連續進入的,可是我們可以控制寫入的地址,假如解析度是1920*1080,分塊是192*10,那麼在DDR寫到192-8地址時,就直接跳轉到0+DDR列長度處了,進而實現DDR的一塊儲存原影像的一行資料。
這裡的話,我選擇的是第一種方案,即DDR的一塊儲存原影像一行有效資料,並在720P和1080P各種制式下驗證通過,具體實現細節見下一篇部落格。
事實上,我只實現了直角旋轉,即旋轉90°,旋轉180°,旋轉270°。而想實現任意角度旋轉的話則思路一致,即重新排列影像寫入DDR順序,使得讀DDR跨行操作次數降低,而關於這一點,萬方上有一篇名叫“基於FPGA的數字影像旋轉引擎設計”(李傑明)的論文,大家有興趣的可以去查閱觀看。