2015年12月31日 星期四

02360156_鄭宇哲_HW04

首先先給個程式圖~


為了讓效果可以疊加,可以做出不同的效果,我做了些簡易的按鈕,讓使用者可以去玩玩它的功能,可以互相交錯疊加使用!!

首先先使用平滑的功能

這是普通版!!
再來是加強版!!
然後威力加強版就是更強!,使用的MASK是 7*7 位移量也最多 也更模糊!

當然可以使用將圖片套用到原圖,做出極致的平滑化!!
很無聊的....


再來是銳利化:
有點不是很好看,他另中點顏色過於突出,也許調整過一下會好一些
此圖是經過處理的銳利化,跟原圖比起來確實有銳利化到,且不會像原本銳利化那種不真實!

銳利化做多了,造成大部分的點都超出255。



再來是中間濾波
把剛剛的銳利化的白點,給稍微變淡了些,不過還是有點不真實,現在來撒點白點上去看看。
這是80% 做一次(左)做兩次(右)
變得頗醜
然後再多做幾次...
已經做到極限之後...白點變很大塊刪不掉...


總結:
這次三項功能,為了讓功能可以互相使用,我做了可以疊加的功能,可以亂亂按亂亂試,
這次只PO了幾次的圖片,我還有做很多其他的,然後我的平滑化是用了3*3 5*5 7*7 的MASK
去試試看,然後做到極限會發現他有位移,很明顯的平滑是有的,為什麼叫平滑的原因吧,然後銳化把顏色之間的差別明顯做出來,造成有些位置變得過白,在經過平滑處理,就變成一張不錯的相片,也就不會太過於不真實,去雜訊的功能,可以將大量不合理出現的顏色,給清除掉,雖然清除之後會造成影像有點馬賽克,至少比整個都是點點的要好!!

2015年12月29日 星期二

資工四乙 黃戎歆 01360114 HW4

1.平滑濾波

             產生出來的效果會看起來比原圖模糊一些。
             在撰寫程式的時候一開始一直只想到一維陣列,覺得寫起來會很麻煩,後來到Blog參考了別人的想法才想到二維,就發現整個城市變得很簡單,在一個回圈內就可以跑完三個顏色跟遮罩所裡的結果了。

對臉部來說,使用平滑濾波器後紅紅的地方明顯少了許多

2.中值濾波
      灑雜訊後可以很明顯的發現濾波器可以把大部分的雜訊過濾掉。
程式中沒有遇到太大的困難,主要是後來才發現有內建的排序函式可以使用。
上圖是只有5%雜訊 中值濾波器可以將大部分雜訊處理掉

上圖是處理30%雜訊,濾波器雖然能處理掉大部分雜訊,但還是有很多事無法處理掉的,而且原本是散佈的小黑點會變成集中成一小塊一小塊的分布

3.銳化濾波器
   使用後整張圖片看起來更突出了。
程式部分主要跟平滑濾波器是一樣的,只是遮罩的不同。
在色彩明亮飽滿的圖片中啟用會感覺有點奇怪

原本比較灰暗的角落,使用後都讓色彩更明顯的顯示出來了
結論:
          平滑濾波器很明顯的就是會將影像中的小細節連接起來變成比較平滑,但運用在一整張圖片中就感覺好像是把它變糊而已,但就處理小區塊來修圖,像是把把臉上的坑坑洞洞便平滑模糊就是一個很好用的東西。

          中值濾波器運用在處理一些小瑕疵上還不錯,不過當瑕疵太多處理出來的效果也變得不太明顯了。
       
          銳化濾波器就是用來強調凸顯色彩的變化,但運用在色彩鮮豔飽滿的圖片上就會變得感覺怪怪的,而運用在灰暗的圖片中就明顯比較好上許多。

2015年12月28日 星期一

资工三甲 林呈钰 04362383 hw4




1.平滑滤波器

原理:减少周围像素点的差距,使每一个像素点输出为周围像素点和的平均值;



2.中值滤波器

原理:找到遮罩像素的中位数并输出,去除较为极端的点


3.锐化滤波器

原理:与平滑滤波器相反,锐化滤波器是点与周围像素的差距


 4.胡椒盐杂讯



心得:
这次的作业是 “滤波器”,所以我把ppt看了一遍,先弄懂了空间滤波器的基本原理,我的总结就是巧用“九宫格”和像素的计算,明白每一个滤波器的原理就差不多都能完成,中间有一些程式上的问题,但是最主要的还是思路清晰,明白每个滤波器的计算思维方式,逻辑上不是重点因为没什么难点,关键其实就是推演公式像素的处理是如何,就好。

2015年12月24日 星期四

資工四甲 01360841 王世權 HW3

這次作業遇到的第一個問題是
C++BUILDER無法使用
在家裡試用版到期了
在學校自從換了MAC後也無法使用
今天終於解決了

剛剛在寫的時候是參考同學的程式碼
馬上就遇到曲線公式搞反了
然後是忘記宣告變數在那邊ERROR半天
最後是找不到BMP檔只好用小畫家轉檔

成品有些偷懶沒有把數據顯示出來
不過功能上是沒問題的

2015年12月23日 星期三

資工四甲 01360193 李東穎 HW3

這次作業主要是做色階與曲線的調整功能
1.色階
主要公式:
iOutput = iOustputMin + (iInput - iInputMin) * (iOutputMax - iOutputMin)/(iInputMax-iInputMin)




















輸入色階為30-225

輸出色階為30-225


2.曲線

曲現向上顏色偏亮



























曲線向下顏色偏暗









*********************************************************************************
曲線在photoshop也是個非常實用的功能
對攝影師來說是個很有幫助的工具


不同曲線調整對於反差/亮度的效果

    圖1                                   圖2                                  圖3                               圖4


1.S型曲線 (增加反差) – 按圖1的兩點位置,將曲線向內推壓,相片反差會相應提
高。
2.反S曲線 (降低反差) – 按圖2的兩點位置,將曲線向外拉開,相片反差則會下降。
3.曲線向上 (增加亮度) – 按圖3的中間點,將曲線向上拉,相片亮度會相應提高。
4.曲線向下 (降低亮度) – 按圖4的中間點,將曲線向下拉,相片亮度則會下降。


此段內容引用自:
http://www.fotobeginner.com/1870/photoshop-curves/
*****************************************************************************************
心得
這次遇到的兩個難題是overflow問題和mousedown使用方式
最後費盡千辛萬苦終於在網路上找到答案
這次操作C++builder很明顯的比上次流暢也輕鬆了許多
對影像處理也更進一步的認識
另外XE的C++builder無論是在家裡還是在S513都無法使用
最後只好選擇borland c++ builder 來完成作業

2015年12月20日 星期日

02360475 傅清毓 HW04

第一個是銳化濾波的效果圖
    

在寫程式時主要的問題是要怎麼處理邊界問題
想了很久於是用以下的寫法解決
//以下的4個變數在算高跟寬的邊界
int hl = ((i-1)<0) ? i : (i-1) ;                     //如果高-1 小於0的話 就不減1
int hr = ((i+1)==imageHeight)?i:(i+1);   //高+1如果等於寬的話也不+1
int wl = ((j-1)<0)?j:(j-1);                         //寬以此類推
int wr = ((j+1)==imageWidth)?j:(j+1);
for(int k = 0; k < 3; k++)
{
        sum = 0;
        maskSum=0;
        for(int h = hl; h <= hr; h++)
               for(int w = wl; w <= wr; w++)
               {
                           sum+=imageRow[h][w*3+k]*mask[h-i+1][w-j+1];
                           //mask是遮罩的權重
                           //用目前要處理的座標-中心點座標+1就可以得到對應的權重
                           maskSum+=mask[h-i+1][w-j+1];
               }
        //最後這邊在判定他有沒有大於255或小於0
        imageRow2[j*3+k] = (sum/maskSum>255)?255: (sum/maskSum<0)?0:sum/maskSum;
                             
}
這樣子就解決掉邊界的問題了


這一個是平滑化的效果圖 可以看到影像有變平順一點 或者可以說模糊一點
 

程式碼跟上面幾乎一樣
所以就沒PO
因為只是改變遮罩的權重
比較不一樣的地方是它不會有小於0跟大於255的問題


最後這兩張圖分別是先做10%跟20%的雜訊後作中值濾波的效果


    
程式碼也是差不多
如下
for(int k = 0; k < 3; k++)
{
       for(int a =0;a<9;a++)
       px[a]=256;                                      //px為儲存9個值的地方 一開始設為256是為了之後運算
       count =0;
       for(int h = hl; h <= hr; h++)
       for(int w = wl; w <= wr; w++)
       {
                 count++;                                                                 //計算共有幾個值
                 px[(h-i+1)*3+(w-j+1)] = imageRow[h][w*3+k];  //把像數值存入px裡面

       }
       sort(px,px+9);                                               //用內建的方法從小到大排序
       imageRow2[j*3+k] = px[(count+1)/2];      
      //因為有用count算有幾個 所以中位數就是(count+1)/2
                     
 }


資工四甲 01360770 張軒睿 HW4

先附上一張灑胡椒(雜訊)成果

針對雜訊的部分採用了每多按一次就隨機在圖片範圍內產生固定數量的雜訊
也就是說按的越多次,雜訊就會越多
接下來是憑滑濾波的圖片

可以從左上的雲和樹發現
原本銳利的部分變得霧霧的
在這個部份上其實選圖片非常重要
因為很多圖片並沒有那些銳利的部分
就會顯得效果並不明顯
同時做了銳滑濾波的功能


可以看到效果非常明顯,將顆粒放大,整張圖片的銳利度都大大的提高
但過度銳滑的後果就是圖片變得像馬賽克
因此在做銳利度的調整時需要謹慎


這次的作業因為上次學到教訓
是直接用舊檔案來做修改
因此省下大量定義變數、拉元件等時間
總共只用了一個晚上就成功做出來
中途也沒有遇到甚麼難關
是一次非常順利的作業!
打算趁著期末考還沒到,還不需要惡補其他科目時盡快將剩下一份作業也完成
這樣期末就能專心準備考試了!

2015年12月16日 星期三

資工三乙 02360386 柯明男 HW4

作業內容:Filter

Smoothing Spatial Filter (平滑空間濾波器):

讓影像模糊化(平滑化,去銳利化)
原理:減少與周圍的差距 遵循以下比例 把周為的點還有自己都加起來 然後除16

圖1.平滑的遮罩

小問題:當遇到邊邊該怎麼辦

我的作法是 當遇到邊邊 利如(-1,-1) ,(-1,0),(-1,1),(0,-1),(1,-1) 就直接跳過
而這樣也會相對的 最後要除的數字多寡
另外 因為怕會因為修改前面而影響到後面 所以 我有被分一份原始圖片
程式嗎如下:
        unsigned char mask[3][3] = {{1,2,1},{2,4,2},{1,2,1}};
        int maskSum;
        int Sum[3];
        BYTE **bPtrImageRow = new BYTE*[iImageHeight]; // 原始圖片的2維陣列宣告
        for(int j=0; j<iImageHeight; j++)
        {
            bPtrImageRow[j] = (Byte *)Image2->Picture->Bitmap->ScanLine[j];
        }
        for(int i=0; i<iImageHeight; i++)
        {
            BYTE *bPtrImage2Row = (Byte *)Image4->Picture->Bitmap->ScanLine[i];
            //要修改圖片的宣告

            for(int j=0; j<iImageWidth; j++)
            {
                maskSum=0;//計算最後要除的量
                Sum[0]=0;//B
                Sum[1]=0;//G
                Sum[2]=0;//R
                for(int h=0;h<3;h++)
                {
                    for(int w=0;w<3;w++)
                    {
                        //防止出界
                        if((i-1+h)>=0 && (i-1+h)<iImageHeight && (j-1+w)>=0 && (j-1+w)<iImageWidth)
                        {
                            for(int k=0;k<3;k++)
                            Sum[k]+=bPtrImageRow[i-1+h][(j-1+w)*3+k]*mask[h][w];
                            maskSum+=mask[h][w];
                        }
                    }
                }
                for(int k=0;k<3;k++)
                    bPtrImage2Row[j*3+k]=Sum[k]/maskSum;
            }
        }
圖2.平滑的效果 稍為可以看出有比較模糊一點

Sharping Spatial Filter(銳化空間濾波器)

讓影像的邊邊可以更明顯 
原裡:增加與周圍的差距
圖3.銳化的遮罩

小問題:有可能會超過 0,255 其他基本上沒問題

程式碼如下:
        Image4->Picture=Image2->Picture;
        int Sum[3];
        BYTE **bPtrImageRow = new BYTE*[iImageHeight];
        for(int j=0; j<iImageHeight; j++)
        {
            bPtrImageRow[j] = (Byte *)Image2->Picture->Bitmap->ScanLine[j];
        }
        for(int i=0; i<iImageHeight; i++)
        {
            BYTE *bPtrImage2Row = (Byte *)Image4->Picture->Bitmap->ScanLine[i];
            for(int j=0; j<iImageWidth; j++)
            {
                Sum[0]=0;//B
                Sum[1]=0;//G
                Sum[2]=0;//R
                for(int h=0;h<3;h++)
                {
                    for(int w=0;w<3;w++)
                    {
                        if((i-1+h)>=0 && (i-1+h)<iImageHeight && (j-1+w)>=0 && (j-1+w)<iImageWidth)
                        {
                            for(int k=0;k<3;k++)
                            Sum[k]+=(bPtrImageRow[i][j*3+k]-bPtrImageRow[i-1+h][(j-1+w)*3+k]);
                        }
                    }
                }
                for(int k=0;k<3;k++)
                {//防止超過0,255 另外這裡多加1次 是因為上面只+8次
                    if(Sum[k]+bPtrImageRow[i][j*3+k]<0)
                        bPtrImage2Row[j*3+k]=0;
                    else if(Sum[k]+bPtrImageRow[i][j*3+k]>255)
                        bPtrImage2Row[j*3+k]=255;
                    else
                        bPtrImage2Row[j*3+k]=Sum[k]+bPtrImageRow[i][j*3+k];
                }
            }
        }
圖4.銳化的效果 Lenna的帽子跟頭髮都比較明顯了

Median Filter(中值濾波器)

去除圖片的雜訊
原裡:雜訊通常是圖片中 較為極端的點
而中值濾波器 是去3*3裡面的中位數 可以去除較為極端的點

小問題:怎麼找中位數(好像也是不是問題

        Image4->Picture=Image2->Picture;
        BYTE **bPtrImageRow = new BYTE*[iImageHeight];
        vector<vector<int> >temp(3,vector<int>());//二維的vector宣告 
        for(int j=0; j<iImageHeight; j++)
        {
            bPtrImageRow[j] = (Byte *)Image2->Picture->Bitmap->ScanLine[j];
        }
        for(int i=0; i<iImageHeight; i++)
        {
            BYTE *bPtrImage2Row = (Byte *)Image4->Picture->Bitmap->ScanLine[i];
            for(int j=0; j<iImageWidth; j++)
            {
                temp[0].clear();//清除vector的內容
                temp[1].clear();
                temp[2].clear();
                for(int h=0;h<3;h++)
                {
                    for(int w=0;w<3;w++)
                    {
                        if((i-1+h)>=0 && (i-1+h)<iImageHeight && (j-1+w)>=0 && (j-1+w)<iImageWidth)
                        {
                            for(int k=0;k<3;k++)
                            //將數字丟進vector最後面
                            temp[k].push_back(bPtrImageRow[i-1+h][(j-1+w)*3+k]);
                        }
                    }
                }
                for(int k=0;k<3;k++)
                {
                    sort(temp[k].begin(),temp[k].end()); //將3個vector 排序
                    if(temp[k].size()%2) //當是奇數值 中位數就是正中間的那個數字
                    {
                        bPtrImage2Row[j*3+k] = temp[k][temp[k].size()/2];
                    }
                    else //偶數時 則是把中間的兩個數相加除二
                    {
                        bPtrImage2Row[j*3+k] = (temp[k][temp[k].size()/2]+temp[k][temp[k].size()/2-1])/2;
                    }
                }
            }
        }
內鍵sort(陣列頭,陣列尾) 要include <algorithm>還要 using namespace std;
以下是灑入雜訊的程式碼:
        int num=StrToInt(Edit5->Text);
        BYTE **bPtrImageRow = new BYTE*[iImageHeight];
        for(int j=0; j<iImageHeight; j++)
        {
            bPtrImageRow[j] = (Byte *)Image2->Picture->Bitmap->ScanLine[j];
        }
        for(int i=0; i<iImageHeight; i++)
        {
            for(int j=0; j<iImageWidth; j++)
            {
                if(rand()%100<num/2)
                {
                    for(int k=0;k<3;k++)
                        bPtrImageRow[i][j*3+k]=0; //灑白點
                }
                if(rand()%100>=100-num/2)
                {
                    for(int k=0;k<3;k++)
                        bPtrImageRow[i][j*3+k]=255; //灑黑點
                }
            }
        }
        Image2->Refresh();//如果沒有打會看不出已經灑點了!!
圖5.灑6%雜訊 去雜訊的效果非常的好
圖6.灑20%雜訊 去雜訊效果也是非常好 不過此時可以很明顯看出有雜訊
程式碼:點我

2015年12月12日 星期六

資工四甲 01360912 陳奕穎 HW4

作業四要我們做三個濾波器,分別是平滑、中值、銳化,用處各不相同,平滑是為了移除影像中的一些小細節,中值是為了去除雜訊,銳化和平滑正好相反,銳化是用來凸顯細節,實作如下圖。

平滑(Normal)

我有 Mask 用 7 x 7 所以看起來模糊很多

平滑(Weight)

雖然有模糊,可是很不明顯

中值

先將圖片灑上胡椒鹽

去除 6% 的胡椒鹽,效果顯拔

銳化(Normal)

沒有考慮角落的銳化

有考慮角落,效果非常顯著



心得    

    作業四依舊花了我不少時間才完成,我花了好多時間在處理邊界值,在邊界的地方用九宮格會超出去,然後只取九宮格有的地方,權重要重算,而且我又不是很想用很多 if else 來做判斷,所以著實令我傷透了腦筋,大概有兩天多的時間都在想這個要怎麼解,最後才想出一個我比較滿意的方法。
   
    這關過了以後,就很順利的把三個濾波器都寫出來了,可是我的銳化濾波器一直會有奇怪的顏色,檢查了很久,公式都沒有錯,完全找不出哪裡有錯,所以我就想,肯定是我在哪裡老師有說但我又有漏掉沒聽到。
   
    於是我就去 blogger 裡面翻找之前有修這門課的人寫的程式碼出來參考,順便看看他們是怎麼解決邊界值問題的,不看沒事,一看晴天霹靂阿 !    原來只要忽略掉邊界值就好......,反正一張圖有沒有去改邊界值,人眼是看不出來的,這問題害我白白花了好多時間,結果只要這麼簡單就解決了,不過有看到跟我一樣在跟邊界值奮鬥的勇者,而且它還是用 if else ,我內心就比較沒那麼難受了,因為至少我知道了我不是孤獨的 !
   
    然後果不其然,我確實漏聽了,我的銳化濾波器少了判斷新的値是否大於 255 或者是小於 0 ,如果大於 255 就要等於 255 ,如果小於 0 就要等於 0 ,加上這個判斷式後,我的程式就很完美的呈現出我想要的結果了。

程式碼在這裡 :
標頭檔
程式碼

2015年12月9日 星期三

資工四甲 01360770 張軒睿 HW3

按照慣例先付上程式截圖
這次的作業遲交了許久,在寫程式的時候先是遇到忘記宣告變數(imageweight等變數),一直跳error卻怎麼google都找不到一樣的狀況,後來去翻上次作業的程式碼才發現自己忘了宣告變數。這件事告訴我把上次程式碼保留著有多重要,留著專案檔會更好。但因為家裡灌的是XE10版本的和學校XE2不同版本,怕有相容性的問題。
而且學校的C++builder不知道為甚麼自從上次換成MAC之後再也打不開了....
宣告完變數之後下一個遇到的問題是Mousedown,之前都是做click的動作,只要按兩下元件就可以開始寫程式。
這次因為要用到這個功能開始想該怎麼做,先是試了直接寫程式碼加上修改標頭檔參數但沒辦法編譯,後來才突然想到可以去屬性的event找,果然就找到mousedown的動作!

有了這兩次程式作業的經驗之後決定存下專案檔以後都在家裡做作業,這樣才不會每次都發生一堆蠢事才開始邁上正軌。
3D照片還是想不到好題材阿...
本來前陣子去高雄和新竹都想找東西拍的,卻怎麼看都覺得不甚滿意....

2015年12月3日 星期四

02360156_鄭宇哲 HW 03

以下是我做的簡易介面:
右邊的上方為調整輸入最大最小與輸出最大最小,
在這邊指令的控制是沒甚麼問題,知道哪邊是該提高或減少的位置用好就可以了,
我這邊的高與寬是設255,只要將MoveTo內的Y或X參數扣掉輸入或輸出的最大最小值即可顯示出該圖形
如下圖,下面是改變過後的,上面是原圖。
而這邊變換的方式根據左邊給的輸入,輸出的最大最小直,把新的像素的顏色給計算出來,然後一一填入改變的TImage。

之後是曲線的部分,這邊我認為比較麻煩是因為要做二項式的計算,三個點決定一個曲線,
由於實在太麻煩就沒有做四個點五個點的三項或四項式。
將曲線向下調整,圖片明顯變暗了些(這邊包含上面的最大最小的輸入輸出值得改變,所以還是比原圖亮一點。)

心得:
真心不是很喜歡看到麻煩的數學計算阿,不過只要將腦中的計算是輸入電腦就好,不必特地去做計算算是謝天謝地,然後有一些部分,在畫曲線的時候,要一個一個點畫,好麻煩,沒辦法直接給他二項式叫他直接畫,還有我並沒有把兩張圖並再一起可是做出來是並在一起的結果,而且由於如果使用CLICK 並沒有回傳滑鼠座標,所以使用MOUSEDOWN的事件來作曲線!