質問内容
二値画像で白のみの画像を高速に判定したい。
どのようにすればよいのでしょうか。
現状
現在のコード
C#
1 public static bool checkWhite(string path) 2 { 3 Bitmap img = new Bitmap(path); 4 bool flg=false; 5 for (int x = 0; x < img.Width; x++) 6 { 7 for (int y = 0; y < img.Height; y++) 8 { 9 Color c = img.GetPixel(x, y); 10 if(c.R !=255 || c.G != 255 || c.B != 255) 11 { 12 flg = true; 13 break; 14 } 15 } 16 if (flg) { break; } 17 } 18 19 //ロックを解除する 20 img.Dispose(); 21 return !flg;
これで一応は判定できています。
ただ、これだと遅いので早くしたいと考えています。
ネットで調べた所、以下のようなコードでどうにか早く出来るかもと思ったのですが
C#
1 PixelFormat pixelFormat = img.PixelFormat; 2 int pixelSize = Image.GetPixelFormatSize(pixelFormat); 3 if (pixelSize != 1) 4 { 5 throw new ArgumentException( 6 "1ピクセルあたり1ビットの形式のイメージのみ有効です。", 7 "img"); 8 } 9 10 //Bitmapをロックする 11 BitmapData bmpData = img.LockBits( 12 new Rectangle(0, 0, img.Width, img.Height), 13 ImageLockMode.ReadWrite, 14 pixelFormat); 15 16 unsafe 17 { 18 byte* pixelPtr = (byte*)bmpData.Scan0; 19 // どうしたらいいのかわかりません。 20 } 21 22 //ロックを解除する 23 img.UnlockBits(bmpData);
どうしたらいいのかわかりません。
pixelPtr がバイト配列?で、8ピクセル分ずつ入っていると思うのですが
どう入っているかがよくわかっていません。
とりあえず、白だけの画像を読み込ませると
pixelPtr の前の方は255だったのですが
改行の辺りで255以外の値が入っていました。
少なくとも、
> if(c.R !=255 || c.G != 255 || c.B != 255)
> {
> flg = true;
> break;
> }
白以外の画素を検出してもimg.Widthのループを無用に続行していますね。
確かに。
指摘ありがとうございます。
帰宅後質問のコードも修正しておきます
> とりあえず、白だけの画像を読み込ませると
> pixelPtr の前の方は255だったのですが
> 改行の辺りで255以外の値が入っていました。
食わせた画像の幅(横pixel数)が8の倍数でなかったらそうなるのでは?
横のピクセル数は確認しなおします。1000だった気がしてます。
しかし、もしかしてy座標が変わるところで何かデータが入っていて
それを含めたデータ幅がStrideなのでしょうか。
↑YES. 切りのいい横幅にしてパフォーマンスを上げるため、
末尾には適当に"埋め草(padding)"が挿入されます。
たとえば画像の横幅が1000だとすると125byte(1pix=1bitなら)、
これをたとえば切りのいい128byteにすべく、3byteの埋め草が入ったりとか。
コメントありがとうございました。
お陰でStrideの意味がわかりました。
回答1件
あなたの回答
tips
プレビュー