Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.01.2016, 02:52   #1
IvaniuS
Форумчанин
 
Аватар для IvaniuS
 
Регистрация: 16.04.2007
Сообщений: 225
По умолчанию Найти края\углы изображения

Сейчас сразу же вспоминаю блог GunSmoker-a и его задачу про X Y Z, т.к. задача определить фигуру, прошу прощение сразу.
Нужно найти крайние точки изображения: Левая-Верхняя, Правая-Верхняя,
Левая-Нижняя, Правая-Нижняя из них вычислить центр и дальше уже проблем вроде нету.
Код:
Function Corners(hImg: TBitmap; TL,TR,BL,BR: TPoint; ColorToFind, ShadeVariation: Cardinal): Boolean;
Var
  x, y: integer;
  row: PRow;
  img: TBitMap;
Begin
  Result := false;
  img := TBitMap.Create;
  Try
    img.Assign(himg);
    img.PixelFormat := pf24bit;

    For y := 0 To img.Height - 1 Do
    Begin
      Row := img.Scanline[y];
      For x := 0 To img.Width - 1 Do
        With Row[x] Do
        Begin
          //Нужный пиксель
          If IsInShadeVariation(rgbtRed, rgbtGreen, rgbtBlue, ColorToFind, ShadeVariation) Then
          Begin
            //ищем область вот тут переписывал несколько раз - результатом я не доволен
//В теории нужно задать минимально возможные и находить больше, если нашли - менять точку пробовал, задавать 0,0 и вычислять расстояние))
{CurDistance := Distance(XRef - x, YRef - y); //Trunc(Distance(XRef , YRef , x, y));
              If BestDistance > CurDistance Then
              Begin
                Center.X := x;
                Center.Y := y;
                BestDistance := CurDistance;
              End;}

            Result := true;
          End;
        End;
    End;
  Finally
    img.Free;
  End;
End;

              If Abs(BR.Y - TR.Y) > Abs(BL.Y - TL.Y) Then
                Center.Y := TR.Y + Abs(BR.Y - TR.Y) Div 2
              Else
                Center.Y := TL.Y + Abs(BL.Y - TL.Y) Div 2;

              If Abs(TR.X - TL.X) > Abs(BR.X - BL.X) Then
              Begin
                Center.X := TL.X + Abs(TR.X - TL.X) Div 2;
                j := Abs(TR.Y - TL.Y);
              End
              Else
              Begin
                Center.X := BL.X + Abs(BR.X - BL.X) Div 2;
                j := Abs(BR.Y - BL.Y);
              End;
IvaniuS вне форума Ответить с цитированием
Старый 22.01.2016, 11:33   #2
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

IvaniuS
Из вашего вопроса ровным счётом не понятно не чего.

Цитата:
Нужно найти крайние точки изображения: Левая-Верхняя, Правая-Верхняя,
Левая-Нижняя, Правая-Нижняя
А компьютерной графике есть такой термин, как AABB прямоугольник. Предлагаю его позаимствовать. Прямоугольник в который вписана фигура. Чтобы его определить. Нам надо найти верхнюю и нижнюю точки фигуры, а также левую и правую. И пусть его стороны параллельны осям. Нам не важны свойства этого прямоугольника. Главное что он минимальный. Он не самый минимальный, так как если его стороны не будут параллельны осям, то можно сделать меньше. Но на практике этого не нужно.

Зачем нужен ААВВ прямоугольник? Очень просто нам не нужен сложный анализ для поиска углов фигуры. Достаточно найти точки принадлежащее фигуре, к примеру через порог. А после найти точки с минимальным и максимальным индексом. Даже так первое и последнее вхождение.

А центр фигуры с допуском совпадает с центром ААВВ-прямоугольника.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 22.01.2016, 14:23   #3
IvaniuS
Форумчанин
 
Аватар для IvaniuS
 
Регистрация: 16.04.2007
Сообщений: 225
По умолчанию

AABB ищется элементарно - находится минимум по X, Y и максимумы X, Y - по сути это и будет две точки чтобы сделать прямоугольник.
А мне нужно именно точки на самой фигуре найти, Но вроде утро дало новые мысли.
IvaniuS вне форума Ответить с цитированием
Старый 22.01.2016, 15:10   #4
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от IvaniuS Посмотреть сообщение
AABB ищется элементарно - находится минимум по X, Y и максимумы X, Y - по сути это и будет две точки чтобы сделать прямоугольник.
А мне нужно именно точки на самой фигуре найти, Но вроде утро дало новые мысли.
Вам нужен детектор углов?
https://en.wikipedia.org/wiki/Corner_detection
Тогда о каком алгоритме речь? FAST, Harris или другой?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 22.01.2016, 18:19   #5
IvaniuS
Форумчанин
 
Аватар для IvaniuS
 
Регистрация: 16.04.2007
Сообщений: 225
По умолчанию

Спасибо, за полезное чтиво, действительно тема оказалась сложнее чем я думал, пока, если использовать один проход по изображению это выглядит как-то так:
Код:
Function Corners(hImg: TBitmap; Var TL, TR, BL, BR: TPoint; ColorToFind, ShadeVariation: Cardinal): TRect;
Var
  x, y: integer;
  row: PRow;
  img: TBitMap;
  Corn: TRect;
Begin
  img := TBitMap.Create;
  Try
    img.Assign(himg);
    img.PixelFormat := pf24bit;
    //Инициализация максимальными параметрами
    With TL, Corn.TopLeft Do
    Begin
      x := 30;
      y := 30;
    End;
    With TR Do
    Begin
      x := 0;
      y := 30;
    End;
    With BL Do
    Begin
      x := 30;
      y := 0;
    End;
    With BR, Corn.BottomRight Do
    Begin
      x := 0;
      y := 0;
    End;
    //Поиск в ширину, подсчет пикселей
    For y := 0 To img.Height - 1 Do
    Begin
      Row := img.Scanline[y];
      For x := 0 To img.Width - 1 Do
        With Row[x] Do
        Begin
          //Нужный пиксель
          If IsInShadeVariation(rgbtRed, rgbtGreen, rgbtBlue, ColorToFind, ShadeVariation) Then
          Begin
            If X > Corn.BottomRight.X Then
              Corn.BottomRight.X := X;
            If Y > Corn.BottomRight.Y Then
              Corn.BottomRight.Y := Y;
            If X < Corn.TopLeft.X Then
              Corn.TopLeft.X := X;
            If Y < Corn.TopLeft.Y Then
              Corn.TopLeft.Y := Y;

            //ищем область
            If ((X < Tl.X) Or (Y < TL.Y)) Then
            Begin
              TL.X := X;
              TL.Y := Y;
            End;
            If ((X >= TR.X) Or (Y < TR.Y)) Then
            Begin
              TR.X := X;
              TR.Y := Y;
            End;
            If ((X < BL.X) Or (Y >= BL.Y)) Then
            Begin
              BL.X := X;
              BL.Y := Y;
            End;
            If ((X >= BR.X) Or (Y >= BR.Y)) Then
            Begin
              BR.X := X;
              BR.Y := Y;
            End;
          End;
        End;
    End;
    Result := Corn;
  Finally
    img.Free;
  End;
End;
Изображения я предварительно обрезаю максимально и оно достаточно маленькое 30х30 или 50х50.
Вложил примеры, мне нужно четко знать что здесь именно круги, на пример.

Вернувшись к задаче о X Y Z возможно я выбрал не верный подход к решению задачи.
Изображения
Тип файла: bmp figure3.bmp (150 байт, 113 просмотров)
Тип файла: bmp figure2.bmp (358 байт, 122 просмотров)
IvaniuS вне форума Ответить с цитированием
Старый 22.01.2016, 19:34   #6
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Опиши задачу и я возможно смогу предложу вам решение.

Цитата:
Вложил примеры, мне нужно четко знать что здесь именно круги, на пример.
С ходу могу предложить 4 решения.
- Проверка по шаблону.
- Преобразование Хафа. Медленно и не очень устойчиво. Зато скажет точно.
- Моменты. Отношение периметра к площади. Средне по скорости. Устойчиво но через чур, шестигранник от круга врятли отличит. А от квадрата запросто. Стр 94.
- Найти 8 или 9, признаков Хаара. Если есть все 8 или 9 признаков присутствуют, то картинка соответствует кругу.

Но для отличия от многоугольника надо будет что-то думать. Я бы прогнал-бы через FAST Corne Detecor и если меньше 3 углов то круг.

PS. Но это доисторические способы распознавания.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 22.01.2016 в 20:14.
Pavia вне форума Ответить с цитированием
Старый 22.01.2016, 21:21   #7
IvaniuS
Форумчанин
 
Аватар для IvaniuS
 
Регистрация: 16.04.2007
Сообщений: 225
По умолчанию

Да ничего нового придумывать и не нужно, треугольник определяется запросто уже при таком поиске запросто - у него 2 из 4х точек совпадают, квадрат тоже легко определить, а вот круг нахожу только методом исключения, не квадрат и не треугольник, если добавится к нам ромб - будут проблемы)
Проверка по шаблону подходит, я ее использую, но не в данном случае, хотелось бы

Последний раз редактировалось IvaniuS; 22.01.2016 в 21:27.
IvaniuS вне форума Ответить с цитированием
Старый 23.01.2016, 18:19   #8
IvaniuS
Форумчанин
 
Аватар для IvaniuS
 
Регистрация: 16.04.2007
Сообщений: 225
По умолчанию

Спасибо за помощь, оказалось что все на много проще:
Код:
Function Corners(hImg: TBitmap; Var TL, TR, BL, BR: TPoint; ColorToFind, ShadeVariation: integer): TRect;
Var
  x, y: integer;
  row: PRow;
  img: TBitMap;
  Corn: TRect;
  Center: Tpoint;
Begin
  img := TBitMap.Create;
  Try
    img.Assign(himg);
    img.PixelFormat := pf24bit;
    //Инициализация максимальными параметрами
    With Corn.TopLeft Do
    Begin
      x := MaxInt;
      y := MaxInt;
    End;
    With Corn.BottomRight Do
    Begin
      x := 0;
      y := 0;
    End;
    With TL Do
    Begin
      x := MaxInt;
      y := MaxInt;
    End;
    With TR Do
    Begin
      x := 0;
      y := MaxInt;
    End;
    With BL Do
    Begin
      x := MaxInt;
      y := 0;
    End;
    With BR Do
    Begin
      x := 0;
      y := 0;
    End;

    For y := 0 To img.Height - 1 Do
    Begin
      Row := img.Scanline[y];
      For x := 0 To img.Width - 1 Do
        With Row[x] Do
        //Нужный пиксель
          If ((ColorToFind=0)and(ShadeVariation=-1)and(ColorToFind<>RGB(rgbtRed, rgbtGreen, rgbtBlue)))or
            (IsInShadeVariation(rgbtRed, rgbtGreen, rgbtBlue, ColorToFind, ShadeVariation)and(ShadeVariation>-1))  Then
          Begin
            //writeln(Format('%d %d %d',[x,y,RGB(rgbtRed, rgbtGreen, rgbtBlue)]));
            If X > Corn.BottomRight.X Then
            begin
              Corn.BottomRight.X := X;
              TR.X := X;
              TR.Y := Y;
            end;
            If Y > Corn.BottomRight.Y Then
            begin
              Corn.BottomRight.Y := Y;
              BR.X := X;
              BR.Y := Y;
            end;
            If X < Corn.TopLeft.X Then
            begin
              Corn.TopLeft.X := X;
              TL.X := X;
              TL.Y := Y;
            end;
            If Y < Corn.TopLeft.Y Then
            begin
              Corn.TopLeft.Y := Y;
              BL.X := X;
              BL.Y := Y;
            end;
          End;
    End;

    Result := Corn;
  Finally
    img.Free;
  End;
End;

{
    Center.X := corn.Left + corn.Right Div 2;
    Center.Y := corn.Top + corn.Bottom Div 2;
    }
Далее просто обрезаю и с помощью StretchBlt Привожу к вот такому результату, который легко обрабатывается, проверкой углов + середины краев:
Изображения
Тип файла: bmp 1.bmp (182 байт, 115 просмотров)
Тип файла: bmp 14.bmp (182 байт, 122 просмотров)
Тип файла: bmp 15.bmp (182 байт, 120 просмотров)
Тип файла: bmp 16.bmp (182 байт, 118 просмотров)
IvaniuS вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Обнаружить края PNG изображения с прозрачным фоном FumarMata JavaScript, Ajax 2 09.01.2014 16:55
круглые края div subbota HTML и CSS 2 10.07.2010 18:35
прямоугольник (закругленные края) TaTT DoGG Общие вопросы .NET 2 14.05.2010 23:58
Найти внутренние углы треугольника (Pascal) street_spirit Помощь студентам 4 02.03.2010 17:25
Треугольник задан длинами своих сторон: a, b, c. Найти углы треугольника. задача на С++ Wia Помощь студентам 6 13.12.2008 16:13