顯示具有 97361000 李翼豪 標籤的文章。 顯示所有文章
顯示具有 97361000 李翼豪 標籤的文章。 顯示所有文章

2011年1月7日 星期五

HW3

這次作業是3D立體影像創作!

在做3D影像之前,首要先分別拍攝左右眼兩張影像。









如果要拍得好就要考慮拍攝物體的距離、左右位移的距離,
要注意不要拍的一前一後、一上一下,這樣效果才好。

根據網路上的一些資源可得知以看書而言,
拍攝距離30cm、左右拍攝視角約12度以內,
是適合做3D影像的左右兩張照片。

拍完兩張照片後我寫了程式把它做成3D影像,
完成後:

















不過因為第一次拍的關係..拍的實在不好,所以就借用網路上的左右圖片。










製作成3D影像:

















製作完成後就可以用拿紅藍眼鏡來看。

雖然老師說看起來有立體效果,但我當時怎麼看卻看不出來...
左右眼所看到的照片沒辦法解讀出立體效果來,
不曉得是圖不夠大還是看的距離、角度的問題,或許也跟看得經驗有關吧!

不過拿下面這張圖看,就很有立體效果!


















我們之所以能看到立體效果是因為人有左右眼可以感覺出物體的遠近,
所以我們才用兩張照片來模擬分別由左右眼看到的影像,
而影像又是由RGB三原色所組成,我們把R、GB分別取出後重疊,
用3D眼鏡讓左眼只看到紅色,右眼只看到藍色,
經由左右眼影像,大腦就會自動分析出遠近、立體的效果。

程式碼部分:








這個概念是當時老師靈機一動想到的,效果好程式又簡單!

不過我原本是這樣寫的:











雖然別人說看起來也不錯,紅藍分明,但其實效果還是不如上個程式。

而強化色彩值這公式是我從某老師給期中考成績開根號乘以十所想出來的...
後面乘16是自己按計算機湊出來的,拿255算算就可以知道有沒有超過範圍,
當然這公式沒有一定,只要效果好就是好!

2011年1月6日 星期四

HW4

這次作業是濾鏡處理,包括平滑化、銳利化和去除胡椒鹽的功能。

首先是平滑化,使圖片看起來變的模糊。














平滑處理後可觀察到邊緣變的模糊,有雜質的地方變的較均勻、不明顯。

原理很簡單,就是把自己和周圍八個像素點的色彩值做平均。

模糊後(中中) = (左上 + 中上 + 右上
.........................左中 + 中中 + 右中
.........................左下 + 中下 + 右下) / 9


從左而右,由上而下,每個像素都做一次,如此就可以讓邊緣銳利、有雜質的圖,變的平滑、模糊。

寫成程式碼:









接著是銳利化,讓圖片變的更銳利、色彩分明。














銳利化處理後使得圖片的細部變得更明顯,與平滑化相反。

原理是把自己的色彩值乘"9",再減去周圍"八"個像素點色彩值,
(或者是把自己的色彩值乘"5",再減去周圍"四"個像素點色彩值)
若減完後的值小於0則等於0;大於255就等於255。

銳利後(中中) = 中中*9 - (左上 + 中上 + 右上
.......................................左中 + 中中 + 右中
.......................................左下 + 中下 + 右下)
if(中中 < 0) 中中 = 0
if(中中 > 255) 中中 = 255

寫成程式碼:











最後是胡椒鹽處理,顧名思義就是去除有如胡椒鹽一顆一顆這樣的雜質。














如圖,色彩值過分差異的點都去除了!

原理一樣很簡單,把自己和周圍八個點的色彩值做排序,取中位數即是答案。
之所以要取中位數是因為排序完後,色彩值過分差異的值都排到很前面或很後面,在取中位數時就不會選到,只會選到9個點中最平均的那個值。

因為要做排序,我先宣告一個陣列來存放色彩值,然後做排序,
排序完後印出陣列[5]即是去除胡椒鹽後的結果!

例如:30,40,41,45,56(中位數),57,58,60,230(胡椒鹽)

不過再仔細看一下上圖,去除後的影像仍有一些沒去除乾淨,
那是因為該3*3的範圍中胡椒鹽過多,超過一半以上,
導致排序完取中位數後仍然取到胡椒鹽,這是正常的。

例如:20,25,26,240,244(中位數),246,250,255,255

這時原本應為胡椒鹽的也不胡椒鹽了!

寫成程式碼:

2010年12月22日 星期三

HW2

這次的作業呢,是顯示一張影像的直方圖,並將影像做均化處理。
結果展示:
















因為我做的是灰階影像,要先把彩色轉灰階。

而在轉換的過程中順便用一個變數(lines[255])統計在這張圖中
"某灰階色彩值總共出現幾次"
例如:灰階色彩值為100的出現30次、255的出現0次...等










有了lines之後我們就可以畫出直方圖了!






其中*0.2是為了別讓直方圖畫超過image,可以用變數讓使用者自行調整比例。

畫完直方圖後開始均化處理

我宣告了一個變數lineSum[255],用來存lines的累加值
lineSum[i] = lineSum[i-1] + lines[i];
就是"累計色彩值的出現次數"
例如:
lineSum[1] = lineSum[0]+色彩值1的出現次數
lineSum[2] = lineSum[1]+色彩值2的出現次數
lineSum[3] = lineSum[2]+色彩值3的出現次數...

然後再用變數P[i]存放lineSum[i]/影像大小(長*寬)
其中lineSum[i]/影像大小 就是"累計到目前為止所佔的比例"

最後新的灰階色彩值就等於P[舊的灰階色彩值]*255
讓原本色彩範圍小的影像均化成色彩範圍0~255大的影像
可以使得色彩更加分明,看得更清楚。

Gary = P[Gary]*255;


做完灰階影像直方和均化後
要做彩色影像就比較容易了
比較直覺的想法就是宣告三個不同的lines[255]分別統計RGB值
lineSum[255]、P[255]也宣告為不同的三個
接著再印出每一像素點的RGB值就好
直方圖也分別印那三個lines[255]

心得:在這次的作業中,因為當初聽老師課堂上的講解沒有很明白、想通
然後作業也比較晚開始寫,記憶變的更模糊的情況下寫起作業來就容易卡住
當初我就是照著自己的想法下去寫,直方圖以前都還沒甚麼問題
但做到均化的部分就開始有問題了,我只想著要把直方圖轉成均化後的樣子
卻忘了影像才是主角....0_0
寫了半天也寫不出個所以然

好在在下次上課時我向老師提出一些問題後開始有了頭緒
統計"某灰階色彩值總共出現幾次"並把值印出
接著"累計色彩值的出現次數"並把值印出...一步一步來
在老師的指導下和不停的嘗試錯誤終於把程式寫出來了
發現程式碼比想像中簡單而且短非常多
只是有些地方腦筋沒辦法馬上轉過來
像是Gary = P[Gary]*255這行就想了好久
儘管如此,經過這次的練習讓我收穫不少 。

2010年11月5日 星期五

HW1

這是我的影像處理課的第一個作業。

題目是:將一張彩色影像轉成灰階影像後,再對灰階影像分別用 128色、64色、32色、16色、8色、4色、2色(黑白影像) 顯示。

作業展示:首先,先開啟一張bmp影像,接著再轉換成256色灰階。
(轉換完後會貼在左邊,當作對照用;右邊是稍後轉換成128、64、32...灰階影像用)























轉換完256色灰階影像後接著再點選"2色顯示",如下圖右邊就是轉換後的結果。























接著是4色顯示


8色顯示


16色顯示


32色顯示


64色顯示


128色顯示



在上面幾個圖中 2、4、8、16色可明顯觀察到與原圖256色的差距,尤其是有漸層的部分;
而 32、64、128色顯示則是幾乎分辨不出與原圖的差距,
因為從彩色轉換成灰階它的色彩範圍已大大減少。


轉換128、64、32...色部分程式碼:

一開始我們先從"2色轉換"的部分看起,是相對簡單一些的。

(因為部落格上程式碼貼上來有問題,所以用圖片)



先從最裡面開始看,兩個if分別是判斷Gray值是否介於0~127還是128~255之間,
(Gray就是影像中其中一個像素點的色彩值,因為已轉換成灰階,固Gray介於0~255之間。)

若介於0~127之間,把0~127之間的值都設成0。(0就是黑色)
若介於128~255之間,把128~255之間的值設成255。(255就是白色)

設定完後最後再把像素點印出,如此該像素點不是色彩值 0 就是 255,達成256色轉成2色的結果。
外面兩個迴圈,從頭到尾,一張影像中的每個像素點都做。

接著不管是 4色、8色、16色、32色、64色、128色也都是用此概念。

例如4色就是把兩個if變成四個if,分別針對色彩值介於0~63、64~127、128~191、192~255
來給定255*0、255*0.33、255*0.66、255*1的值。



但我們不太可能做到128色還在用128個if來寫,

因此我把這N個if用for(i = 1 ;i <= N; i++)來完成:


最裡面的迴圈就是用來做那N個if,那個if會因為N的不同而把256色切成N塊,
再宣告一個變數j0用來控制這個if做到那N塊中的哪一塊。
然後再把該像素色彩值設定成255*(Ratio*j0)。
(Ratio是把1切割成N-1塊,j0會從0跑到N)

舉個例子比較好理解,若N=4,並把最裡面的迴圈拆開,看拆開後長甚麼樣:



所以,有了這三個迴圈我只要改"存成N種顏色"的N值就可以達到存成 2色、4色、8色、16色、32色、64色、128色的需求。
但也因為是三個迴圈,時間複雜度高為缺點之一,幸好圖片不算大張,所以影響不大。

程式撰寫心得:我在寫程式前一定會有個大概的想法,並從簡單的地方開始做。
如同我先從2色先做起,想法很簡單,2色不是0(黑色)就255(白色),
我就把"比較"黑的(0~127)變成0;"比較"白的(128~255)變成255,就這樣而已。

有了2色的概念後繼續延伸出4色、8色、16色...的程式,但這裡會碰到一個問題:2色2個if,4色4個if...128色128個if,這未免太多了!
解決辦法就是用迴圈處理,而且這迴圈是有彈性的會隨N不同而改變,當然迴圈內的某些變數也會跟著改變。

這個程式還真的有點小複雜,概念不難但寫起來有挑戰性,尤其是在寫第三個迴圈時還真的有點想破頭,三個迴圈挺複雜的...

好不容易寫出來了又碰到一個恐怖的問題...就是除錯,第一次開始執行時沒有反應,也不知道為甚麼會這樣,
接著我仔細看了一遍程式看看是不是有打錯字等等,但完全看不出來,此時會產生想放棄這個方法的念頭..
到後來我只好把所有變數的值印出來,像i、j、h、w、Gray、Cut等全部印出直到找到錯誤,果然還真的把錯都找出來!

像我當初印出color值時竟然都是0,我才覺得可能這是保留字之類的所以改成ColoR,然後就沒問題了;
還有我的Ratio印出時怎麼也都是0?我就聯想到資料型態不對,應該宣告為double才對因為int只會顯示整數。

所以說我認為程式除錯時,印出變數的值是很重要的,印出來才知道值對不對,才能找到程式錯在哪,
但前提是你要清楚程式中的每個變數所代表的意義,否則你會不知道你在印甚麼!