程式碼 => https://www.dropbox.com/s/otc61q4ryfbuhqo/Unit1.cpp?dl=0
這次作業要分析圖片的色彩值並做成直方圖
圖1.主程式的樣貌
圖1是主程式的樣貌,主目錄Open底下的Image是開啟圖片,C++ Builder只支援bmp檔請注意,Image底下的Add是將色彩值出現的次數加起來,Histogram底下分別為Blue、Green、Red,分別畫出這三個的直方圖及累積直方圖,下面的3個TabSheet 分別是開啟的圖、直方圖、累積直方圖,至於為什麼沒有改,因為還不會改
圖2. 開啟圖片後
圖引(id=8424385)
開啟圖片後的樣子如圖2,有加上ScrollBox使得圖太大可以拖曳(右方及下方),上方Image底下有個Add,按下去將會計算這張圖的色彩值次數
上方三張圖由上至下分別是Blue的直方圖、Green的直方圖、Red的直方圖
統計部分如下:
iBlue[bPtrImageRow[3*j]]++;
iGreen[bPtrImageRow[3*j+1]]++;
iRed[bPtrImageRow[3*j+2]]++;
由bPtrImageRow讀取每個像素點再由各個顏色相對應的陣列儲存
上方三張圖由上至下分別是Blue的累積直方圖、Green的累積直方圖、Red的累積直方圖,看起來好像一樣但其實是有差的
統計部分如下:
iBlueSum[0]=iBlue[0];
iGreenSum[0]=iGreen[0];
iRedSum[0]=iRed[0];
for(int k=1;k<256;k++){
iBlueSum[k]+=iBlue[k]+iBlueSum[k-1];
iGreenSum[k]+=iGreen[k]+iGreenSum[k-1];
iRedSum[k]+=iRed[k]+iRedSum[k-1];}
至於為什麼要事先先給第0個位置的值才開始迴圈,因為回圈內會呼叫k-1,從0開始的話會呼叫到-1,所以特別先做,迴圈的k也從1開始而非0
至於畫出直方圖的部分,一開始很單純就照著得到的值畫,結果理所當然的衝出去,所以要想辦法將圖給縮小,最後使用比例的算法
將每個值代入(x*450)/x-Max,用得到的新值畫圖
x是指第幾個色彩值,x-Max是指此色彩中最大的色彩值,目的是將最大值壓成450,其餘的值等比例減少,500是畫布的高而不是450,會設450的目的是想讓直方圖好看一些
比較大的問題是比例的部分,我最大的問題其實是─ 一開始拿來跑的圖是同一色系,導致直方圖某個值太大而其他值低到感覺不到變化,以為程式哪裡寫錯
本以為這次的作業不難,以為找色彩值是最難的部分,已經知道怎麼找色彩值而且老師上課又有教過,但發現到比例的問題時,才知道色彩值根本天差地遠,這次作業寫起來很好玩,而且又是馬上執行就看的到自己做的成果,寫出來真的有成就感。