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

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

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

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 17.12.2021, 13:58   #1
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 627
По умолчанию Сравнение изображений

Какой самый оптимальный метод сравнения изображений?

Задача такая:
Есть два изображения. При этом низ одного дублирует верх другого. То есть, если небольшой "перехлест". И вот нужно найти количество строк этого перехлеста
Kronos913 вне форума Ответить с цитированием
Старый 17.12.2021, 16:15   #2
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,551
По умолчанию

Покажите на примере, что надо сделать.
Arigato вне форума Ответить с цитированием
Старый 17.12.2021, 16:51   #3
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 627
По умолчанию

Пример... Ну допустим такой: вы сделали скриншот переписки в телеграме. Потом пролистали переписку вниз и сделали еще один скриншот. Так что получился небольшой перехлест
И теперь надо склеить эти 2 скриншота в один
Kronos913 вне форума Ответить с цитированием
Старый 17.12.2021, 17:19   #4
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Сжимаем изображение в 32 раза. *) Заменяем цвета из 24 бит в 8 бит.
Затем применяем быстрый алгоритм поиска длины наибольшей подпоследовательности. См линк:
http://algolist.ru/search/lcs/simple_lcs.php

И из этой матрицы отбираем наибольшую длину с края.
Если не нашли подрезаем наше изображение на 4 линий и повторяем. И так 32/4=8 раз.
*) Для учета вращения после сжатия надо сделать перебор с небольшими отклонениями.
Далее вырезаем перекрывающиеся участки. выделяем углы и ищим матрицу перехода. Путем метода наименьших квадратов.

Либо по тому туторилу что я довел в соседней теме.
https://disk.yandex.ru/i/Xir2HjHwJAds9A
Либо как приведено в статье.
https://disk.yandex.ru/i/4G0JJRAFeiNnVQ

Но это так с ходу придумал. А вообще советую поискать алгоритм склеивания изображения и создания панорамных снимков.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 17.12.2021, 17:21   #5
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Для скриншотов алгоритм можно упростить.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 17.12.2021, 17:31   #6
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Для скриншотов просто цикл по строчка и по столбцам из второго цикла break при первом различие. Будет почти линейный алгоритм.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 17.12.2021, 18:40   #7
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,551
По умолчанию

Цитата:
Сообщение от Pavia Посмотреть сообщение
Для скриншотов просто цикл по строчка и по столбцам из второго цикла break при первом различие.
Набросал пример, единственное условие, ширина изображений должна совпадать и не должно быть горизонтальных сдвигов.

Код:
const
  PixelCountMax = 32768;

type
  PRGBArray = ^TRGBArray;
  TRGBArray = array[0..PixelCountMax-1] of TRGBTriple;

function BmpCross(bmp1, bmp2: TBitmap): Integer;
var
  x, y, h, LineSize: Integer;
  Line1, Line2: PRGBArray;
  Equal: boolean;
begin
  Result := 0;
  if bmp1.Height > bmp2.Height then h := bmp2.Height else h := bmp1.Height;
  LineSize := bmp1.Width * SizeOf(TRGBTriple);
  repeat
    Inc(Result);
    Equal := True;
    for y := 0 to Result - 1 do begin
      Line1 := bmp1.ScanLine[bmp1.Height-Result+y];
      Line2 := bmp2.ScanLine[y];
      if not CompareMem(Line1, Line2, LineSize) then begin
        Equal := False;
        Break;
      end;
    end;
  until (Result >= h) or Equal;
  if not Equal then Result := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  bmp1, bmp2: TBitmap;
  Cross: Integer;
begin
  bmp1 := TBitmap.Create;
  bmp1.LoadFromFile('1.bmp'); // верхнее изображение
  bmp2 := TBitmap.Create;
  bmp2.LoadFromFile('2.bmp'); // нижнее изображение
  if bmp1.Width = bmp2.Width then begin
    if (bmp1.PixelFormat = pf24bit) and (bmp2.PixelFormat = pf24bit) then begin
      Cross := BmpCross(bmp1, bmp2);
      bmp1.Height := bmp1.Height + bmp2.Height - Cross;
      bmp1.Canvas.Draw(0, bmp1.Height - bmp2.Height, bmp2);
      bmp1.SaveToFile('3.bmp');
      ShowMessage('Совпадающих строк: ' + IntToStr(Cross));
    end else ShowMessage('Неверный формат BMP');
  end else ShowMessage('Ширина изображений не совпадает');
  bmp1.Free;
  bmp2.Free;
end;
Arigato вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сравнение изображений. stlcrash Общие вопросы Delphi 66 02.06.2016 13:37
Сравнение изображений. C# Serg94 Помощь студентам 1 27.11.2012 19:43
Сравнение 2 изображений wlords Помощь студентам 0 23.11.2010 20:47
Сравнение изображений AmbaQ Общие вопросы Delphi 1 07.08.2010 19:20
Сравнение изображений DeDoK Общие вопросы Delphi 1 11.10.2008 21:16