エッジと長方形を検出する方法


14

画像内の長方形を検出しようとしています。画像の背景は1色です(ほとんどの場合)。バイナリイメージ(1 =背景、0 =エッジ)を取得し、後でハフ変換を実行する2つの方法を試しました...

  1. ソーベルまたはキャニーフィルター

  2. 滑らかな画像A、差分画像Aの作成-ガウス、しきい値付きのバイナリ画像の作成(ヒストグラムの作成、最高ビンは背景にする必要があります...)

結果は、エッジのあるバイナリイメージです。さまざまな異なる画像に対してどの方法がよりうまく機能するかは、今ではわかりません。何か案は?


1
「より良く働く」とはどういう意味ですか?キャニーは、この種のことで非常に人気がありますが、それはあなたがエッジを取得した後に何をしようとしているかに依存します。正確に何を達成しようとしていますか?
ポールR

4
コミュニティでの最初の質問に対して新規ユーザーを下票しないでください!

1
このスレッドはuseful-かもしれないdsp.stackexchange.com/questions/2975/...
ジム・クレイ

エッジ検出器の説明:dsp.stackexchange.com/q/74/1273
ペネロペ

「結果はエッジのあるバイナリイメージです。現在、どの方法がさまざまな異なるイメージに適しているかはわかりません。アイデアはありますか?」おそらく、あなたが答えを見つけるために、またはあなたが数えるかもしれない環境でいくつかの写真を撮るために、いくつかの画像テストライブラリが必要です。この分野に最高のアルゴリズムが存在する場合、なぜ他の多くのアルゴリズムを学ぶ必要があるのでしょうか?確率的な意味で、どのアルゴリズムにも利点があると思います。

回答:


10

かつて、長方形の検出用のアプリケーションを作成しました。Sobelエッジ検出とラインハフ変換を使用しました。

ハフ画像(線)で単一のピークを探す代わりに、プログラムは90度の距離で4つのピークを検索しました。

ハフ画像の各列(ある角度に対応)について、他の3つの列の局所的最大値を検索しました。4つの列のそれぞれに十分なピークが見つかった場合、長方形が検出されています。

プログラムは長方形を作成し、長方形の内外で色の一貫性をチェックして、誤検知を判別しました。このプログラムは、スキャンされた用紙の用紙配置を検出するためのものでした。


5

ラプラシアンオブガウスエッジ検出器の方が適している場合があります。キャニーエッジ検出器よりも頻繁に閉じた輪郭が得られるはずです。あなたの次のステップはハフ変換を適用することなので、私はそれがあなたが望むものだと信じています。


2

あなたにとっては役立つかもしれませんが、今日このサイトを訪れるのは遅すぎます

        Bitmap bmp=new Bitmap(pictureBox1.Image);
        int x1=0, x2=0, y1=0, y2=0;            
        for (int i = 1; i < bmp.Height;i++ )
        {                
            for (int j = 1; j < bmp.Width;j++ )
            {
                if( bmp.GetPixel(j,i).R<7  &&  bmp.GetPixel(j-1,i).R>240  && bmp.GetPixel(j,i-1).R>240 ){

                    for (int k = j; k < bmp.Width - 1;k++ )
                    {

                        if ((bmp.GetPixel(k, i).R < 7) && (bmp.GetPixel(k+1, i).R > 240) && (k-j>30)) {
                            int count1 = 0;

                            for (int g = j; g < k;g++ ){
                                if(bmp.GetPixel(g,i).R<7){
                                    count1++;                                    
                                }
                            }//get total width

                         if(count1==k-j){                                 
                             x1 = j;
                             y1 = i;
                             x2 = k;
                         }
                        }
                    }
                         for (int a = i; a < bmp.Height - 1;a++ )
                         {
                             if ((bmp.GetPixel(j, a).R < 7) && (bmp.GetPixel(j, a+1).R > 240) && (a- i > 30)) {

                                 int count2 = 0;

                                 for (int x = i; x < a;x++ )
                                 {
                                     if(bmp.GetPixel(j,x).R<7){                                            
                                         count2++;
                                     }
                                 }


                                 if (count2 == (a - i))
                                 {

                                     y2 = a;
                                 }
                                 else {
                                     Console.WriteLine("check");
                                 }
                             }

                         }

                         if ((bmp.GetPixel(x2, y2).R < 7) && (bmp.GetPixel(x2 + 1, y2).R > 240) && (bmp.GetPixel(x2, y2+1).R > 240))
                         {

                             bool r1 = false;
                             bool r2 = false;
                             int count3 = 0;
                             for (int y = y1; y < y2;y++ )
                             {
                                 if(bmp.GetPixel(x2,y).R<7){
                                     count3++;                                     
                                 }
                             }

                             if (count3== y2 - y1) {
                                 r1 = true;
                             }                                
                             if(r1==true){
                                 int count4=0;
                                 for (int x = x1; x < x2;x++ )
                                 {
                                     if(bmp.GetPixel(x,y1).R<7){
                                         count4++;
                                     }
                                 }

                                 if(count4==x2-x1){
                                     r2 = true;
                                     Console.WriteLine("values :  X1 " + x1 + "   y1 :" + y1 + "   width : " + (x2 - x1) + "  height :  " + (y2 - y1));
                                     Pen pen = new Pen(Color.Red, 2);
                                     pictureBox1.CreateGraphics().DrawRectangle(pen, x1, y1, x2 - x1, y2 - y1);
                                 }                     
                             }
                            }

                }

                    }// initial point loop




                }// first if

2
dsp.stackexchangeへようこそ:)遅い回答であっても、どんな回答でも大歓迎ですが、回答に何らかのコンテキストを提供していただければ幸いです。説明ソースを提供する回答が望ましいです-回答を編集し、コードが何をするのか、それが尋ねられた問題にどのように役立つかについてのいくつかの文章を書いてください、そしてあなたでない場合はソースを引用するかもしれませんか?もしあなたの答えがもっと良くなるなら。また、あなたのIDを編集してください-私は試しましたが、あなたのコードの3分の1を通過した後、私は迷子になりました。
ペネロペ

0

画像が比較的きれいな場合、多くの中断のない明らかな長方​​形があります。Hough変換の代替手段は、輪郭を作成し、4辺の輪郭=長方形になるまで縮小することです。

これを行うためのopencvサンプルがあります


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.