Як виявити краї та прямокутники


14

Я намагаюся виявити прямокутники в зображеннях. Фон зображень одноколірний (більшість часу). Я спробував два способи отримати бінарне зображення (1 = фон, 0 = ребра), щоб згодом зробити трансформацію Хофа ...

  1. Фільтр Собеля або Кенні

  2. Гладке зображення A, створення відмінності зображення A - гаус, створення бінарного зображення з порогом (Створіть гістограму, найвищий бін має бути фоном ...)

В результаті виходить двійкове зображення з ребрами. Я зараз не знаю, який метод працює краще для різних зображень. Будь-які ідеї?


1
Що ви маєте на увазі під "працює краще"? Кенні дуже популярний у подібних речах, але це залежить від того, що ви намагаєтеся зробити, коли у вас є краї. Чого саме ви намагаєтесь досягти?
Пол Р

4
Будь ласка, не відмовляйтесь від голосування нових користувачів за їх найперше запитання щодо спільноти!

1
Ця тема може бути корисною
Jim Clay

Детектори обріз
пенелопа

"Результат - це двійкове зображення з ребрами. Я зараз не знаю, який метод працює краще для різних зображень. Будь-які ідеї?" Можливо, вам знадобиться тест-тест для пошуку зображень, щоб знайти відповідь або сфотографуватись у середовищі, на яку, можливо, ви порахуєте. Якщо в цій галузі існують найкращі алгоритми, чому ми повинні так багато вчитися? Я вважаю, що будь-які алгоритми мають перевагу іноді, в сенсі ймовірності.

Відповіді:


10

Я колись написав заявку на виявлення прямокутника. Він використовував детектування країв Собеля та лінійну трансформацію Хаффа.

Замість того, щоб шукати поодинокі піки у зображенні (лініях) Хоф, програма шукала 4 піки з відстані 90 градусів між ними.

Для кожного стовпця на зображенні Хауфа (відповідного деякому куту) три інші колонки шукали локальні максимуми. Коли в кожному з чотирьох стовпців був виявлений насичений пік, прямокутник виявлено.

Програма побудувала прямокутник і здійснила додаткові перевірки на відповідність кольорів усередині прямокутника і поза ним, щоб розрізнити помилкові позитиви. Програма була для виявлення розміщення паперу у відсканованих аркушах паперу.


5

Ви можете виявити, що кращий детектор краю Лаплаціа Гаусса - кращий вибір. Він повинен надавати вам закриті контури частіше, ніж детектор краю Canny. Я вважаю, що саме цього ви хочете, оскільки ваш наступний крок - застосувати трансформацію Хоф.


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 :) Будь-яка відповідь, навіть пізня, дуже вітається, але було б добре, якби ви надали якийсь контекст зі своєю відповіддю. Відповіді, які надають пояснення та джерела, є кращими - чи можете ви відредагувати свою відповідь, написати кілька речень того, що робить код, і як це допоможе у питанні заданої проблеми, а може, наведіть джерело, якщо це не ви? Якби зробити вашу відповідь набагато кращою. Крім того, відредагуйте свій ідентифікатор, будь ласка - я спробував, але я загубився, переглянувши третину вашого коду.
пенелопа

0

Якщо ваше зображення відносно чисте, у вас очевидні прямокутники без великої кількості розривів, альтернативою перетворенню Хаффа є створення контурів і зменшення їх до тих пір, поки вони не сформують 4-х сторінний контур = ваш прямокутник.

Для цього є зразки opencv


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.