Модераторы: Snowy, Alexeis, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Быстрое сравнение двух рисунков 
:(
    Опции темы
EPaul
Дата 20.9.2010, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.6.2009
Где: Наб-Челны

Репутация: нет
Всего: нет



Есть ли какой нибудь метод быстрого сравнения двух рисунков, типа if bitmap1 = bitmap2 then Попиксельный метод сравнения 2 bitmap не подходит, очень медленно, да и систему нагружает сильно. Заранее спасибо за ответы 
PM MAIL   Вверх
~FoX~
Дата 20.9.2010, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


Профиль
Группа: Участник Клуба
Сообщений: 2819
Регистрация: 8.10.2003
Где: Зеленоград

Репутация: 2
Всего: 68



ScanLine быстрее в делфях не предусмотрено... Можно использовать GDI+, там много быстрее работа с изображениями...
Вобще то тему в алгоритмы, но и в этом разделе вопрос сравнения изображений поднимался не раз...
Проще всего сравнивать не сами рисунки, а например МД5 или ЦРЦ (если это файлы), есть алгоритм PSNR, но это сложно... 



--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
Snowy
Дата 20.9.2010, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 18
Всего: 484



Можно загрузить оба битмапа в TMemoryStream.
Если размер стримов разный, то сразу нет.
Если одинаковый, то сравнить с помощью CompareMem.
PM MAIL   Вверх
EPaul
Дата 20.9.2010, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.6.2009
Где: Наб-Челны

Репутация: нет
Всего: нет



Snowy,  Спасибо.  Буду пробовать
PM MAIL   Вверх
EPaul
Дата 20.9.2010, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.6.2009
Где: Наб-Челны

Репутация: нет
Всего: нет



Snowy,  Попробовал.  Сравнение стримов и попиксельное сравнение по нагрузке на систему большой разницы не заметил. Кроме того, загрузка в stream также сильно нагружает систему, в зависимости от размера Bitmapa.  Может есть другие методы или компонеты для быстрой работы с графикой, использующие DirectX, например, или еще что. 
PM MAIL   Вверх
Alexeis
Дата 20.9.2010, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



Цитата(EPaul @  20.9.2010,  15:26 Найти цитируемый пост)
Кроме того, загрузка в stream также сильно нагружает систему, в зависимости от размера Bitmapa.  Может есть другие методы или компонеты для быстрой работы с графикой, использующие DirectX, например, или еще что.  

  Можно для начала файлы открыть в TFileStream и сравнить размеры, если не совпадают, то перейти к началу растра и подгружать кусками, скажем по 4кб и сравнивать. 
  Вообще, есть решение лучше. Вместо TMemoryStream использовать отображение файлов в память FileMapping, а уже для отображений использовать CompareMem. Функция CompareMem сравнивая будет постепенно подгружать файл. Если файлы одного размера, но с разным контентом, то реально загрузиться лишь небольшой фрагмент от каждого файла, что займет значительно меньше времени.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
EPaul
Дата 20.9.2010, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.6.2009
Где: Наб-Челны

Репутация: нет
Всего: нет



Alexeis,  Сравниваю не файлы, а картинку с экрана. Принцип такой, при старте программы сохраняю картинку с экрана в bitmap, допустим в PredBMP. Через определенные промежутки времени снимаю экран в CurrBMP. Это делаю методом BitBlt.  Нагрузка почти нулевая при разрешении экрана 1680Х1050
Далее дроблю оба bitmapa на N-ное количество мелких LPredBMP и LCurrBMP , допустим 50х50 пикселей, получаю при таких входных параметрах 714 мелких картинок методом
    LPredBMP.Canvas.CopyRect(Rect(0, 0, LRight-LLeft, LPredBMP.Height),   PredBMP.Canvas,   Rect(LLeft, LTop, LRight, LBottom)); 
и  LCurrBMP.Canvas.CopyRect(Rect(0, 0, LRight-LLeft, LCurrBMP.Height),   CurrBMP.Canvas,   Rect(LLeft, LTop, LRight, LBottom)); Тормоза начинаются уже здесь. Потом сравниваю между собой мелкие картинки. Если разные, сохраняю в StringList порядковый номер картинки и саму измененную картинку записываю в конец результирующего LLongBMP, размером Height =50 и Width = количество измененных картинок * 50. 
StringList с номерами и LLongBMP пересылаются потоками другой программе которая, по номеру вычисляет координаты измененных мест на экране и прорисовывает их. Сравнивать пробовал и попиксельно и с помощью MemoryStream, разницы не заметил. При частоте опроса 10 раз в секунду, процессор грузится до 50%.  Что можно сделать? 
PM MAIL   Вверх
Qu1nt
Дата 21.9.2010, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 13.1.2007

Репутация: 2
Всего: 50



Опиши задачу smile
PM MAIL   Вверх
Alexeis
Дата 21.9.2010, 09:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



Цитата(EPaul @  20.9.2010,  18:04 Найти цитируемый пост)
StringList с номерами и LLongBMP пересылаются потоками другой программе которая, по номеру вычисляет координаты измененных мест на экране и прорисовывает их. Сравнивать пробовал и попиксельно и с помощью MemoryStream, разницы не заметил. При частоте опроса 10 раз в секунду, процессор грузится до 50%.  Что можно сделать?  

  Ну так количество сравнений будет n^2/2 = 250000 сравнений на 1 кадр и 2,5 млн сравнений в секунду по 250 пикселов. Можно процесс несколько ускорить, если для каждого фрагмента посчитать например сумму цветов всех пикселов (или crc сумму). Если суммы отличаются, то картинки на 100% отличаются, если же суммы совпали, то нужно дополнительно проверить сравнением. 
  Если совпадения кадров явление частое, то можно считать crc32. Случайное совпадение crc32 событие исключительно редкое, так что совпадение crc32 можно считать совпадением картинок. 

  Алгоритм со сложностью n^2 является плохим, но сравнение целых чисел куда быстрее чем картинок + расходы на расчет 714 (это все таки не 250 000). Кроме того, и этот алгоритм можно улучшить, если ключи (хеш суммы) отсортировать при помощи алгоритма быстросорт (сложность алгоритма n * log2 n ).

  Итого вместо жуткого n^2 по картинкам можно дойти до сложности n * log2 n по ключам + сложность n по вычислению хеша

Добавлено через 4 минуты и 3 секунды
Цитата(Alexeis @  21.9.2010,  08:39 Найти цитируемый пост)
если ключи (хеш суммы) отсортировать при помощи алгоритма быстросорт (сложность алгоритма n * log2 n ).

  На всякий случай. Чтобы найти одинаковые картинки в отсортированном массиве нужно сравнивать только соседние элементы. Можно оптимизировать быстросорт так чтобы он сразу же исключал повторения и создавал уже готовый массив уникальных ключей.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
EPaul
Дата 21.9.2010, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.6.2009
Где: Наб-Челны

Репутация: нет
Всего: нет



Alexeis,  Это нужно переварить
PM MAIL   Вверх
Dimonka2
Дата 22.9.2010, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 19.3.2009

Репутация: нет
Всего: нет



Картинки можно сначала уменьшить, а потом сравнивать уменьшенные верии. Это если конечно не интересуют какие-то сверх-мелкие детали.
PM MAIL   Вверх
Alexeis
Дата 22.9.2010, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



Цитата(Dimonka2 @  22.9.2010,  10:43 Найти цитируемый пост)
Картинки можно сначала уменьшить, а потом сравнивать уменьшенные верии. 

  Так картинки и так относительно маленькие 50х50. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
xkor
Дата 22.9.2010, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 8.1.2007
Где: Питер

Репутация: нет
Всего: 4



Цитата(EPaul @  20.9.2010,  19:04 Найти цитируемый пост)
Далее дроблю оба bitmapa на N-ное количество мелких LPredBMP и LCurrBMP , допустим 50х50 пикселей, получаю при таких входных параметрах 714 мелких картинок методом
    LPredBMP.Canvas.CopyRect(Rect(0, 0, LRight-LLeft, LPredBMP.Height),   PredBMP.Canvas,   Rect(LLeft, LTop, LRight, LBottom)); 
и  LCurrBMP.Canvas.CopyRect(Rect(0, 0, LRight-LLeft, LCurrBMP.Height),   CurrBMP.Canvas,   Rect(LLeft, LTop, LRight, LBottom)); Тормоза начинаются уже здесь.

естественно тут будут тормоза CopyRect вещь медленная, тут тоже лучше BitBlt использовать (правда не помню умеет ли она куски вырывать, но если нет то 100% есть аналог который умеет)
НО у вас мне кажется неверный подход, зачем изображение сразу дробить?, вы сначала сравните старую большую и новую большую картинку, а дальше уже копируйте только куски с изменившимися данными, а лучше одновременно, то есть сравниваете попиксельно (быстрее невозможно) и как только один пиксель оказался не таким как раньше копируете соответствующий этому пикселю кусок картинки в массив изменившихся и больше пиксели этого куска не трогаете.

PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
EPaul
Дата 22.9.2010, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 22.6.2009
Где: Наб-Челны

Репутация: нет
Всего: нет



xkor, Я вообщето так и делаю. На пальцах трудно объяснять. Если не поленитесь посмотреть код, могу выслать.
PM MAIL   Вверх
x128
Дата 22.9.2010, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 29.9.2009

Репутация: 5
Всего: 7



Цитата(EPaul @  20.9.2010,  19:04 Найти цитируемый пост)
Далее дроблю оба bitmapa на N-ное количество мелких LPredBMP и LCurrBMP , допустим 50х50 пикселей, ... Тормоза начинаются уже здесь. Потом сравниваю между собой мелкие картинки. Если разные, сохраняю в StringList порядковый номер картинки и саму измененную картинку записываю в конец результирующего LLongBMP, размером Height =50 и Width = количество измененных картинок * 50. 

Зачем делать лишнюю работу если результат может потом не понадобиться? Сначала нужно проверить, а только потом копировать фрагменты где есть разница.

Цитата(EPaul @  20.9.2010,  19:04 Найти цитируемый пост)
tringList с номерами и LLongBMP пересылаются потоками другой программе которая, по номеру вычисляет координаты измененных мест на экране и прорисовывает их. Сравнивать пробовал и попиксельно и с помощью MemoryStream, разницы не заметил. При частоте опроса 10 раз в секунду, процессор грузится до 50%.  Что можно сделать? 

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

Цитата(Alexeis @  21.9.2010,  09:39 Найти цитируемый пост)
Можно процесс несколько ускорить, если для каждого фрагмента посчитать например сумму цветов всех пикселов (или crc сумму). Если суммы отличаются, то картинки на 100% отличаются, если же суммы совпали, то нужно дополнительно проверить сравнением.   Если совпадения кадров явление частое, то можно считать crc32. Случайное совпадение crc32 событие исключительно редкое, так что совпадение crc32 можно считать совпадением картинок.

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

З.Ы. ради интереса прикинул затраты на сравнение, в результате на р4-2.4 с размером изображения 1600х1200 и размером блоков 16х16 и с визуализацией, при 10 кадрах в секунду нагрузка на процессор составила ~5%. 
PM MAIL WWW   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • По вопросам разработки игр стоит заглянуть сюда

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема »


 




[ Время генерации скрипта: 0.1159 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.