halcon旋转后坐标_FPGA大赛【八】具体模块设计图像旋转方案
生活随笔
收集整理的這篇文章主要介紹了
halcon旋转后坐标_FPGA大赛【八】具体模块设计图像旋转方案
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
【注】該項(xiàng)目是我們團(tuán)隊(duì)參加2019屆全國大學(xué)生FPGA大賽的作品,系統(tǒng)主要實(shí)現(xiàn)視頻任意角度旋轉(zhuǎn)。該項(xiàng)目最終晉級決賽,并獲得紫光同創(chuàng)企業(yè)特別獎。該系列文章介紹我們團(tuán)隊(duì)的作品。關(guān)注公眾號“數(shù)字積木”對話框回復(fù) FPGA2019 ,即可獲得該項(xiàng)目的工程源代碼,詳細(xì)的文檔說明,MATLAB仿真代碼。
4.6圖像旋轉(zhuǎn)方案
4.6.1總體方案
標(biāo)準(zhǔn)模式下,從攝像頭獲取到圖像數(shù)據(jù),將該圖像數(shù)據(jù)緩存到DDR中,再通過顯示驅(qū)動模塊將圖像讀取出來,在顯示屏上進(jìn)行顯示。?圖像數(shù)據(jù)通過AXI接口寫入到DDR中,通過AXI總線從DDR中讀取。這期間要跨三個(gè)時(shí)鐘域。分別是 攝像頭數(shù)據(jù)輸出時(shí)鐘,AXI讀寫時(shí)鐘,顯示屏驅(qū)動時(shí)鐘。在跨時(shí)鐘域傳輸數(shù)據(jù)時(shí),數(shù)據(jù)都要經(jīng)過fifo緩存。?在圖像旋轉(zhuǎn)設(shè)計(jì)中,插入一個(gè)圖像旋轉(zhuǎn)模塊。將從攝像頭緩存的圖像先讀取出來,組合成一幀旋轉(zhuǎn)的圖像后再寫入ddr中,再由顯示驅(qū)動模塊讀取進(jìn)行顯示。4.6.2數(shù)據(jù)傳輸方案
ddr中數(shù)據(jù)的讀取采用AXI協(xié)議。數(shù)據(jù)從攝像頭寫入ddr,從ddr讀出傳輸?shù)斤@示模塊,均采用axi的突發(fā)傳輸。因?yàn)閿?shù)據(jù)都是按照相同的順序進(jìn)行儲存和讀取,故只需要按照順序進(jìn)行數(shù)據(jù)的突發(fā)寫入和讀取即可正確的顯示一張圖片。?而在進(jìn)行旋轉(zhuǎn)操作中,由于旋轉(zhuǎn)后的圖片和原圖的坐標(biāo)不是順序?qū)?yīng)的,旋轉(zhuǎn)輸出圖像數(shù)據(jù)由若干個(gè)不是順序排列的原圖像數(shù)據(jù)決定的,故對于原圖像數(shù)據(jù)的讀取,利用突發(fā)傳輸反而浪費(fèi)時(shí)間,且突發(fā)讀取到的數(shù)據(jù)中可用的數(shù)據(jù)占比較少。?對原圖像的數(shù)據(jù)讀取擬采用突發(fā)長度為1的傳輸。根據(jù)旋轉(zhuǎn)圖像的所需要的原始圖像的數(shù)據(jù)來讀取所需地址的數(shù)據(jù),用于重建旋轉(zhuǎn)后的圖像。?旋轉(zhuǎn)后的圖像數(shù)據(jù)也經(jīng)過突發(fā)長度為1的方式寫入進(jìn)ddr中。?旋轉(zhuǎn)圖像的重建模塊的始終頻率設(shè)置為和axi的時(shí)鐘頻率一致,一來可以不使用fifo來數(shù)據(jù)緩存,二來,該時(shí)鐘頻率為100MHz,運(yùn)行速度也更快。4.6.3圖像幀處理
在讀取原圖時(shí),如果原圖像在不停地儲存更新,那么重建的旋轉(zhuǎn)是由多幀圖像組合而成的,該圖像便會出錯(cuò)。如果在旋轉(zhuǎn)圖像儲存過程中便讀取該圖像進(jìn)行顯示,顯示圖像的幀率大于旋轉(zhuǎn)圖像重建的幀率,顯示的圖像也會出錯(cuò)。?該方案采用了降幀的方案。在圖像儲存時(shí),不對輸入的每一幀圖像都進(jìn)行儲存。當(dāng)儲存完了一張圖后,停止儲存下一幀的圖片,然后旋轉(zhuǎn)控制模塊便開始讀取這一幀圖片,進(jìn)行旋轉(zhuǎn)重建,待到這一幀圖片旋轉(zhuǎn)重建完成后,才開始接受下一幀的圖片。這樣便保障了讀取時(shí)原圖的完整性。?在將圖片重建后,需要進(jìn)行儲存,利用乒乓操作,將重建的圖像利用兩個(gè)空間進(jìn)行儲存。當(dāng)向空間1寫入重建的圖像數(shù)據(jù)時(shí),不斷讀取空間2的圖像數(shù)據(jù)進(jìn)行顯示。直到空間1的一幀圖像數(shù)據(jù)寫入完成,且該幀顯示結(jié)束,交換讀寫地址,將重建的圖像數(shù)據(jù)寫入到空間2,同時(shí)讀取空間1的數(shù)據(jù)進(jìn)行顯示。由于重建的幀率小于顯示的幀率,一個(gè)空間的圖像數(shù)據(jù)需要重復(fù)顯示多次。?如上所述,在該方案中,原圖的輸入,旋轉(zhuǎn)圖像的重建都進(jìn)行了降幀處理。但圖像顯示沒有做降幀處理,但在沒有交換讀寫地址時(shí),會重復(fù)顯示儲存在該空間的一幀圖片,呈現(xiàn)出動態(tài)刷新,靜態(tài)顯示的效果。4.7圖像旋轉(zhuǎn)計(jì)算
4.7.1圖像旋轉(zhuǎn)原理
圖像旋轉(zhuǎn)的本質(zhì)利用的是向量的旋轉(zhuǎn),而在MATLAB等算法工具中向量的計(jì)算往往轉(zhuǎn)換成相應(yīng)矩陣的計(jì)算,向量是幾何中的概念,因此在算法的編譯中常常不直接進(jìn)行向量的運(yùn)算,而是將其轉(zhuǎn)換成在極坐標(biāo)中的對應(yīng)坐標(biāo)矩陣來進(jìn)行算法的構(gòu)建。?矩陣乘法的實(shí)質(zhì)是進(jìn)行線性變換,因此對一個(gè)向量進(jìn)行旋轉(zhuǎn)操作也可以,通過矩陣和向量所對應(yīng)的特征矩陣相乘的方式進(jìn)行,而這在大多數(shù)的計(jì)算機(jī)語言中是通用的方法。正是因?yàn)檫@一點(diǎn),在圖像旋轉(zhuǎn)的這個(gè)模塊中,采用了構(gòu)建特征矩陣進(jìn)行坐標(biāo)轉(zhuǎn)化這個(gè)思路。具體思路如下。假設(shè)有二維向量v = [x ; y],其中x,y是原圖的像素點(diǎn)的橫軸和縱軸坐標(biāo)。若要進(jìn)行逆時(shí)針旋轉(zhuǎn)角度a。則旋轉(zhuǎn)矩陣R為:旋轉(zhuǎn)后的向量 Ro = R * v。Ro =[Xo,Yo]; ?其中Xo, Yo 是輸出圖像的坐標(biāo)值。?在正式處理過程中可以這么表示,原像素位置記為p,中心點(diǎn)記為c,旋轉(zhuǎn)后像素位置記為pp。則有(pp - c) = R*(p - c),即:pp = R*(p-c) + c4.7.2輸入輸出圖像坐標(biāo)的方案選擇
方案一:在此方案中,實(shí)現(xiàn)代碼的方式是正向的思路,將原圖中的像素點(diǎn)的坐標(biāo)進(jìn)行坐標(biāo)的旋轉(zhuǎn),然后直接幅值到輸出的圖像中,此方案旨在找到輸入坐標(biāo)與輸出坐標(biāo)之間的代數(shù)對應(yīng)關(guān)系,以此來進(jìn)行Verilog代碼的編寫。?但在實(shí)際的分析的過程中,先采用極坐標(biāo)系進(jìn)行分析,得到了對應(yīng)的坐標(biāo)對應(yīng)關(guān)系,如下圖所示:在該方法中,首先將原始坐標(biāo)以及目標(biāo)坐標(biāo)放入了極坐標(biāo)中,并且通過在極坐標(biāo)中的關(guān)系,找到了同時(shí)滿足X0,Y0,X1,Y1四個(gè)參量的方程組,以此來解出對應(yīng)的坐標(biāo)關(guān)系,并以此為基礎(chǔ)得到了輸入與輸出之間的矩陣運(yùn)算關(guān)系如下:這樣就解決了坐標(biāo)的代數(shù)關(guān)系。但在實(shí)際的測試中發(fā)現(xiàn),這種方法所旋轉(zhuǎn)得到的圖像有著較為嚴(yán)重的失真現(xiàn)象,具體情況如下圖所示:?很明顯可以看到,在旋轉(zhuǎn)之后這兩張圖片出現(xiàn)了較大的差別,首先是原圖像被裁減了,其次是目標(biāo)圖像中有較多的瑕點(diǎn)(雜點(diǎn))。究其原因在于,從原圖旋轉(zhuǎn)后得到的目標(biāo)圖像的像素位置在原圖中找不到。另外就是邊緣被裁剪的問題,由于在這個(gè)方案中約束了顯示區(qū)域,因此在旋轉(zhuǎn)的過程中,部分像素點(diǎn)就會由于超出邊界而被裁剪。針對以上的兩個(gè)問題,進(jìn)行了如下改進(jìn)。方案二:由于在之前的方案中出現(xiàn)了雜點(diǎn)以及圖像邊緣裁剪的問題,因此在本方案中,我們采用了逆向思維,用目標(biāo)圖像的坐標(biāo)去與原圖的坐標(biāo)進(jìn)行坐標(biāo)匹配,若在原圖像中能找到匹配的圖像,就顯示該點(diǎn)旋轉(zhuǎn)后的點(diǎn)坐標(biāo),若在原圖中找不到該點(diǎn),則不顯示該點(diǎn),通過這樣就解決了雜點(diǎn)的問題,具體所限定的原圖的查找區(qū)域代碼如圖所示:?其中,pp為旋轉(zhuǎn)在后的坐標(biāo)對應(yīng)矩陣,在if語句中限定了原圖的區(qū)域,用此區(qū)域則可以到原圖中的坐標(biāo)點(diǎn),以此來排除不在區(qū)域中的坐標(biāo)點(diǎn),這樣就可以解決雜點(diǎn)的問題。(以上是前期在MATLAB中的仿真代碼截取)在這種方案下,坐標(biāo)的對應(yīng)關(guān)系如下:這樣,該旋轉(zhuǎn)后的圖像就有了較好的還原度,達(dá)到了相應(yīng)的題目要求,具體的方案的效果如下圖所示:? ? ? 如圖所示,相對方案一而言,圖像的效果就好了很多,但圖像邊緣仍然存在邊緣被切割的現(xiàn)象,因此在第三種方案中,對代碼進(jìn)一步進(jìn)行優(yōu)化。?方案三:考慮到未對旋轉(zhuǎn)后的圖像進(jìn)行顯示區(qū)域的劃分,因此此類旋轉(zhuǎn)只是對單一像素點(diǎn)的旋轉(zhuǎn),然后在原圖像的顯示區(qū)域上進(jìn)行坐標(biāo)點(diǎn)的重新組合,得到顯示的圖像。在解決的方法的思路上,采用目標(biāo)顯示區(qū)域的重新劃分來解決該問題。具體思路是,采用原圖像的長寬作為基準(zhǔn),再用坐標(biāo)轉(zhuǎn)換的關(guān)系,將長和寬轉(zhuǎn)換到旋轉(zhuǎn)后的坐標(biāo)系中,得到目標(biāo)圖像在旋轉(zhuǎn)后坐標(biāo)系中的顯示區(qū)域,具體如下:這樣,就解決了圖像邊緣被裁剪的問題,是整個(gè)圖像得以完整的顯示,實(shí)際的效果如下:從圖示的效果可以看出,邊緣區(qū)域被裁剪的問題被解決了,但問題是圖片加陰影的區(qū)域面積比原圖大很多。?但在實(shí)際的操作中,采用這一類的圖像點(diǎn)坐標(biāo)的對應(yīng)關(guān)系,產(chǎn)生的結(jié)果與預(yù)期有著較大的誤差,圖像的效果較差,因此為了更好的進(jìn)行圖像的處理,我們又在網(wǎng)絡(luò)上尋找了CORDIC算法,以此來得到更好的處理效果。?4.7.3旋轉(zhuǎn)坐標(biāo)計(jì)算
在該設(shè)計(jì)中,要求圖像擁有0到360的任意角度的旋轉(zhuǎn),坐標(biāo)變換需要角度的正弦和余弦值。?利用matlab生成正余弦表,并將其擴(kuò)大256倍,打印到文件中。利用得到的正余弦表數(shù)值,將其寫入verilog代碼中,生成正余弦查找表。通過輸入角度值來索引其正余弦數(shù)值。Matlab生成正余弦列表的代碼如下;?該正弦,余弦通過MATLAB計(jì)算得到,并預(yù)先儲存到FPGA的片上儲存空間中,在進(jìn)行坐標(biāo)變換時(shí),讀取對應(yīng)角度的正弦,余弦值,進(jìn)行坐標(biāo)變換。由于計(jì)算得到的正弦和余弦值為浮點(diǎn)數(shù),而FPGA擅長于進(jìn)行整數(shù)運(yùn)算。故要進(jìn)行浮點(diǎn)數(shù)到整數(shù)的轉(zhuǎn)換,具體的實(shí)現(xiàn)方法是,將計(jì)算得到的浮點(diǎn)正弦,余弦值乘上 256 后再取整,計(jì)算得到的結(jié)果于原結(jié)果相比被擴(kuò)大了256倍,而在數(shù)字電路中,除法操作可以用移位來進(jìn)行。結(jié)果右移8位即等效于除于256 。坐標(biāo)變換的核心代碼如下:?將坐標(biāo)變換計(jì)算模塊封裝為一個(gè)子模塊,輸入輸出圖像的坐標(biāo)和旋轉(zhuǎn)角度后,即可計(jì)算出對應(yīng)的輸入圖像對應(yīng)的像素的坐標(biāo)。然后讀取該坐標(biāo)的像素值,寫入到旋轉(zhuǎn)重建的圖像對應(yīng)的坐標(biāo)位置即可。本文完!!!歡迎關(guān)注,更精彩的內(nèi)容等著你!總結(jié)
以上是生活随笔為你收集整理的halcon旋转后坐标_FPGA大赛【八】具体模块设计图像旋转方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: B站上线“高考模拟器”:带你重做当年高考
- 下一篇: 上手苹果iOS 16新系统:不仅在画饼