映像由彩色轉化為灰階的過程叫灰階化,也叫去色。 彩色映像灰階化的原理很簡單,就是按某種計算方法將映像各像素的R、G、B分量取成同樣的值即可。計算方法有幾種: 1、每個像素R、G、B各分量的值為該象素R、G、B的平均值; 2、每個像素R、G、B各分量的值為該象素R、G、B中最大值; 3、按YUV色彩空間原理,每個像素R、G、B各分量的值為:Y = 0.3R + 0.59G + 0.11B。 在Delphi程式的具體應用中,一般是對映像各像素點逐點取值、計算和修改等過程實現的,很繁瑣,而且效率不高。 使用GDI+,通過對ColorMatrix矩陣數組進行適當設定,可以很很輕鬆的搞定。下面是個按YUV色彩空間原理對彩色映像灰階化的Delphi過程:
implementation
uses Gdiplus, GdipTypes;
// 彩色映像灰階化
procedure GrayImage(Image: TGpImage);
const
ColorMatrix: TColorMatrix =
((0.3, 0.3, 0.3, 0.0, 0.0), // Red
(0.59, 0.59, 0.59, 0.0, 0.0), // Green
(0.11, 0.11, 0.11, 0.0, 0.0), // Blue
(0.0, 0.0, 0.0, 1.0, 0.0), // Alpha
(0.0, 0.0, 0.0, 0.0, 1.0));
var
Tmp: TGpImage;
attr: TGpImageAttributes;
g: TGpGraphics;
begin
Tmp := Image.Clone;
g := TGpGraphics.Create(Image);
attr := TGpImageAttributes.Create;
try
attr.SetColorMatrix(ColorMatrix);
g.DrawImage(Tmp, GpRect(0, 0, Image.Width, Image.Height),
0, 0, Tmp.Width, Tmp.Height, utPixel, attr);
finally
g.Free;
attr.Free;
Tmp.Free;
end;
end;
// 測試
procedure TForm1.Button1Click(Sender: TObject);
var
Image: TGpImage;
g: TGpGraphics;
begin
Image := TGpImage.Create('..media41001.jpg');
GrayImage(Image);
g := TGpGraphics.Create(Handle, False);
g.DrawImage(Image, 10, 10);
g.Free;
image.Free;
end;
可以看出,過程中的實現代碼相當簡單,主要是try ... finally之間2句的代碼,而起關鍵作用的就是這個ColorMatrix。
對於ColorMatrix,有關資料是這樣的介紹的:
GDI+ 提供用於儲存和操作映像的 Image 和 Bitmap 類。Image 和 Bitmap 對象將每個像素的顏色都儲存為 32 位的數:紅色、綠色、藍色和 alpha 各占 8 位。這四個分量的值都是 0 到 255,其中 0 表示沒有亮度,255 表示最大亮度。alpha 分量指定顏色的透明度:0 表示完全透明,255 表示完全不透明。
顏色向量採用 4 元組形式(紅色、綠色、藍色、alpha)。例如,顏色向量 (0, 255, 0, 255) 表示一種沒有紅色和藍色但綠色達到最大亮度的不透明顏色。 表示顏色的另一種慣例是用數字 1 表示亮度達到最大。使用這種慣例,上一段中描述的顏色將用 (0, 1, 0, 1) 表示。GDI+ 在進行顏色變換時使用以 1 表示最大亮度的慣例。 可通過用 4×4 矩陣乘以這些顏色向量將線性變換(旋轉和縮放等)應用到顏色向量中。但是,您不能使用 4×4 矩陣進行平移(非線性)。如果在每個顏色向量中再添加一個虛擬第 5 座標(例如,數字 1),則可使用 5×5 矩陣應用任何組合形式的線性變換和平移。由線性變換組成的後跟平移的變換稱為仿射變換。
從原理上說,ColorMatrix並不難理解,主要通過矩陣運算對顏色向量進行線性或非線性轉換,以達到對映像的各種數文書處理的目的。我在網上看到有很多人對於矩陣中的虛擬位不理解,而解答的的人可能心裡明白,卻也總是說的不徹不透,有時還把人越說越糊塗,似乎這個概念只可意會,不可言傳。其實上面的解答已經很明確的,4*4矩陣只能進行顏色的線性變換,而不能進行非線性變換和平移,這就相當4把椅子坐了4個人,無法相互移位,如果加一把空椅,就可方便的實現移位了,這把空椅就是虛擬位!如果還不明白,可以看一下《大唐雙龍傳》,估計很多人都看過,這個虛擬位就是小說中所謂的“遁去的一”!^_^ 從實際應用看,要真正熟練運用ColorMatrix卻也並非那麼簡單,必須同時具備較好的數學和電腦圖形學知識以及較高水平的編程能力,才能做到隨心所欲的運用。本人由於各方面都很差,所以至今也沒有完全搞明白它的一些具體運用(比如昨天發的文章《GDI+ 在Delphi程式的應用 -- 調整映像亮度》,對於映像亮度調整,我知道可以用ColorMatrix來實現,而不必逐點計算,但實驗了幾次,確實能夠調整,但總是不很理想)。 後記:使用ColorMatrix確實能夠調整圖象亮度,見《GDI+ 在Delphi程式的應用 -- ColorMatrix與映像亮度》,(2007.11.17)