- ベストアンサー
VB.NETにおける二値化処理の高速化
いつも参考にさせて頂いております。 現在、VB.NET(VS2003/.NET Framework1.1)を使用して画像の二値化処理のプログラムを作成しております。 処理する事は簡単で、ビットマップファイルのRED要素を取り出し、閾値内なら白に変換して二値化するプログラムです。 以下がそのプログラムです。 ----- '変換する前の画像をファイルから読み込む Dim img1 As System.Drawing.Bitmap = New System.Drawing.Bitmap(filepath) '変換後のビットマップ Dim img2 As System.Drawing.Bitmap = New System.Drawing.Bitmap(img1.Width, img2.Height) '二値化処理 Dim b As Byte For i = 0 To img1.Width - 1 For j = 0 To img1.Height - 1 b = img1.GetPixel(i, j).R If b >= 閾値下限 And b <= 閾値上限 Then img2.SetPixel(i, j, Color.White) Else img2.SetPixel(i, j, Color.Black) End If Next Next PictureBox1.Image = img ----- これで処理は出来るのですが、ファイルが大きい場合は、非常に時間が掛かってしまいます。処理速度はCPUの速度にもよると思うのですが、できるだけ高速化したのですが、何かよい知恵があればご教授頂けると助かります。よろしくお願いいたします。 XP Pro SP2/VS2003/VB.NET/.NET Framework1.1
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
If b >= 閾値下限 And b <= 閾値上限 Then これを If b >= 閾値下限 AndAlso b <= 閾値上限 Then に変えてみる。 If 条件A And 条件B では、必ず条件A と条件B を演算してしまうが、 If 条件A AndAlso 条件B では、条件A が False なら条件B の演算は行わない。
その他の回答 (1)
- sgwjn
- ベストアンサー率70% (47/67)
どこまで効果があるかはわかりませんが、以下の部分を変更すると多少高速になるかもしれません。 (1)i, j がInteger型の場合は、Long型に変更する (2)ループ処理の縦横の参照順を入替える (3)閾値判定を AND から OR に変更する (4)img2を作成せず、img1を書換える (5)(4)を前提に、With~End With を使用する (1)は、CUPが32bitの場合は、多少高速になります。 (2)は、VB.netの配列のメモリ上の配置がどうなっているか知りませんが、A(x1, y1, z1)、A(x2, y1, z1)、A(x3, y1, z1)の順に配置されていれば、メモリの参照が高速になります。そうでなければ遅くなります。 (3)は、 if b >= 閾値下限 And b <= 閾値上限 Then img2.SetPixel(i, j, Color.White) Else img2.SetPixel(i, j, Color.Black) End If の部分を、 if b < 閾値下限 Or 閾値上限 < b Then img2.SetPixel(i, j, Color.Black) Else img2.SetPixel(i, j, Color.White) End If とし、尚且つ、 if b < 閾値下限 Or 閾値上限 < b Then の判定の1つ目の条件に成立する可能性が高い条件を持ってきます。上記の例では、閾値上限 < b よりも b < 閾値下限 の方が成立しやすいと仮定しています。 これは、2つ目の判定条件をなるべく判定させないようにするためです。 (4)は、ファイルサイズが大きくなると遅くなるというのは、反復回数が増えることが主原因だと思いますが、データ量が多すぎてスワップが発生しているということもあるかもしれません。処理中に保持するデータ量を減らせばスワップが発生しにくくなり、高速になるかもしれません。 (5)はうろ覚えですが、(4)でインスタンスを img1 のみとした後で、2つのFor文を With img1 ~ End With で囲むと、インスタンスの参照回数が減って高速になるような気がします。 高速化は、やってみないと分からない部分もありますので、断定的なことは書けませんが、もし良ければお試しください。
お礼
早速のアドバイスに感謝しております。 (1)は直ぐに実践してみます。 (2)も試して検証をしてみます。 (3)はAndAlsoを使用して2つ目の条件を判定しないように工夫してみます。 (4)はimg1を後で使用するので今回は実践できませんが、他で応用ができます。 (5)も試して検証をしてみます。 確かに高速化は試行錯誤の繰り返しだと思いますので、色々と試してみて活路を見出すしかないですね。 今回は、有益なヒントを頂き、ありがとうございました。
お礼
早速の回答、ありがとうございます。 AndSlsoと言うキーワードがある事すら知りませんでした。 非常に有益な情報をありがとうございます。 すぐにFalseになる可能性が高い条件を最初に持ってきてAndAlsoに変更して検証してみます。