2014年12月18日 星期四

Spatial Filtering 實作

HW4:Spatial Filtering

這次的作業是有關模糊化(blur),
銳化(Sharpen),胡椒鹽雜訊(Pepper-and-salt Noise),
中值濾波器(Median Filter)的實作。


這是程式的界面
有兩個Page,第一個Page為Image顯示原圖
第二個Page為Result顯示處理后的結果圖
程序有5個功能(如下圖所示)
1.box blur(快速均值模糊)             
2.Gaussian Blur(高斯模糊)          
3.Sharpen(銳化)                          
4.Sharpen Diagonal(對角戲銳化)
5.Median Filter(中值濾波器)        


一:
第一個是box blur(快速均值模糊)
其做法是將影像中每個像素點的值更改為
其周圍九宮格內像素的平均值


這裡要注意的是邊界不能取到
for (j=1; j<iImageHeight-1; j++)
所以是從1到imageheight-1做scanline
做完box blur的結果(如下圖)


二:
第二個是Gaussian Blur(高斯模糊)
高斯模糊是一種圖像模糊濾波器,它用正態分布
計算圖像中每個像素的變換。
可以理解為加了權重的box blur
它更加注重臨近的點對中間那點的影響


做完box blur的結果(如下圖)


三:
第三個是Sharpen(銳化)
銳化用到了Laplacian(拉普拉斯)運算子
將銳化濾波器的公式簡化可得
 g(x,y)=f(x,y)-∇^2 f(x,y)
=f(x,y)-[f(x+1,y)+f(x-1,y)+f(x,y+1)+f(x,y-1)-4f(x,y)]
=5f(x,y)-f(x+1,y)-f(x-1,y)-f(x,y+1)-f(x,y-1)
簡化后的銳化濾波器的遮罩(如下)


左邊為只對橫向和縱向做銳化
右邊還加入了對角線的銳化

在做銳化的時候要注意色彩值可能超過255或小於0的問題
沒有做攔截的話可能出現(如下圖)的錯誤


int f=(5*a[4]-a[1]-a[3]-a[5]-a[7])
if(f>255)f=255;

else if(f<0)f=0;
所以這段很重要!
正確結果(如下):


可以發現整個畫面變得更清晰了。

四:
第四個是Sharpen Diagonal(對角戲銳化)
這個與三的區別在對角戲也做了銳化
結果(如下):


可以發現銳化效果相比于三更加明顯。

五:
第五個是Median Filter(中值濾波器)
中值濾波器常可用來消除脈衝雜訊
所以在用這個濾波器之前要先做
胡椒鹽雜訊(Pepper-and-salt Noise)這個動作
影像中的脈衝雜訊是以白點或黑點的形式出現,
所以胡椒鹽雜訊就是用亂數將影像的
某些像素點的色彩值改成黑白色
從而產生胡椒鹽的雜訊效果。
結果如下(這是6%的胡椒鹽):


撒完鹽之後就需要用到中值濾波器來處理了。

中值濾波器是將九宮格內的色彩值,


取出來之後排序,

之後拿取中間值


(這裡引用 99360134 徐賢傑 學長的圖來做說明)

中值濾波器處理后的結果(如下):


看起來會比之前影像模糊一點點

如果是10%的胡椒鹽就還會殘留一些雜訊


總結:這次的作業寫完后很有感覺,不僅模擬了photoshop的功能
還實作了影像的修復與處理。在撒完鹽后又用中值濾波器
將圖像復原的過程很有成就感。還有就是再老師指點完
將銳化的bug處理掉之後,得到了真正銳化的結果。
那個時候有興奮的感覺!
總而言之,這次的實作讓我對影像處理更加感興趣了!







 

2014年12月17日 星期三

99360303 吳泓霖 HW4


讀取好的原圖
使用平滑濾波器(有權重)後
加入胡椒鹽雜訊
接著使用中值濾波器
最後再使用銳化濾波器

在銳化濾波器以前都非常簡單但是也很繁瑣
如果使用最簡單的方法的話
4個角落以及4個邊都會沒有效果
所以特別用了很多的if, else if, else去run那些特殊地方

中值濾波器因為是"中值"
而4邊和4角都沒有所謂的中值
所以是感覺上最簡單的

胡椒鹽有動了些手腳
輸入基數其實是用+1後的數值下去做運算
不會有小數點的問題

在銳化濾波器的地方遇上了蠻蠢的問題
但是因為不清楚原因所以一直改程式碼
最後請教了老師才知道只是簡單的要設範圍
讓最後結果最低是0   最高是255就沒事了


資工三乙 01360353 高子翔 HW3

程式碼:

https://www.dropbox.com/s/4robzxpgwzl88t7/Unit1.cpp?dl=0

心得:

在寫程式的一開始不太清楚怎麼寫
然後之後就問朋友跟看講義慢慢研究
這次比較困難的點就是做曲線的時候
曲線如何判定跟移動
目前也還在改善

實作:






2014年12月12日 星期五

資工三乙 01360025 郭雅筑 HW2

HW2
統計圖片每個像素的BGR色彩值

PDF(直方圖)

這邊一直卡在畫圖的地方
畫圖的起始位置一直搞錯
畫出來的直方圖都是反的
左下角的Y座標是255不是0

CDF(累積圖)

程式碼
https://drive.google.com/file/d/0BxnCZ29IxiicbGRVd1RaeXdwT1k/view?usp=sharing

心得
在過程中 一直有小錯誤
很多都是卡在畫圖的地方
做完後很開心
也覺得神奇
程式沒有很長
大概分為統計資料和畫圖兩大部分
卻可以做出photoshop其中一小個功能=))







資工三乙 01360592 范姜詩婷 HW2


這次的作業是
分別統計一張彩色影像之紅、綠、藍色彩的 PDF
分別統計一張彩色影像之紅、綠、藍色彩的 CDF



首先就是要先讀取圖片的每一個像素點
並計算RGB的值
  
        for(j=0; j<iImageHeight; j++)
        {
         bPtrImage = (Byte *)Image1->Picture->Bitmap->ScanLine[j];
         for(i=0; i<iImageWidth; i++)
                for(k=0; k<3; k++)
                        iHistogram[k][bPtrImage[i*3+k]]++;
         }



再將統計好的RGB值
分別畫在三個畫布上



         //紅色
         Image2->Canvas->Pen->Color=clRed;
         Image2->Canvas->MoveTo(i,255);
         Image2->Canvas->LineTo(i,255-iHistogram[2][i]*0.25);


         //綠色
         Image3->Canvas->Pen->Color=clGreen;
         Image3->Canvas->MoveTo(i,255);
         Image3->Canvas->LineTo(i,255-iHistogram[1][i]*0.25);


         //藍色
         Image4->Canvas->Pen->Color=clBlue;
         Image4->Canvas->MoveTo(i,255);

         Image4->Canvas->LineTo(i,255-iHistogram[0][i]*0.25);


PDF 






然後做CDF
一樣先計算圖片每個像素的RGB值
再分別在畫布上作圖


         //畫圖
        Image2->Canvas->MoveTo(0,255);
        Image3->Canvas->MoveTo(0,255);
        Image4->Canvas->MoveTo(0,255);

        for(i=0; i<256; i++)
        {

         //紅色
         Image2->Canvas->Pen->Color=clRed;
         Image2->Canvas->LineTo(i,255-iHistogram[2][i]*255/iHistogram[2][255]);


         //綠色
         Image3->Canvas->Pen->Color=clGreen;
         Image3->Canvas->LineTo(i,255-iHistogram[1][i]*255/iHistogram[1][255]);

         
         //藍色
         Image4->Canvas->Pen->Color=clBlue;
         Image4->Canvas->LineTo(i,255-iHistogram[0][i]*255/iHistogram[0][255]);



         }

CDF





其實這個程式並不難
了解每一行做的事情
多花點心就可以做出來
只是中間的過程
debug實在很痛苦
畢竟一直看螢幕
很容易打錯字沒看到
一直以為是哪裡的語法錯誤
沒想到只是打錯字
但做出來的時候心情真的很好~~






2014年12月10日 星期三

01361030藍政歆HW3




程式碼=>https://www.dropbox.com/s/gyw71mm54tknvig/Unit1.cpp?dl=0
這次作業做色階的調整
 上圖為程式介面,工具列的檔案可將圖載入進來,下方為色階的調整部分,左方是上下限輸入出調整,給定上下限的輸入輸出然後依照比例來調整,右方是二次曲線調整,輸入(X,Y)座標後畫出拋物線後根據對應的output值調整
 ↑圖引(http://seiga.nicovideo.jp/seiga/im3991410)
一樣先把圖給叫進來,然後先進行色階調整
 上圖(左)是以輸入下限100上限200輸出下限0上限255做色階調整後圖的樣子,顏色看起來比原圖深,上圖(右)是色階調整的曲線圖
 上圖(左)是以(X,Y)=(100,150)做色彩曲線後的樣子,較原圖淺些,但不怎麼的明顯,上圖(右)是色彩曲線,是一條拋物線

程式部分,這次用了查表法來增加運算的速度,設兩個大小為256的陣列,一個給色彩調整,另一個給色彩曲線,將計算後的色彩值放到對應的位置,到時候需要轉換時只要這個陣列尋找就好,不用每個色彩值都重新計算,會省下許多時間

for(int k=0;k<256;k++)
        {
            if(k>iInputMax)
                iOneBox[k]=iOutputMax;
            else if(k<iInputMin)
                iOneBox[k]=iOutputMin;
            else
                iOneBox[k]=iOutputMin+(k-iInputMin)*((iOutputMax-iOutputMin)/(iInputMax-iInputMin));
        }
上面是色彩調整的表格製作,iOneBox是儲存運算後的色彩值的陣列,iOneBox[k]的k是欲運算的色彩值,等號後面的運算後的值是轉換後的新色彩值,到時候只要把原本的色彩值帶入k,然後就可以取得轉換後的新色彩值

沒有使用查表法的話,每個色彩值都必須代入運算,這樣要運算圖片的大小*3(RGB)的次數,而查表法的話只要運算256次+查表圖片的大小*3(RGB)的次數的時間

 再來為何要有k>iInputMax跟k<iInputMin的限制,因為要把色彩值限制在iOutputMax跟iOutputMin之間,而轉換公式iOutputMin+(k-iInputMin)*((iOutputMax-iOutputMin)/(iInputMax-iInputMin))是用相似三角形的比例概念推導出來的

fA=(fPointY-fPointX)/(fPointX*fPointX-255*fPointX);
fB=1-255*fA;     //這裡將色階取線的輸出值建表
    for(int k=0;k<256;k++)
        {
            fS=fA*k*k+fB*k;
            if(fS>255)
                iTwoBox[k]=255;
            else if(fS<0)
                iTwoBox[k]=0;
            else
                iTwoBox[k]=fS;
        }
上面是色階曲線的表格製作,fPointX跟fPointY分別對應(X,Y)的X跟Y,fA是在計算拋物線y=ax^2+bx+c的a,fB是在計算y=ax^2+bx+c的b,在這裡y=ax^2+bx+c的c是=0,故捨去

a,b,c都算出來了,代回去原本的方程式並將(x,y)給代入(此處的x,y是色彩變數)會得出fS,而fS>255跟fS<0的限制是因為色彩值是在0~255之間,所以不能超過這個範圍

這次遇到最大的問題是轉換後的像素需要新的BYTE*去存放,原本是直接覆蓋在bPtrImageRow[3*j+k]裡面,結果出來的圖跟想像中不一樣,之後用bPtrNewImageRow[3*j+k]來存放並顯示出來,圖才正常的轉換

  這次的作業比上次難了些,但還是想一想就有辦法寫出來的,比較麻煩的是公式的推導,但老師上課有講如何推導,所以實際推導一遍其實不算太難,就是要肯想肯實際去操作   

2014年12月6日 星期六

資工三甲 01363116 彭宇壕 HW2

作業二:Color Histogram
畫出圖片的PDF和CDF

打開圖片
if (OpenPictureDialog1->Execute())
{
Image2->Picture->LoadFromFile(OpenPictureDialog1->FileName);
iImageWidth = Image2->Picture->Width;
iImageHeight = Image2->Picture->Height;
}




PDF



CDF





2014年12月2日 星期二

99360816 張育瑋 HW3

Level調整的介面
用了4個Track Bar調整色階輸出入的上下界
另可直接用Edit輸入要用的值

調整好上下界後
按下Apply後
程式便會讀取所有輸出入的上下界值

程式中前兩個if判斷式用來判別
若小於Input Min則輸出為Output Min
若大於Input Max則輸出為Output Max
而介於兩者間的其他值則以下列公式換算
即可得到每個輸入色階對應的輸出值

iLevelTable[i] = 
iOutputMin + (i - iInputMin)* (iOutputMax - iOutputMin)/(iInputMax - iInputMin);
i值 = 0~255

算完後再查表更新圖片
結果如下

結果(1)

結果(2)

 =======================================================================

Curve調整的介面
可直接點Image物件調整曲線

在此利用了幾個Image的Event Handler

<MouseDown>
點下滑鼠左鍵時
會抓滑鼠游標的XY座標
設定CurveMouseDowned為true
並計算及繪製曲線一次

<MouseMove>
游標在Image物件內移動
若CurveMouseDowned為true
即有按著滑鼠左鍵時
隨游標的移動
不斷的重新計算及繪製曲線

<MouseUp>
放開滑鼠左鍵
即設定CurveMouseDowned為false
如此一來游標移動時便不會更動曲線

在決定曲線後
按下Apply
程式就會以iCurveTable對圖片做調整
結果如下

結果(1)

結果(2)
========================================================================


這是另外做的直方圖均值化
將RGB的色階出現機率分別計算完
並儲存在dCumulative陣列內
接著計算255*dCumulative[j][i]
j=0~2, i=0~255
計算完存入iEqualization陣列
最後以查表法更新圖片即可完成直方圖均值化

資工三乙 01360786 張凱崴 HW2

第一次程式作業


重點:
將BMP圖片裡的BGR值取出並做成圖表


心得:
開頭就想很久,不知道該從何下手
就跑去翻之前的講義,中途還不小心
把Red跟Blue寫反...,寫到最後
在測時還發現一堆錯誤,
當時的心都涼了一半
才發現原來是我宣告都用int
所以錯的一蹋糊塗
當時只能以苦笑面對。



程式碼:https://www.dropbox.com/s/0kszvjmmwzzgct9/Unit1.cpp?dl=0



成果附圖


讀取檔案



PDF


CDF