Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 05.06.2018, 17:38
-=#PupaJr#=- -=#PupaJr#=- вне форума
Новичок
 
Регистрация: 17.08.2010
Сообщения: 69
Репутация: 518
Вопрос Детектор границ Канни

Добрый день. Не могу понять в чём ошибка реализации детектора границ Кенни на Delphi6.
Во вложении исходные изображения, углы градиента, градиент и границы. Собель работает вроде верно - очень похоже на то что есть в инете по картинкам, определение углов тоже похоже на правду - стороны света определяются верно на простых перпендикулярных линиях 0-180 градусов с кратностью 45. Сам детектор построен по теории описанной везде - берём точку с углом и градиентом, сравниваем её с соседними точками у которых тот же угол (если 90 то идем вверх и вниз, если 45 то по диагонали проверяем точки), если угол тот же то проверяем градиент на больше/меньше - если у исследуемой точки больше чем у соседних то есть граница и на выходном битмапе ставим белую точку в координату исследуемой.
Куски кода:
код собеля
Код:
  FOR Y := BM1.Height-2 DOWNTO 2 DO         // перебор матрицы c запасом по краям на 1 пиксель
    BEGIN
      i1 := BM1.ScanLine[Y-1];               // строка выше
      i0 := BM1.ScanLine[Y];                 // исследуемая
      i2 := BM1.ScanLine[Y+1];               // ниже
      d  := sobel.ScanLine[Y];                // результат
      sba:= sobang.ScanLine[Y];               // массив углов
      i  := 3;                          // 3 байта на цвет
      FOR X := 2 TO BM1.Width-2 DO
        begin
          mgx:=    -p1*i1^[i-3]-p2*i0^[i-3]-p1*i2^[i-3];
          mgx:=mgx +p1*i1^[i+3]+p2*i0^[i+3]+p1*i2^[i+3];
 
          mgy:=    -p1*i1^[i-3]-p2*i1^[i]-p1*i1^[i+3];
          mgy:=mgy +p1*i2^[i-3]+p2*i2^[i]+p1*i2^[i+3];
 
 
       ang:=0;
       if mgx=0 then mgx:=0.00001;
       if (mgx=0)and(mgy=0) then ang:=0;
       if mgx<>0 then ang:=trunc(((180/3.1415926)*(ArcTan2(mgy,mgx))));
 
 //      if mgy=0 then mgy:=0.00001;
 //      if (mgy=0)and(mgx=0) then ang:=0;
  //     if mgy<>0 then ang:=trunc(((180/3.1415926)*(ArcTan2(mgx,mgy))));
 
          mgx:=mgx*mgx;
          mgy:=mgy*mgy;
          grad:=trunc(sqrt(mgx+mgy));         // вычисляем градиент
 
       if grad<angmin then angmin:=grad;
       if grad>angmax then angmax:=grad;
       g:=grad;
 
       if grad>255 then g:=255;
         GistArray[g]:=GistArray[g]+g;
          if GistArray[g]>Gmax then
           begin
            Gmax:=GistArray[g]; // ищем максимум одинаковых данных
            Nmax:=g;            // запомнили число
           end;
 
       if CheckBox6.Checked then                // если надо порог считать, иначе без порога заносим в картинку
         if (grad > porog) then grad:= 255
            else grad:= 0;
 
           if ((ang<=22)and(ang>=0))or ((ang>=-22)and(ang<=0))then iang:=30   // определяем все углы и им даём цвет
            else if (ang>22)and(ang<=67) then iang:=60
             else if (ang>67)and(ang<=112) then iang:=90
              else if (ang>112)and(ang<=158) then iang:=120
               else if (ang<=180)and(ang>158)or((ang>=-180)and(ang<=-158)) then iang:=150
                else if (ang>=-158)and(ang<-112) then iang:=180
                 else if (ang>=-112)and(ang<-67) then iang:=210
                  else if (ang>=-67)and(ang<=-22) then iang:=240;
 
          d^[i] := grad;
          sba^[i]:=iang;
          Inc(i);
          d^[i] := grad;
          sba^[i]:=iang;
          Inc(i);
          d^[i] := grad;
          sba^[i]:=iang;
          Inc(i);
        end;
    END;

код канни
Код:
	

   FOR Y := sobel.Height-2 DOWNTO 2 DO         // перебор матрицы c запасом по краям на 1 пиксель
    BEGIN
      g2 := sobel.ScanLine[Y-1];
      g1 := sobel.ScanLine[Y];         // данные амплитуд градиента
      g0 := sobel.ScanLine[Y+1];
 
      a2 := sobang.ScanLine[Y-1];
      a1 := sobang.ScanLine[Y];         // данные углов
      a0 := sobang.ScanLine[Y+1];
 
      e0 := Edgeout.ScanLine[Y];        // приёмное изображение
 
      i  := 3;                          // 3 байта на цвет
      FOR X := 2 TO sobel.Width-2 DO
        begin
          e0^[i]:=0;    // очищаем
          e0^[i+1]:=0;
          e0^[i+2]:=0;
          mgg:= g1^[i];    // взяли данные амплитуды
          mga:= a1^[i];    // взяли данные угла
           if mga=30 then         //(ang<=45)and(ang>=0)       // определяем все углы и им даём цвет
             begin
              mgg1:=g1^[i+3];   // направление --> -22+22    =0
              mga1:=a1^[i+3];
              if mga=mga1 then  // если углы направления градиента совпали то выбираем наибольшее значение градиента
               if (mgg>mgg1)and(mgg>porog) then begin e0^[i]:=255;e0^[i+1]:=255;e0^[i+2]:=255; end  // занулили слабый окончательно
                 else begin e0^[i]:=0;e0^[i+1]:=0;e0^[i+2]:=0;end
               else begin e0^[i]:=255;e0^[i+1]:=255;e0^[i+2]:=255; end;
            end // 30
            else if mga=60 then    //(ang>22)and(ang<=67) =+45
              begin
               mgg1:=g0^[i+3];   // направление /
               mga1:=a0^[i+3];
               if mga=mga1 then  // если углы направления градиента совпали то выбираем наибольшее значение градиента
                if (mgg>mgg1)and(mgg>porog) then begin e0^[i]:=255;e0^[i+1]:=255;e0^[i+2]:=255;  end  // занулили слабый окончательно
                 else begin e0^[i+0]:=0;e0^[i+1]:=0;e0^[i+2]:=0; end
                else begin e0^[i]:=255;e0^[i+1]:=255;e0^[i+2]:=255; end;
              end
             else if  mga=90 then    //(ang>67)and(ang<=115)  =+90
               begin
                mgg1:=g0^[i];   // направление |
                mga1:=a0^[i];
                if mga=mga1 then  // если углы направления градиента совпали то выбираем наибольшее значение градиента
                 if(mgg>mgg1)and(mgg>porog) then begin e0^[i]:=255;e0^[i+1]:=255;e0^[i+2]:=255;  end  // занулили слабый окончательно
                  else begin e0^[i]:=0;e0^[i+1]:=0;e0^[i+2]:=0; end
                 else begin e0^[i]:=255;e0^[i+1]:=255;e0^[i+2]:=255; end;
               end
              else if  mga=120 then  //(ang>115)and(ang<=162)  =+135
                begin
                 mgg1:=g0^[i-3];   // направление \
                 mga1:=a0^[i-3];
                 if mga=mga1 then  // если углы направления градиента совпали то выбираем наибольшее значение градиента
                  if (mgg>mgg1)and(mgg>porog) then begin e0^[i]:=255;e0^[i+1]:=255;e0^[i+2]:=255;  end  // занулили слабый окончательно
                   else begin e0^[i]:=0;e0^[i+1]:=0;e0^[i+2]:=0; end
                   else begin e0^[i]:=255;e0^[i+1]:=255;e0^[i+2]:=255; end;
                end
Может что-то ещё надо? пробывал разбираться с двойным порогом - но толкового описания ненашёл как его реализовать... Вроде как должен убрать шум и двойные границы...
Хелп.
Могу конечно весть проект положить или екзешник, чтобы не собирать его...
Разными пробами кода удавалось получить меньше шума и кое-что похожее на окружности но они были рваные - незамкнутые, в тругих вариантах кода получалось получить боле-менее результат но на переходах углов всегда дырки в контуре..
В картинках - картинка исходник, собель, углы, канни
Изображения
Тип файла: jpg canny2.JPG (16.9 Кбайт, 4 просмотров)
Тип файла: jpg canny3.JPG (42.5 Кбайт, 4 просмотров)
Тип файла: jpg canny4.jpg (54.6 Кбайт, 3 просмотров)
Тип файла: jpg circle-recoge.jpg (34.4 Кбайт, 3 просмотров)
Тип файла: jpg canny1.JPG (91.9 Кбайт, 3 просмотров)
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:41.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter