วิธีการตรวจจับขอบและสี่เหลี่ยม


14

ฉันพยายามตรวจจับสี่เหลี่ยมในภาพ พื้นหลังของภาพเป็นสีเดียว (ส่วนใหญ่) ฉันลองสองวิธีเพื่อให้ได้ภาพไบนารี (1 = พื้นหลัง, 0 = ขอบ), เพื่อทำการแปลงแบบ Hough ในภายหลัง ...

  1. Sobel หรือ Canny Filter

  2. ภาพเรียบ A, สร้างภาพที่แตกต่าง A - เกาส์, สร้างภาพไบนารีที่มีเกณฑ์ (สร้างฮิสโตแกรม, bin สูงสุดควรเป็นพื้นหลัง ... )

ผลที่ได้คือภาพไบนารีที่มีขอบ ฉันไม่ได้จริงๆตอนนี้วิธีการใดที่ทำงานได้ดีกว่าสำหรับภาพที่แตกต่างหลากหลาย ความคิดใด ๆ


1
คุณหมายถึงอะไรโดย "ทำงานได้ดีขึ้น"? Canny ได้รับความนิยมอย่างมากสำหรับสิ่งนี้ แต่มันขึ้นอยู่กับสิ่งที่คุณพยายามทำเมื่อคุณมีขอบ คุณพยายามทำอะไรให้สำเร็จ
พอล R

4
โปรดอย่าโหวตให้ผู้ใช้ใหม่สำหรับคำถามแรก ๆ ของพวกเขาในชุมชน!

1
หัวข้อนี้อาจเป็นประโยชน์
Jim Clay

เครื่องตรวจจับขอบอธิบาย: dsp.stackexchange.com/q/74/1273
penelope

"ผลที่ได้คือภาพไบนารีที่มีขอบฉันไม่ได้จริงๆตอนนี้วิธีการใดที่ทำงานได้ดีกว่าสำหรับภาพที่แตกต่างหลากหลายความคิดใด ๆ ?" บางทีคุณอาจต้องการ lib ทดสอบรูปภาพเพื่อค้นหาคำตอบหรือถ่ายภาพในสภาพแวดล้อมที่คุณอาจนับ หากมีอัลกอริธึมที่ดีที่สุดในฟิลด์นี้ทำไมเราควรเรียนรู้สิ่งอื่น ๆ มากมายฉันเชื่อว่าอัลกอริทึมใด ๆ มีข้อดีในบางครั้ง

คำตอบ:


10

ฉันเคยเขียนแอพพลิเคชั่นสำหรับการตรวจจับสี่เหลี่ยมผืนผ้า ใช้การตรวจจับขอบ Sobel และการแปลง Hough line

แทนที่จะมองหาพีคเดียวในภาพ Hough (เส้น) โปรแกรมค้นหา 4 พีคส์ด้วยระยะทาง 90 องศาระหว่างนั้น

สำหรับแต่ละคอลัมน์ในภาพ Hough (ตรงกับบางมุม) คอลัมน์อื่น ๆ สามคอลัมน์ถูกค้นหาเพื่อหาค่าสูงสุดในท้องถิ่น เมื่อพบจุดสูงสุด satifactory ในแต่ละคอลัมน์ทั้งสี่คอลัมน์จะถูกตรวจพบ

โปรแกรมสร้างสี่เหลี่ยมและทำการตรวจสอบเพิ่มเติมสำหรับความสอดคล้องของสีทั้งภายในและภายนอกสี่เหลี่ยมเพื่อแยกแยะผลบวกปลอม โปรแกรมนี้ใช้สำหรับตรวจจับการวางกระดาษในแผ่นกระดาษที่สแกน


5

คุณอาจพบว่า Laplacian of Gaussian edge detector เป็นตัวเลือกที่ดีกว่า ควรให้รูปทรงปิดคุณบ่อยกว่าตัวตรวจจับขอบ Canny ฉันเชื่อว่านั่นคือสิ่งที่คุณต้องการตั้งแต่ขั้นตอนต่อไปของคุณคือการใช้การแปลง Hough


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 :) คำตอบใด ๆ แม้จะมาช้าก็ยินดีต้อนรับมาก แต่มันจะดีถ้าคุณให้บริบทกับคำตอบของคุณ คำตอบที่ให้คำอธิบายและแหล่งที่มาเป็นที่ต้องการ - คุณสามารถแก้ไขคำตอบเขียนสองสามประโยคว่าโค้ดทำอะไรได้บ้างและจะช่วยอย่างไรกับปัญหาที่ถามและอาจอ้างอิงแหล่งที่มาหากไม่ใช่คุณ หากจะทำให้คำตอบของคุณดีขึ้นมาก โปรดแก้ไขข้อมูลประจำตัวของคุณด้วย - ฉันได้ลองแล้ว แต่ฉันหลงทางหลังจากอ่านรหัสหนึ่งในสามของคุณแล้ว
Penelope

0

หากภาพของคุณค่อนข้างสะอาดคุณมีรูปสี่เหลี่ยมผืนผ้าที่ชัดเจนโดยไม่มีการแบ่งจำนวนมากทางเลือกในการแปลง Hough คือการสร้างรูปทรงและลดขนาดลงจนกว่าพวกเขาจะได้รูปแบบ 4 ด้าน = รูปร่างของคุณ

มีตัวอย่าง opencv ให้ทำเช่นนี้


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.