2010年11月5日 星期五

HW1

因為我不確定128、64、32、16、8、4、2色的值,
是要彩色圖片轉成灰階後取轉換後的128、64、32、16、8、4、2色的值,
還是彩色圖片取128、64、32、16、8、4、2色的值之後再轉成灰階。
因此我寫了這兩部分的程式。

第一部分:
彩色圖片取128、64、32、16、8、4、2色值之後再轉成灰階。

















































































第二部分:
彩色圖片轉成灰階後取轉換後的128、64、32、16、8、4、2色的值。

















































































這次的作業我覺得非常容易,不管是第一部分或第二部分,
每個色值的判斷都只要幾行短短的程式結果就出來了。
比較需要思考的地方我認為只有如何取得128、64、32、16、8、4、2色的值,
而我研究出來的數學公式為: ( 256 * n ) / L

n: 所需的顏色數-1

L: 256 / ( n + 1 )

之後只要將計算取得色值的公式,加入程式中並加上判斷設值的轉換範圍,
這樣程式就寫完了。
程式碼如下:
for(i=0; i< iImageWidth; i++)
{
for(j=0; j< iImageHeight; j++)
{
R=GetRValue(Image1->Canvas->Pixels[i][j]); //先將圖片中的RGB個別取出
G=GetGValue(Image1->Canvas->Pixels[i][j]);
B=GetBValue(Image1->Canvas->Pixels[i][j]);

for(k=4,n=0;k<=256,n<=63;k=k+4,n++) //n為顏色數,k為強度
{
if(k-4<= R && R< k)
R=(256*n)/63; //算出該取的顏色數值
if(k-4<=G && G< k)
G=(256*n)/63;
if(k-4<=B && B< k)
B=(256*n)/63;
if(R==256)
R=255;
if(G==256)
G=255;
if(B==256)
B=255;
gray=(0.299*R+0.587*G+0.114*B);
Image64Color->Canvas->Pixels[i][j]=RGB(gray,gray,gray);
}
上面的執行結果是比較簡單的轉換法,
後來我嘗試使用直接去呼叫記憶體中的值去轉換,
但是發生了轉換後的圖改變了原本的彩色圖,
造成色彩混亂,目前這部分還在研究中。

P.S:關於呼叫記憶體發生錯誤的問題,在老師的協助下解決了。
原來只是我那部分寫得太複雜了,導致後來讀圖的時候取影響到了原本的彩色圖片。
之後聽老師上可講解老師的程式,發現我的寫法還是比較複雜,
寫得行數還是太多了,還是可以再更簡短的,這部分的能力還得再加強。

下方為聽完老師講解後修改出來的程式
for (i=0; i<256; i++)
{
pal.peRed = GrayLevel[i/4]; //在調色盤進行顏色的選取
pal.peGreen = GrayLevel[i/4];
pal.peBlue = GrayLevel[i/4];
SetPaletteEntries(GrayHandle,i,1,&pal);
}
imNew->Picture->Bitmap->Palette = GrayHandle;


for (j=0;j {
bPtrImage = (Byte *)Image1->Picture->Bitmap->ScanLine[j];
bPtrNewImage = (Byte *)imNew->Picture->Bitmap->ScanLine[j];

for (i=0;i< iImageWidth;i++)
bPtrNewImage [i]=(Byte)(0.299*bPtrImage[i*3+2]+0.587*bPtrImage[i*3+1]+0.114*bPtrImage[i*3]);
}
在執行後,比我之前寫的執行速度還要更快,而且也少了冗長的判斷,
就算判斷其它位元強度也只需要更改GrayLevel[i/4]; 紅色字的數值,
而且閱讀上也更加方便,真的事讓我受益良多,該學的還多的很。

沒有留言:

張貼留言