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只會顯示整數。

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

沒有留言:

張貼留言