Как определить края и прямоугольники

14

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

  1. Собел или Канни фильтр

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

Результатом является двоичное изображение с краями. Я действительно не знаю, какой метод лучше работает для различных изображений. Есть идеи?

Мартин Томпсон
источник
1
Что вы подразумеваете под «лучше работает»? Canny очень популярен для такого рода вещей, но это зависит от того, что вы пытаетесь сделать, когда у вас есть преимущества. Чего именно вы пытаетесь достичь?
Пол Р
4
Пожалуйста, не голосуйте против новых пользователей за самый первый вопрос в сообществе!
1
Эта ветка может быть полезной
Джим Клэй,
Детекторы Пограничные объяснил: dsp.stackexchange.com/q/74/1273
Пенелопу
«В результате получается бинарное изображение с краями. Я не знаю, какой метод лучше работает для множества различных изображений. Есть идеи?» Возможно, вам понадобится тестовая библиотека изображений, чтобы найти ответ, или сделайте несколько снимков в среде, которую вы, возможно, считаете. Если существуют лучшие алгоритмы в этой области, почему мы должны так много учить других? Я считаю, что любые алгоритмы иногда имеют свои преимущества в смысле вероятности.

Ответы:

10

Однажды я написал приложение для обнаружения прямоугольников. Он использовал определение краев Собеля и линейное преобразование Хафа.

Вместо поиска одиночных пиков в изображении Хафа (линии), программа искала 4 пика с расстоянием между ними 90 градусов.

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

Программа построила прямоугольник и провела дополнительные проверки согласованности цвета внутри и снаружи прямоугольника, чтобы различить ложные срабатывания. Программа была для обнаружения размещения бумаги в отсканированных листах бумаги.

ЛИБОР
источник
5

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

chippies
источник
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

Мартин Беккет
источник