Оптимизация сравнения двух изображений

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Re: Оптимизация сравнения двух изображений

Сообщение Лекс Айрин » 20.04.2019 05:26:11

Alex2013, а ты вообще осознаешь, что такое raw? Я лично вот удивлен, что его можно использовать для любого файла. Хотя, скорее всего, это не оригинальный raw, а просто представление картинки в виде байтового массива. Изначально это набор данных во внутреннем представлении цифрового фотоаппарата. Поэтому люди и стараются не использовать его. Ибо неизвестно что будет если там что-то тронешь.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Оптимизация сравнения двух изображений

Сообщение Alex2013 » 20.04.2019 11:29:44

Лекс Айрин писал(а):Alex2013, а ты вообще осознаешь, что такое raw? Я лично вот удивлен, что его можно использовать для любого файла. Хотя, скорее всего, это не оригинальный raw, а просто представление картинки в виде байтового массива. Изначально это набор данных во внутреннем представлении цифрового фотоаппарата. Поэтому люди и стараются не использовать его. Ибо неизвестно что будет если там что-то тронешь.

Разумеется к raw-формату цифровых фотокамер TBitmap.RawImage не имеет никакого отношения . Но фокус в том что именно в доступе к "представлению картинки в виде битового массива" довольно часто нуждаются все программисты. Очень многое просто по другому не сделаешь (помню свои первые изощрения с графикой в лазарусе так я тогда придумал ничего лучшего чем переписать изображение в массив ( через Canvas.Pixels) обработать и записать обратно (правда уже не по точкам, а линиями (как в PCX-се)) но всё равно получалось гораздо быстрее потому, что существуют оптимизированные алгоритмы рассчитанные именно под обработку битового массива ) Глянь как нибудь на эффекты с ZX-спектрума и ужаснись :arrow: https://www.youtube.com/watch?v=Jv4-80f7kt4 https://www.youtube.com/watch?v=q4JY05hcU5E https://www.youtube.com/watch?v=NVrZuSYDVVg&t=114s :wink:
Последний раз редактировалось Alex2013 24.04.2019 10:08:38, всего редактировалось 1 раз.
Alex2013
долгожитель
 
Сообщения: 2924
Зарегистрирован: 03.04.2013 11:59:44

Re: Оптимизация сравнения двух изображений

Сообщение Лекс Айрин » 20.04.2019 12:34:57

Alex2013, любое представление картинки это байтовый массив.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Оптимизация сравнения двух изображений

Сообщение Alex2013 » 20.04.2019 14:20:39

В принципе да но только стандартный доступ туда через "село Тужиловка Липецкой области ".... :wink: и ты не понял в чем дело ... Суть возможности обращается к изображению как куску памяти а не как двухмерной матрице точек... (Причем ладно бы через обычный массив с динамической метрикой так не же .... в Canvas.Pixels обращение идет через GUI-шные SetPixel/GetPixel угу угу к куску своей же памяти (кстати "аппаратно привязанные" битмапы и битмапы Лазаруса это почти "совершенно разные сущности" например чтобы что-то нарисовать на битмапе через OpenGl нужно провести для TBimap "капитальный ремонт" тоже касается и якобы "стандартного" битмапа для захвата кадров с вебкамеры ) )

Но я отвлекся !

Суть использования "Битового массива "( заметь не Байтового ) в возможности проводить массированное изменение/чтение/сравнение почти что "одной командой" (и не надо софистику про "циклы в внутри" разводить - разница есть ! )+ есть хитроумные БИТОВЫЕ алгоритмы заточенные под конкретный "формат пискля" + блочные операции и быстрое построение примитивов и т.д. (Я уж молчу про прямое использование всяческих 3Dnow/mmx/Sse/Avc.. да и компилятору иногда "проще разобраться" ... )

ЗЫ
Еще одна демка...
https://www.youtube.com/watch?v=kN9kkbMDgiw
Обрати внимание на бегущею строку ... (И попробуй сделать такую же через Canvas.Pixels на современном ПК ... :idea: )
https://youtu.be/kN9kkbMDgiw?t=149
Alex2013
долгожитель
 
Сообщения: 2924
Зарегистрирован: 03.04.2013 11:59:44

Re: Оптимизация сравнения двух изображений

Сообщение Лекс Айрин » 20.04.2019 16:21:59

Alex2013, отдельных битовых массивов, по крайней мере в паскале, не бывает. При желании можно сделать групповое сравнение, выставление о дельного бита в 0 или 1, но это будет геморрой чисто для попробовать.
Ладно, допустим, что мы пришли к тому, что это все норма и побитовое сравнение круто, но! Отрежь по одной стороне полоску шириной в один пиксель и это будут уже совсем разные картинки. То есть, даже попиксельное сравнение ещё не даёт гарантии сходства, а уж побитовое... Хотя уже есть программы поиска дубликатов, которые позволяют находить даже довольно сильно изменённые копии.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Оптимизация сравнения двух изображений

Сообщение Alex2013 » 20.04.2019 18:39:51

Я про "Фому а мне про Ерёму" ... :D Причем тут паскаль ! Даже в дельфи и библиотеке Кол прямой доступ к данным битмапа устроен легче чем LCL. Но опять-же не это не суть как важно потому что доступ все-же есть ... Но глядя на простыни кода применением Canvas.Pixels даже только на этом форуме становится как минимум СТРАННО что многие годы никто почему-то об этом не подозревал . :idea:

Что до сравнения то разумеется это не "распознавание образов " ... Я тут просто примитивную утилитку для отслеживания появления "вредного" транспаранта в "Портале смешанной реальности" вчера за час накидал...
Изображение

"Auto Win-Y" как следует из названия на требование нажать Win-Y включается "тупой робот" и эмулирует нажатие ... Прикол в том что появляется транспарант всегда в по одним и тем-же координатам так что захватываю скрин вытаскиваю верхнюю полоску записываю образец, запускаю таймер и... а дальше был небольшой но симпатичный облом... нет в стандартных средствах возможности сравнить два битмапа даже "на полное равенство" .. Пришлось изобретать очередной велосипед
Кстати вот архив (Бинарник (Для Win64 )+ исходники ).
:arrow: AutoWinY0_002.7z :idea:(Перезалил на ЯД)
(Может еще кому-то подобную "затычку" понадобится писать а тут уже готовый шаблон лежит ) :idea:
Alex2013
долгожитель
 
Сообщения: 2924
Зарегистрирован: 03.04.2013 11:59:44

Re: Оптимизация сравнения двух изображений

Сообщение Лекс Айрин » 20.04.2019 19:36:19

Alex2013, а как ты думаешь, почему такие простыни? Потому что Лазарус кроссплатформенное средство разработки. И не только под виндой или линуксом, но и под десятком других, более экзотических осей. А значит, нужно иметь какой-то базис, вокруг которого приходится плясать. Возможно, что сделано это не оптимально, но тут уж как получилось. Как-то я попытался выкинуть из одного модуля ненужные мне строки... И не смог, слишком плотно все связано, обязательно где-то, но вылезет ошибка. Чтобы что-то упростить надо вначале распотрошить схему всей lcl, плотно покурить... и решить какие операционки не нужны.
Дельфи же это решение только для винды, поэтому он проще.
А насчёт твоей смешанной реальности... Я же уже говорил, что это пародия на нормальную альтернативную реальность. Ты ещё не раз столкнется с подобными обломами. Да и с сомнительными решениями типа окна прямо перед глазами тоже. Назвался гиком терпи. Вообще, подобные окна должны быть в отдельном слое, который можно смахнуть в сторону (скрыть), чтобы не мешался, но кому то просто зудит все сделать через то место, откуда у них руки торчат. И это далеко не плечи.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Оптимизация сравнения двух изображений

Сообщение Alex2013 » 20.04.2019 23:11:22

1 "Крос Лазруса" к психологической загадке почему все долгое время пользовались ИСКЛЮЧИТЕЛЬНО Canvas.Pixels с редкими вкраплениям (кстати СУГУБО виндового) ScanLine отношения не имеет . (TBitmap.RawImage вполне "кроссплатформенное средство" и я действительно допускаю "сложность" с BeginUpdate связанна именно с этим )

2 Я действительно не понимаю, что мешало сделать альтернативную структур Canvas.FastPixels работающею чрез RawImage тупо забив в функции чтения/ записи все существующие форматы от 1-го до 32 бит . Или альтернативный LCLScanLine .
(Ну пусть бы работало не "везде" (кстати "везде" Canvas.Pixels и так не работает) а в оговоренных случаях - но этих оговоренных случаев большая часть ) Да "для тех кто познал силу RawImage" все это уж не важно есть случаи когда использование RawImage тоже изрядно избыточно.
3 Про смешанную реальности вообще и WMR в частности в этой теме я вообще не заикался есть мелкая нужда в утилите реагирующей на транспарант.... Но все это к "проблеме сравнения двух битмапов на тождество" не имеет ... а "успешно преодоленный облом" 8) был именно там .
Зы
И кстати никакого "окна пред глазами" нет (конкретно этот транспарант на обычном десктопе вылезает) .
Зы Зы
Пока писал эту "гуманитарную помощь глодающим" "сам все понял" :mrgreen: : Утилиту определенно нужно доработать...
1 Сделать "режим инверсии" то есть эмулировать нажатие Win-Y если транспарант нет ( нужно продумать алгоритм работы в РИ бо не так уж он прост ... )
2 Добавить "переназначение Win-Y"
Alex2013
долгожитель
 
Сообщения: 2924
Зарегистрирован: 03.04.2013 11:59:44

Re: Оптимизация сравнения двух изображений

Сообщение Лекс Айрин » 21.04.2019 00:26:04

Блокировка нужна потому что работа идёт с битовым представлением, которое очень легко повредить, если картинка внезапно изменится. Когда это делается с помощью натягиваемой поверх всего этого пиксельной таблице, это совсем другое дело. Скорее всего, блокировка там тоже есть.
Конечно, проверить можно только посмотрев реализацию, но, если честно, лень.

Добавлено спустя 9 минут 49 секунд:
Кстати, что-то подсказывает, что ты не правильно подошёл к проблеме. Тебе надо, если дело на обычном десктопе, перебирать список открытых окон и проверять их заголовки или имена процессов. Найдя нужное просто послать ему соответствующее сообщение. Получится мелкая утилитка.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Оптимизация сравнения двух изображений

Сообщение Alex2013 » 21.04.2019 01:51:13

1 Блокировка не проблема ни в дельфи ни в Кол+FPC ее как-бы нет но все работает. Как минимум ScanLine (в отличии от LCL аналога ) точно без заметной блокировки работает. "Пиксельная таблица всюду реализована практически одинаково через дисплейный контекст и медленный GUI-шный SetPixel /Get Pixel (Возможно в этом есть какой-то "высший смысл" но что мешает сделать стандартную альтернативу непонятно ... :roll: )


По утилите и WMR : Там нет окна ... в этом то и прикол ... процесс портала выводит транспарант на уровне ниже обычного GUI (возможно через какую-то специальное API для низкоуровневых сервисов ) Кроме того ты просто не вдел количество процессов весящих в Вин-10 при использовании WMR ... Хотя разумеется самым разумным было бы просто поискать подходящий ключ в реестре или в ресурсах "Портала-WMR" или покопать WMR-апи .
Последний раз редактировалось Alex2013 26.04.2019 06:30:50, всего редактировалось 2 раз(а).
Alex2013
долгожитель
 
Сообщения: 2924
Зарегистрирован: 03.04.2013 11:59:44

Re: Оптимизация сравнения двух изображений

Сообщение olegy123 » 21.04.2019 08:09:43

Лекс Айрин писал(а):Блокировка нужна потому что работа идёт с битовым представлением

скорее системе говорится, что данные в памяти меняются, они заблокированные. Такой подход применяется при многопоточности, когда один поток читает, а другой записывает.

Alex2013 писал(а):Возможно в этом высший есть какой-то "высший смысл" но что мешает сделать стандартную альтернативу непонятно

скорее проще, есть читение/записи пикселя - люди используют, про всякий accelerate еще не знают. Использование accelerate требует хороших аппаратных знаний, кто их использует уже не заботит вопрос о наложении одной картинки на другую и как правило уже не уровня fpc вопрос.
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Оптимизация сравнения двух изображений

Сообщение Лекс Айрин » 21.04.2019 09:21:50

Alex2013, ниже уровня gui есть только работа с графикой напрямую. Система же всегда использует созданный ею же механизм вывода. Исключение только одно -- синий экран смерти. Да и то вроде в десятке все сложнее. Да, используются более низкоуровневые механизмы, но это лишь повод изучить систему получше.
Всего-лишь несколько сотен, и что? Думаешь это намного сложнее, чем перелопатить несколько тысяч пикселей, пусть даже и в битовом представлении? Так что, я тебя огорчу, намного проще. Не, если тебе реально делать нечего, барабан на шею, палочки в зубы и вперёд. В будущем может и пригодится.

Добавлено спустя 1 минуту 19 секунд:
olegy123, это да, но думал, что это как раз очевидно.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Оптимизация сравнения двух изображений

Сообщение Alex2013 » 21.04.2019 14:19:17

1 Транспарант виден всегда (не смотря на переключение между виртуальными экранами ) так что возможно это просто "тупой хук на onPaint" десктопа. А "изучить систему получше" это безусловно хорошая идея но если важен быстрый результат то в начале делаешь по первому пришедшему в голову рабочему варианту (а потом еще и думаешь, а нужен ли вообще в данном случае весь этот "махровый перфекционизм" ) Кстати не факт что в данной случае вообще есть другое решение например упомянутый выше " хук на onPaint" отследить "умными методами" практически нереально. :idea:

2 Ну не я же "перелопачиваю несколько тысяч пикселей" а мой код (точнее CompareByte ) ты просто глянь в код программы
Код: Выделить всё
Function CompareBMP (B1,B2:TBitmap):Bool;
begin
  Result:=False;
If (B1<> Nil) and (B2<> Nil) and  (B1.RawImage.DataSize>0) and (B2.RawImage.DataSize>0) then
Result:=( CompareByte(B1.RawImage.Data^,b2.RawImage.Data^,b1.RawImage.DataSize) = 0);
end;

procedure TSCForm1.Timer1Timer(Sender: TObject);
  var
   MyBitmap : TBitmap;
   ScreenDC : HDC;
   R:TRect;
begin

   MyBitmap:=TBitmap.Create;

   ScreenDC:=GetDC(0); MyBitmap.LoadFromDevice(ScreenDC);
   R:=Rect(0,0,MyBitmap.Width,self.TrackBar1.Position);

   With  Image1.Picture.Bitmap do 
      begin  SetSize(r.Width,r.Height);  Canvas.CopyRect(r, MyBitmap.Canvas,r);  end;
MyBitmap.Free;

Shape2.hide;

   if  CheckBox1.Checked And
    CompareBMP(Image1.Picture.Bitmap,Image2.Picture.Bitmap) then
    begin
      Shape2.Show;
      KeyInput.Down(vk_LWin);
      KeyInput.Press(vk_Y);
      KeyInput.Up(vk_LWin);
    end
end;


Все ! А через процессы и хуки на события?(это если допустить что они вообще работают :roll: ) Да возможно было бы быстрее,но код скорее всего получился бы сложнее и как минимум менее очевидным. К тому-же скорость в данном случае не особо важна ... Да, это "самоочевидное решение в лоб" но функцию выполняет а написано и отлажено за час (и то по причине упомянутого поиска "готовых решений" и копания в своем же старом коде (где я и выудил CompareByte) ) так что q.e.d. :idea:
Последний раз редактировалось Alex2013 21.04.2019 14:31:43, всего редактировалось 1 раз.
Alex2013
долгожитель
 
Сообщения: 2924
Зарегистрирован: 03.04.2013 11:59:44

Re: Оптимизация сравнения двух изображений

Сообщение Лекс Айрин » 21.04.2019 14:30:43

Alex2013, если это не тупо картинка взятая из файла, то данные откуда-то брались, для ее синтеза. А значит где-то есть буфер, где эта картинка. Единственное место, если не считать очень уж большой экзотики, это буфер окна, так нелюбимый тобою канвас. И нет никаких причин полагать, что создатели операционки или программы создали костыль чтобы что-то кинуть поверх окна. Скорее всего, это обычное всплывающее окно. Возможно частично рисованное или упрощённое, это несложно. Особенно на это намекает, что туда надо отослать некую комбинацию нажатий клавиш. То есть, сам механизм обработки сообщений есть.
Видимо,. Тебе привычнее работать с графикой, чем с GUI. Обычный программист все же попытался бы найти окно. Это реально легче.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Оптимизация сравнения двух изображений

Сообщение Alex2013 » 21.04.2019 15:11:18

1 Канвас я люблю (ага, "нежно и ласково" ... :wink: ) С точки зрения простого рисования примитивами это реально очень удобная и достаточно быстрая "надстройка". (Особенно если учитывать возможность использования метафайлов Кстати Канвас это не просто оболочка GUI или GDI ... ) Но вот "Пиксельная матрица" это реальный "медленный кошмар" даже на чтение.

2 Уф! Картинка? Не думаю ! ( Даже точно не картинка потому что от цветовой схемы зависит ) Однако вполне вероятно, что там хук и простой TextОut( ScreenDC ,Х,Y, "нажмите Win-Y..." ) (ну или что-то не менее кондовое ) и все... Другое дело что где-то в ресурсах или реестре есть сама надпись, скан код клавиши, стартовое состояние и вполне возможно некий "флаг блокировки" .

3 Охотно признаю что сейчас обработка изображений достаточно близкая мне тема. Но согласись что мое решение тоже из разряда "проще не бывает" . Хотя разумеется хотелось бы отловить транспарант в "темную" без необходимости "захвата образца" что явно лишнее движение .
Возможно в это деле может помочь WMR API (По идее прикладным программам нужно знать текущее состояние "захвата ввода" )
В принципе информации достаточно
https://habr.com/ru/company/microsoft/blog/418655/
Но ... опять из пушки по воробьям ! :idea:
Последний раз редактировалось Alex2013 24.04.2019 10:17:27, всего редактировалось 3 раз(а).
Alex2013
долгожитель
 
Сообщения: 2924
Зарегистрирован: 03.04.2013 11:59:44

Пред.След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

Рейтинг@Mail.ru