作業內容:
直方圖均化
影像直方圖:影像分成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);
來提醒使用者 還沒有載入圖片。
有沒有先做過直方圖再做均化 也可以用if來判斷。