2015年10月29日 星期四

資工三乙 02360386 柯明男 HW2

作業內容:直方圖均化

影像直方圖:影像分成RGB,並且統計0~255 的數量

作法:

(畫布高度) / (統計出的最大值)  * (0~255的統計數量) 就是0~255 要畫出來的長度了。

程式碼:

        float 紅色基準點 = 128/float(紅色最大值);
        float 綠色基準點 = 128/float(紅色最大值);
        float 藍色基準點 = 128/float(紅色最大值);
        for(int i=0; i<256; i++)
        {
            //畫布大小為(128,128)
            //此處0.5 為 128/256
            Image5->Canvas->MoveTo(0.5*float(i),128);
            Image5->Canvas->LineTo  (0.5*float(i),128-紅色基準點*紅色直方圖[i]);
            Image6->Canvas->MoveTo(0.5*float(i),128);
            Image6->Canvas->LineTo  (0.5*float(i),128-綠色基準點*綠色直方圖[i]);
            Image7->Canvas->MoveTo(0.5*float(i),128);
            Image7->Canvas->LineTo  (0.5*float(i),128-藍色基準點*藍色直方圖[i]);
        }


圖片1.影像直方圖

直方圖均化:講影像色彩平均化拉開,進行對比度調整

作法:

將統計出來的直方圖作cdf轉成累積直方圖,再將 255 * (目前累積的量) / (累積的最大值) 
及為新的色彩值了。

程式碼:

        for(int i=1;i<256;i++)
        {
            //在這邊第255個值極為最大值
            新的紅色色彩值[i] = int(255*(float(累積紅色值[i])/累積紅色值[255]));
            新的綠色色彩值[i] = int(255*(float(累積綠色值[i])/累積綠色值[255]));
            新的藍色色彩值[i] = int(255*(float(累積藍色值[i])/累積藍色值[255]));
        }
        for(int j=0; j<iImageHeight; j++)
        {
            BYTE *bPtrImageRow = (Byte *)Image4->Picture->Bitmap->ScanLine[j];
            for(int i=0; i<iImageWidth; i++)
            {
                bPtrImageRow[3*i+0]=新的藍色色彩值[bPtrImageRow[3*i+0]];
                bPtrImageRow[3*i+1]=新的綠色色彩值[bPtrImageRow[3*i+1]];
                bPtrImageRow[3*i+2]=新的紅色色彩值[bPtrImageRow[3*i+2]];
            }
        }

 
圖片2.直方圖均化



 圖片3.處理後的直方圖

延伸問題:

ComboBox:

為了讓我可以隨時切換要看哪一個直方圖
所以我新增了一個 ComboBox 來做選單
而選單中的資料可以用 ComboBox1->Items->Add() 來新增
或者是在介面設計的地方 他的屬性裡面的Item也可以新增

 
圖片4.ComboBox新增List

程式碼及TImage宣告的的問題:

程式碼只要判斷ComboBox1->Text就可以只到使用者要看哪個圖的直方圖
    TImage *tempImage = new TImage(this);
    String ComboText=ComboBox1->Text;
    if (ComboText == "Image1" && Image2->Picture!=NULL)
        tempImage->Picture = Image2->Picture;
    else if(ComboText == "Image2" && Image4->Picture!=NULL)
        tempImage->Picture = Image4->Picture;

但是這裡會遇到一個問題 在compile的時候會出現
[Linker Error] Unresolved external '__fastcall Extctrls::TImage::TImage(Classes::TComponent *)' referenced from
並且停在TImage宣告的地方
上網查資料料之後發現,老師的Bloger裡面有解答: 點我

解決辦法: 
Project > Options > Packages >Runtime Packages中的
Build with Runtime Packages 的勾勾去掉 即可

圖片5.解決TImage宣告問題 

畫布得刷新:

因為不斷的重新畫直方圖但是3個畫布不會自動清空。

解決辦法:

1.     mage5->Canvas->Brush->Color= clWhite;
        Image5->Canvas->Rectangle( TRect(0, 0,128, 128)); 
此方法就是在畫布上面放一個白色的矩形
不過會因為pen的顏色的關係 會有個邊框在
結果辦法就是設定成 TRect(-1,-1,129,129)即可

2.     Image5->Picture=NULL; 
不過此方法會把一些基本的設定改掉 需要每次都重新設定畫筆大小及顏色
  

防呆設定:

防止使用者沒有載入圖片 新增了 bool bLoad; 當有載入就改成true
這樣只要判斷if (bLoad) 即可知道有沒有載入了
如果沒有載入則用 Application->MessageBox("圖片未載入","錯誤",0);
來提醒使用者 還沒有載入圖片。
MessageBox 相關指令網址: 點我
有沒有先做過直方圖再做均化 也可以用if來判斷。 


程式碼:點我

沒有留言:

張貼留言