最近花了點時間,把以前沒做好的事情仔細整理了一下。一看時間,隔了有半年之久。慚愧慚愧。。。。其實以前都沒有仔細考慮清楚到底是怎么樣的事情,只是照着別人的思路把程序寫下來而已,這幾天重新做了幾個實驗,仔細考慮了一番。
一、以前的BUG
以前的結果中,圖片中有一條橫線,效果也感覺不對,其實是程序中的BUG。是在我的插值函數中:
1 uchar *data1 = imageWater.data + y[0]*imageWater.step + x[0]*imageChannels; 2 uchar *data2 = imageWater.data + y[0]*imageWater.step + x[1]*imageChannels; 3 uchar *data3 = imageWater.data + y[1]*imageWater.step + x[0]*imageChannels; 4 uchar *data4 = imageWater.data + y[1]*imageWater.step + x[1]*imageChannels;
我是在imageInfo中存儲原圖片的數據,imageWater中用來存儲變換過后的圖片。顯然在插值過程中,目標點周圍四個整數點應該是取原圖中的數據。所以應該將上述代碼中的imageWater.data全部替換成 imageInfo.data。這次的效果圖如下:
這一次就沒有中間那一條線,效果也比上一篇文章中的效果好多了。
二、新的問題
仔細觀察右圖你會發現,尤其是右下角,你會發現一些扭曲的紋路(其實是老師發現的),這是怎么產生的?其實我自己也不知道是不是應該出現這種情況。我開始的想法是:
r' = r + a*sin(b*r) a,b 是合適的常數,r是當前點的半徑。對於不同的r, 顯然a*sin(b*r)的值是不一樣的 。所以算出來的新圖片中,有些點會比較密集,有些點會比較稀疏。
接下來,我做了一張網格圖,然后就會出現如下的效果:
這個樣子有點嚇人,怎么會是這樣?網格圖比較復雜,那我就去做一張全部是半徑的圖,來看看效果:
現在看起來,右圖中的現象好像可以解釋了,方框中的幾個地方明顯可以看出,點稠密和點稀疏的地方,直線最外面都斷開了。那么中間的圓圈是怎么回事,是因為,越到圓心,每條直線之間的間隔就越來越小,有些點稠密的地方就連在了一起,形成一個圈。我最開始的想法看來是沒有什么大問題的。
那么那個網格圖是怎么回事情呢?應該用下面的圖說明問題比較好。
最下面的點是圓心,A點距離圓心比較遠,B點距離圓心比較近,假設在ra' = ra + a*sin(b*ra) 中 a*sin(b*ra)為正, ra' > ra,同理,rb' < rb。於是,原本是直線,經運算過后,變成了曲線。在網格圖中,橫向的直線跟縱向的直線疊加在一起,就造成了那樣的效果。如果只存在縱向的直線,效果如下:
為什么會出現這樣的曲線,我覺得應該弄清楚了。
三、總結
之后,我再sin()函數里加了一個變量,制作出很多幀圖片,合成一個視頻。(優酷應該壓縮了,與第一組圖片對比,看着很模糊,將就看吧。)
視頻中,看起來有水波紋的樣子,但是感覺效果還是不太好。
其實,我把整個問題搞反了。正確的思考方式應該是,思考水波紋的圖片是由原圖怎么來得到的。思考每一個像素點應該怎么樣移動,並由此推出一個公式,再來驗證結果。也就是說,對於那樣的網格圖,我們應該先思考,怎么樣才能變成水波紋的樣子,然后推導出一個公式,來移動像素點,最后再來驗證得到的是不是你想要的結果。
對於上文的第二組網格圖片,原圖和結果圖應該都是已知的,然后根據這兩張圖片,思考怎么樣構造一個公式,將原圖變成結果圖。
而現在重要的問題是,水波紋的結果圖究竟應該是一個什么樣子?然后我們才能下一步談這么變換。對於這個問題,我表示不知道怎么下手。也許要去查閱物理知識,才能得到一個好的結果。