一部の情報は非常に古いもの(20年以上前〜)ですので、利用する際はご注意ください(Java 1.4 とか .NET 1.0 とか、Windows 2000 とか)
お問い合せは wiki@shise.net まで。Gmail に転送されるので、スパムは全部カットされます。
最初に補足
このページでは、C# 単体で画像のグレースケール変換を行っています。
画像の複雑な処理、画像の認識などの場合は OpenCV を利用すると良いと思います(外部 DLL 使います)
参考 URL:
schima.hatenablog.com - OpenCvSharpをつかう
C# で画像の中に一致するパターンがあるか探す
まず
画像処理をしたいと思った。
Bitmap クラスには、GetPixel 、SetPixel というメソッドがあるので、それを使って一ピクセルずつ処理してみた。
が!!!
これがまたクソ遅い。半端じゃない。
なので、バイト列をいぢって画像を操作する方法を検索して、出来たのでメモ。
ちなみに、ピクセル操作と、バイト列操作では、100 倍くらい処理時間が違う。
SetPixel、GetPixel を使って処理すると、9000ms かかるが、
バイト列を取り出して操作すると、90ms で終わる、といった具合。
int 型とかビットシフトとかで演算してるけど、浮動小数点の演算が得意な CPU があるとか無いとかで、下手に int でやるより float でやったほうが早いとの話もあるが、試してないのでよく分からない。
・・・・・・・・・・てか、
画像処理は MSDN に、ちゃんとサンプルあったし。(ノ∀`)ペチッ
http://msdn.microsoft.com/ja-jp/library/system.drawing.imaging.bitmapdata.scan0.aspx
グレイスケール化
using System; using System.Drawing; // 参照設定に System.Drawing を追加する必要アリ using System.Drawing.Imaging; using System.Runtime.InteropServices;
// 画面キャプチャ Bitmap bmp = ScreenCapturer.CaptureDesktopImage(); // 画像データをメモリ上に固定? BitmapData bmpdata = bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb ); // グレイスケール用のアレ int rp = (int)(0.298912 * 1024); int gp = (int)(0.586611 * 1024); int bp = (int)(0.114478 * 1024); // バイト配列にコピー byte[] ba = new byte[bmp.Width * bmp.Height * 4]; Marshal.Copy(bmpdata.Scan0, ba, 0, ba.Length); // 処理 int pixsize = bmp.Width * bmp.Height * 4; for (int i = 0; i < pixsize; i += 4) { // 画像のバイト列って、ARGB じゃなくて、BGRAになってるっぽい?? // リトルエンディアンか。 byte g = (byte)((bp * ba[i + 0] + gp * ba[i + 1] + rp * ba[i + 2]) >> 10); ba[i + 0] = g; // ブルー ba[i + 1] = g; // グリーン ba[i + 2] = g; // レッド ba[i + 3] = 0xFF; // アルファ } // 元のところに書き込む。 Marshal.Copy(ba, 0, bmpdata.Scan0, ba.Length); bmp.UnlockBits(bmpdata);
これで、bmp は、グレイスケール化されました。
めでたしめでたし。
ちなみに、ScreenCapturer は、どこかこのへんからコピってきた、C# でスクリーンキャプチャー(スクリーンショット?)とれるやつ。