【.NET】カラー行列(ColorMatrix)で画像をグレースケール化する
C#、VB.NETでカラーの画像をグレースケール化するのに、ColorMatrixが使えます。
グレースケールとは、全てのピクセルにおいてR(赤)とG(緑)とB(青)の値が等しくなるような色、つまり、白、灰色(濃淡あわせて)、黒だけで描画した状態です。
(写真はうちの犬です。)
今回、カラー画像をグレースケール化するのに使用するのは、NTSC加重平均法と呼ばれる方法です。
(ColorMatrixの説明は、前回のカラー行列(ColorMatrix)で画像のRGBの値を調整するをご覧ください。)
カラーをグレーにするには?
カラーをグレーにするには、各ピクセルの明るさの違いだけを残して、RとGとBの差がないような色にします。
単純なのは、
(R + G + B) ÷ 3
という風に平均をとってしまう方法です。
しかし、人間の目には、色の違いによって明るさが違うように見えます。
色による明るさの感じ方
下の画像は、R(赤)とG(緑)とB(青)のうちいずれか一つを最大にし、他はゼロにした色で塗った四角形です。
しかし、おそらく、緑が一番明るく、次に赤、一番暗いのは青と感じるのではないでしょうか?
より自然な感じにするには、この色による心理的な感じ方の差を反映する方法を用いた方が良いです。
NTSC加重平均法
NTSCは、National Television Standards Committeeによって定められたアメリカや日本で使われるアナログのテレビに使われる規格です。
NTSCでは、白黒放送と両立させるために輝度信号と色信号にわけられています(YIQカラーモデル)
色による明るさの感じ方の違いを考慮しており、輝度信号(Y)とRGBの関係は以下の式で表されます。
Y = R × 0.298912 + G × 0.586611 + B × 0.114478
プログラムのサンプル
上記のRGBと輝度との関係をプログラムに使ってみます。
最終的にRGBのそれぞれに上の式のYを入れます。
'VB.NETのサンプル '(Imports System.Drawing.Imagingが必要) 'ファイルを読み込む Dim sourceImage As Bitmap = _ DirectCast(Bitmap.FromFile("ファイル名.bmp", True), Bitmap) 'RGBの比率(YIQカラーモデル) Const r As Single = 0.298912F Const g As Single = 0.586611F Const b As Single = 0.114478F 'ColorMatrixにセットする行列を 5 * 5 の配列で用意 '入力のRGBの各チャンネルを重み付けをした上で、 '出力するRGBがR = G = B となるような行列をセット Dim matrixElement As Single()() = _ {New Single() {r, r, r, 0, 0}, _ New Single() {g, g, g, 0, 0}, _ New Single() {b, b, b, 0, 0}, _ New Single() {0, 0, 0, 1, 0}, _ New Single() {0, 0, 0, 0, 1}} 'ColorMatrixオブジェクトの作成 Dim matrix As ColorMatrix = New ColorMatrix(matrixElement) 'ImageAttributesにセット Dim attr As ImageAttributes = New ImageAttributes() attr.SetColorMatrix(matrix) Dim imageWidth As Integer = sourceImage.Width Dim imageHeight As Integer = sourceImage.Height '新しいビットマップを用意 Dim changedImage As Bitmap = New Bitmap(imageWidth, imageHeight) '新しいビットマップにImageAttributesを指定して '元のビットマップを描画 Dim graph As Graphics = Graphics.FromImage(changedImage) graph.DrawImage(sourceImage, _ New Rectangle(0, 0, imageWidth, imageHeight), _ 0, 0, imageWidth, imageHeight, _ GraphicsUnit.Pixel, _ attr) graph.Dispose() '--表示や保存などの処理をここに記述-- '使い終わったら後始末 'sourceImage.Dispose() 'changedImage.Dispose()
//C#のサンプル //(using System.Drawing.Imaging;が必要) //元のイメージを読み込む Bitmap sourceImage = (Bitmap)Bitmap.FromFile(@"ファイル名.bmp", true) //RGBの比率(YIQカラーモデル) const float r = 0.298912F; const float g = 0.586611F; const float b = 0.114478F; //ColorMatrixにセットする行列を 5 * 5 の配列で用意 //入力のRGBの各チャンネルを重み付けをした上で、 //出力するRGBがR = G = B となるような行列をセット float[][] matrixElement = {new float[]{r, r, r, 0, 0}, new float[]{g, g, g, 0, 0}, new float[]{b, b, b, 0, 0}, new float[]{0, 0, 0, 1, 0}, new float[]{0, 0, 0, 0, 1}}; //ColorMatrixオブジェクトの作成 ColorMatrix matrix = new ColorMatrix(matrixElement); //ImageAttributesにセット ImageAttributes attr = new ImageAttributes(); attr.SetColorMatrix(matrix); int imageWidth = sourceImage.Width; int imageHeight = sourceImage.Height; //新しいビットマップを用意 Bitmap changedImage = new Bitmap(imageWidth, imageHeight); //新しいビットマップにImageAttributesを指定して //元のビットマップを描画 Graphics graph = Graphics.FromImage(changedImage); graph.DrawImage(sourceImage, new Rectangle(0, 0, imageWidth, imageHeight), 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, attr); graph.Dispose(); //--表示や保存などの処理をここに記述-- //使い終わったら後始末 //sourceImage.Dispose(); //changedImage.Dispose();
サンプルプログラムのダウンロード
関連図書
ディジタル画像処理の基礎と応用 改訂版―Visual C#.NET&Visual Basic.NETによる 基本概念から
関連記事
TrackBack URL :
Comments (2)
PictureBoxのImageをグレーアウト C#
ツールバーなどで表示する画像を そのボタンが使えないときに(Enabled=false)
画像をグレーアウト処理したいと思い調べていると
CommentOut? » 【.NET】カラー行列(ColorMatrix)で画像をグレー…
トラックバック by SOHOプログラマのぼやき @Links[アットリンクス] — 2008/6/5 木曜日 @ 18:29:10
大変参考になりました。
今後も利用させていただきます!
コメント by しおじ — 2008/11/25 火曜日 @ 16:50:18