2016年12月10日 星期六

03360440 曾郁凱 HW03

作業內容 : Level & Curve

1. Level


透過手動輸入改變 InputMax ,InputMin ,OutputMax ,OutputMin,調整照片色彩明暗度。

公式 :
           
                                                                                            OutputMax - OutputMin
          Output = OutputMin + ( Input - iInputMin) *            -------------------------------------
                                                                                             InputMax  -  InputMin
有幾點需要注意

1. 原影像色階若高於InputMax,則要讓它等於OutputMin,
     
     而原影像若色階低於InputMin,則要讓它等於OutputMax。

程式碼 :
             
              for ( j = 0 ; j < iImageHeight ; j++ )
                 {
                 bPtrImageRow = (Byte *) Image1->Picture ->Bitmap ->ScanLine[ j ];
                 bPtrNewImageRow = (Byte *) Image8->Picture ->Bitmap ->ScanLine[ j ];
                 for ( i = 0 ; i < iImageWidth ; i++ )
                    {
                    for ( k = 0 ; k < 3 ; k++ )
                       {
                       if ( bPtrImageRow[3 * i + k] > iInputMax )
                          bPtrNewImageRow [3 * i + k] = iOutputMax;
                       else if ( bPtrImageRow[3 * i + k] < iInputMin )
                          bPtrNewImageRow [3 * i + k] = iOutputMin;
                       else
                          bPtrNewImageRow [3 * i + k] = iOutputMin+
                          (bPtrImageRow[3*i+k]-iInputMain)
                          *((iOutputMax-iOutputMin)/(iInputMax-iInputMin));  
                       } 
                    }
                 }   

2. 上方底線的部分須注意,若一開始為將變數宣告成int 則影像會修改錯誤。

例子 :
原影像(圖一)


色階調整函數圖(圖二)

調整過後錯誤(圖三)

解決辦法 :
                 1.一開始就先宣告成float

                 2.或將上述程式碼畫底線部分改為

                    ( ( (float) iOutputMax - iOutputMin ) / ( iInputMax - iInputMin ) ) + 0.5

正確之影像(圖四)

3. 手動輸入 InputMax ,InputMin ,OutputMax ,OutputMin必須有防呆的部分。

4. 色階調整函數圖 (分三段畫)

部分程式碼 :
                     
                      Image9 -> Canvas -> MoveTo( 0 , 500 - 2 * iOutputMin );
                      Image9 -> Canvas -> LineTo( 2 * iInputMin , 500 - 2 * iOutputMin );
                      Image9 -> Canvas -> LineTo( 2 * iInputMax , 500 -2 * iOutputMax );
                      Image9 -> Canvas -> LineTo( 500 , 500 - 2 * iOutputMax );

2. Curve : 利用曲線來修改圖片

1 . 首先要修改曲線圖上的點,我們會用到Image事件MouseDown,藉由這個事件
     
    我們可以取得點的XY座標,把新座標帶入就能得到一些關係式
   
    Y = Y - 255;
   
    a =double( Y - X ) / ( X * X - X * 255 );

    b = double(1 - 255 * a );

2 . 改變原影像

部分程式碼:
    
                      for ( i = 0 ; i < iImageHeight ; i++ )
                         {
                         bPtrImageRow = (Byte *) Image8->Picture->Bitmap ->ScanLine[i];
                         for ( j = 0 ; j < iImageWidth ; j++ )
                            {
                            for ( k=0 ; k < 3 ; k++)
                               bPtrImageRow [ 3 * j + k ] = Curve[ bPtrImageRow[3*j+k] ];
                            }
                         }  
成果
 
 

曲線圖(圖五)


                                    調整後(圖六)                                    


曲線圖(圖七)


 調整後(圖八)

心得 :

Level 的部分套用上課推導出的公式,我們可以輕易的轉成程式碼,讓電腦幫忙計算,

並成功的調整照片色彩明暗度,而在Curve的部分我們可以比對圖六和圖八,兩張圖

分別為變亮和變暗,再觀察圖五和圖七,我們可以發現當曲線凹向下時,圖片整體會變亮,

而曲線凹向上則圖片整體變暗,而再這2次的作業裡,可以發現到影像處理的作業,基本上

都可以靠幾個迴圈就達成目的,只要對元件的操作用法熟悉,程式就能順利完成。



 



2016年12月8日 星期四

02360760 蘇明瑜 HW02

1.原圖

解說:
選用圖檔image讀檔

圖片顯示


2.PDF

Probability Density Function

解說:
連續隨機變數之機率函數稱為機率密度函數
定義為,連續隨機變數之變量為連續的,故若畫成直方圖為一圓滑曲線,該巨線在各變量上的高度表示各變量之機率密度,將各變量之機率密度以函數表示,即為機率密度函度。

圖片顯示


3.CDF

Cumulative Probability Function 

解說:
累積分配函數,也稱累加機率函數,定義為累積分配函數係用以求算特定變量之以下累加機率之函數。

圖片顯示

4.Histogram Equalization

解說:
直方圖均衡化是圖像處理領域中利用圖像直方圖對對比度進行調整的方法。
這種方法通常用來增加許多圖像的全局對比度,尤其是當圖像的有用數據的對比度相當接近的時候。通過這種方法,亮度可以更好地在直方圖上分布。這樣就可以用於增強局部的對比度而不影響整體的對比度,直方圖均衡化通過有效地擴展常用的亮度來實現這種功能。

圖片顯示



心得:
先統計每個顏色的個數,累積直方圖做出來再做成累積直方圖,接著把RGB每個顏色的累積個數除以RGB的各個總數,這個值就代表之前所包含的顏色出現的機率,最後只要把每個RGB的顏色都去乘上那個機率就完成了.而在此我遇到的問題是,一開始設想把圖片檔直接讀取在上方,採取大多圖片檔的格式jpeg,不過這樣就會發現會使程式碼錯誤,但若是將原本的圖片檔 ,經由重新另存新檔,選取bmp格式,問題便輕易解決了.

2016年12月4日 星期日

03360474 陳鈺翔 HW02

直方圖、直方圖均化


【直方圖均化】


用於增加影像的對比度,可以讓影像的亮度有更好的表現;實際實驗後發現在影像過度曝光、曝光不足或是背景前景太亮或太暗有不錯的效果,可以讓影像某些部份變得比較清楚,可是在對失焦的圖做均化則沒有什麼效果,甚至做完均化後圖片反而變得更糟......。

【程式撰寫】

1.畫出直方圖跟累積直方圖
部分程式碼:
//直方圖
//累積直方圖

2.直方圖均化
部分程式碼:
//計算累積最大值
//計算目前累積值
//直方圖均化
公式: g(x,y) = 255 * cdf( f(x,y) )  --->  色彩值 = 255 * ( 目前累積值 / 累積最大值 )

3.畫圖
部分程式碼:
利用TImage物件裡的內部函數就可以完成
//設定畫筆顏色(紅色)
//移動畫筆到點(x1,y1)
//從目前的點(x1,y1)畫一條線到(x2,y2)

【實驗結果】
1.過度曝光












2.影像部分區塊亮度不足

3.失焦

【心得】

對應上面的直方圖跟累積直方圖:
1.從直方圖可以發現,本來統計後很擠的位置,在做過均化後整個分散開來了。
2.從累積直方圖可以發現,都變成了比較像三角形的形狀,也就是說它的累積值的變化是比較固定的彼此之間不會有太大的差異。
以上兩點可以知道在做過均化後的圖片,影像的亮度變得更平均。
這些在上面實驗結果的第1跟2項可以看到紅圈部分變得更清楚了 !
寫完程式後,想了一下均化的用途是在對影像做對比度的調整,可以讓比較暗的地方變得比較亮、比較清晰;既然在影像過度曝光、曝光不足或是背景前景太亮或太暗的這些情況下使用會有不錯的效果,那麼再失焦的影像上做處理會有什麼情況產生了點興趣。均化後發現亮度的確變的平均了、本來不明顯的地方也變的明顯了,可是圖片變得更糟了,所以我覺得對失焦照片做均化應該是沒有什麼效果。
在寫影像處理程式的時候,通常使用雙重迴圈再加上幾行負責處理的程式碼就可以完成,而這次的直方圖以及累積直方圖也是如此,所以在寫程式的時候也沒有遇到什麼困難,比較要注意的只有在畫圖部分,TImage物件的(x,y)原點是在左上角,y往下是增加往上是減少,這邊跟平常習慣的不太一樣,所以花了點時間適應。唯一遇到問題是讀取某一些影像會出現"stream read error",雖然上網找了資料,可是看不懂......,目前只知道用Photoshop CS把影像存為BMP檔再用BCB打開的時候才會發生。


















05362640 周芸 HW02


直方圖與直方圖均化

直方圖統計原理:

        Bmp 圖片的存儲 ,每一個圖元按照B、G、R三個通道順序存儲其顏色值,顏色範圍從0-255,表示每個通道顏色的深淺,對圖片的每一個圖元顏色進行直方統計,就可以知道圖片的顏色是較為明豔還是暗淡,有利於對圖像的優化處理。而一個圖元有3個顏色,每個顏色有256種可能,256^3種顏色組合是非常巨大的,而且也不夠直觀,為了避免麻煩,因此對3個通道分別進行長條圖統計。

直方圖統計方法:

    宣告3個大小為256的陣列對圖像的每一個圖元進行顏色統計:


通過畫布畫出直方圖:


累積直方圖方法:



     
同理通過畫布畫出:


直方圖均化原理:

    將每個圖元顏色通道的累積比例*255 ,g(x, y) = cdf( f(x, y) ) * 255成為新的圖像的值,即可讓每一個顏色均分拉開成為一個長條圖,

長條圖均化方法:
由於圖片均勻的取色於區間(0-255),所以每一個長條圖都有傾向於均勻的分散的趨勢。

此時可以看到直方圖有拉開均化成為直方形狀的趨勢


而基本上顏色數值都是在(0-255)之間均勻取值,在累積時,每一次都會累積差不多的個數,所以累積圖的增長是呈現線性增長的。
均化後的累計直方圖也成了有規律的三角形狀


    顏色較為豔麗的圖片不適合做直方圖均化處理,而較為昏暗無光的圖片反而會有意想不到的效果:


存儲並打開處理後的圖像





因為讓圖片長條圖均化,均勻取色之後,顏色不會都集中在黑色部分,部分擴散到了接近白色,所以圖片在原本很灰暗的時候可以變的更清晰明亮一些。

介面設計:

為了方便觀看效果,弄成兩個視窗且不必切換



去除左邊的勾時可以隱藏該軌道的直方圖



TButton控制項使用:

按兩下控制項,和TmainMenu一樣直接編寫即可



TCombobox控制項使用:


按一下打開視窗


編輯下拉選項




編寫程式判斷:

void __fastcall TForm1::HistogramChange(TObject *Sender)

{
  if (ComboText == "Original_Histogram" && Image4->Picture!=NULL)

                    tempImage->Picture = Image4->Picture;

          else if(ComboText == "Now_Histogram" && Image2->Picture!=NULL)

                    tempImage->Picture = Image2->Picture;

}

TCheckbox控制項使用:

if(CheckBox1->State==cbChecked)

{

         //如果打勾執行程式

}

else

{

  //否則執行

}

    因為這裡分為了長條圖和累積長條圖兩種,而checkbox只是判斷通道,所以先用Tcombobox選擇是長條圖還是累積長條圖,然後將計算的數值存在固定的陣列X[256],然後check打勾時,只用將X[256]在畫布上畫出就可以了。

2016年12月2日 星期五

03360440曾郁凱HW02

作業內容 : 直方圖均化

這個作業可以分成幾個部分

1. 分別針對 BGR 三原色進行統計,製作影像直方圖

部分程式碼 :
   for (j=0;j<iImageHeight;j++)
      {
      bPtrImageRow = (Byte *)Image1->Picture->Bitmap->ScanLine[j];
      for (i=0;i<iImageWidth;i++)
         for (k=0;k<3;k++)
            iHistogram[ k ][ bPtrImageRow[ i * 3 + k ]  ]++;         
      }

2. 要了解畫筆(Pen)與刷筆(Brush)兩項元件,以便製作直方圖(Histogram)

重點 :
         一單位         : (畫布高度) / (統計出的最大值) 
         要畫的長度 :  一單位 * (0~255統計的數量)
        
3. 將直方圖轉為累積直方圖
部分程式碼 :
   for (j=1;j<256;j++)
      {
      for (k=0;k<3;k++)
         {
         iHistogram[ k ][ j ]+= iHistogram[ k ][ j - 1 ]; 
         }
      }

4. 直方圖均化

公式 =g(x, y) = cdf ( f(x, y) ) * 255
重點 :
         新的色彩值 = ( (目前累積的量)/(累積最大值) ) * 255
 部分程式碼 :
    for (j=0;j<iImageHeight;j++)
       {
       bPtrImageRow = (Byte *)Image1->Picture->Bitmap->ScanLine[j];
       bPtrImageRow1 = (Byte *)Image8->Picture->Bitmap->ScanLine[j];
       for (i=0;i<iImageWidth;i++)
          {
          bPtrImageRow1[3*i+0] = 新的色彩值[ [bPtrImageRow[3*i+0] ];
          bPtrImageRow1[3*i+1] = 新的色彩值[ [bPtrImageRow[3*i+1] ];
          bPtrImageRow1[3*i+2] = 新的色彩值[ [bPtrImageRow[3*i+2] ];
          }
       }  
實驗結果 :

圖片1 . 原始影像


圖片2 . 原始影像之直方圖



圖片3 . 直方圖均化後之影像


圖片4 . 處理後之直方圖

心得 : 
         我們可以觀察到圖片1和圖片3之間的差異,處理後的影像明顯的影像亮度更平均 ,

         而影像處理的程式通常都可以用幾個迴圈就達到目的,靠著其背後強大的演算法,

         這次的作業也是靠著一個簡單的公式,就能將圖片做直方圖均化,寫完非常有成

         就感,感覺能寫出功能簡單的Photoshop。