Название: Как быстро сравнить две картинки? Отправлено: PavelVX от Июнь 17, 2014, 12:52 Добрый день!
Есть 2 jpg файлика. Один кусок другого. Подскажите, а как можно быстро сравнить две картинки? Подскажите также, как сохранить/загрузить картинку не изменяя её? Пробую дубово сравнить картинки: QImage img1, img2; int globalCount=0, ecvivaletCount = 0; QString format = "jpg"; QString fileName; fileName = QString("d:/cache/boot_logo.%1").arg(format); img2.load(fileName, format.toAscii()); img1.load(fileName, format.toAscii()); fileName = QString("d:/cache/boot_logo2.%1").arg(format); img1.save(fileName, format.toAscii(), 100); img1.load(fileName, format.toAscii()); if ((img1.width() != img2.width()) || (img1.height() != img2.height())) return 0; globalCount = img1.width()*img1.height(); for (int i=0;i<img1.width();i++) for (int j=0;j<img1.height();j++) { if (img1.pixel(i, j) == img2.pixel(i, j)) ecvivaletCount++; } return 100 * ecvivaletCount / globalCount; Казалось бы, берем картинку, сохраняем, открываем. Но при сравнении получается 50% совпадения. ЧЯДНТ? Название: Re: Как быстро сравнить две картинки? Отправлено: Swa от Июнь 17, 2014, 13:23 А вы сравните размеры файлов boot_logo и boot_logo2, они будут разные, потому что второй файл был получен методом QImage::save, скорее всего с помощью немного другого алгоритма.
Но вам не нужно сравнивать попиксельно, ищите алгоритмы сравнения изображений (https://www.google.com/search?num=100&newwindow=1&site=&source=hp&q=%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC+%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F+%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B9), например посмотрите тут http://habrahabr.ru/post/120562/ (http://habrahabr.ru/post/120562/) Название: Re: Как быстро сравнить две картинки? Отправлено: PavelVX от Июнь 17, 2014, 15:23 За ссылки спасибо, буду читать. На хабре очень много полезного есть.
У меня картинки-то 300 на 300 пикселей. Могу и тупо перебором сделать. Но хочется-то красиво :) Хмм, тогда появляется вопрос: а как сохранять картинку не изменяя её??? Не писать же самому хранение потока попиксельно в qrgb. Название: Re: Как быстро сравнить две картинки? Отправлено: Swa от Июнь 17, 2014, 16:00 Ну вот по этим ссылкам и будет красиво, а то, что делаете вы - это некрасивый и неработающий велосипед.
А как у вас программа работает? Зачем вы сохраняете картинку? В её изменяете в процессе? Название: Re: Как быстро сравнить две картинки? Отправлено: PavelVX от Июнь 17, 2014, 17:10 Все до безобразия просто: есть набор картинок на экране, нужно сравнить их с шаблонами на диске.
Но сравнение должно быть точным. Как раз в деталях и будет различие. Поэтому часть методов с хабра не подойдут. Название: Re: Как быстро сравнить две картинки? Отправлено: Swa от Июнь 17, 2014, 19:11 А поподробнее можно?
Название: Re: Как быстро сравнить две картинки? Отправлено: PavelVX от Июнь 17, 2014, 19:46 Есть две картинки: на сайте и на диске.
Я делаю скриншот сайта. Если нужный фрагмент не совпадает с эталоном(на диске) мне нужно выдать предупреждение. Поэтому я и начал реализовывать самое простое: побайтовое сравнение. Если проект пойдет в жизнь, то буду оптимизировать. Подскажите: как мне программно сравнить побайтово две картинки? Или как сохранить без искажений? Название: Re: Как быстро сравнить две картинки? Отправлено: Swa от Июнь 17, 2014, 20:03 Вам нужно почитать про форматы изображений.
Если кратко, то изображения могут храниться в разных форматах. Самый простой формат - bmp, в нем каждый пиксель картинки описывается тремя числами - красная, синяя и зеленая компоненты. Т.о. два изображения формата bmp можно сравнять попиксельно (с учетом того, что они имеют одинаковую битность). Все остальные форматы - это форматы с потерей информации. То есть когда вы сохраняете изображение в формате jpg то некоторые пиксели меняют данные о цвете, но так, что человеческому глазу это едва заметно. Компьютер же оперирует не образами на картинке, а числами, соответственно он считает эти два изображения разными. Кроме того, при сохранении изображения в формате jpg алгоритму можно передать разные опции сжатия, соответственно изображения, полученные с разными параметрами, будут отличаться (опять же, для компьютера). Делайте тогда так, что и изображения у вас на диске, и скриншот делала бы ваша программа и сохраняла эти изображения в одинаковом формате (bmp). Потом от каждой картинки (на диске) считаете хеш, как описано в статье по ссылке. Если хеши совпадают, то с большой вероятностью изображения одинаковые. Тогда уже можно их сравнить попиксельно, чтобы убедиться в этом. Такой метод позволит сократить время поиска совпадения (числа сравнивать быстрее чем большой массив чисел) Название: Re: Как быстро сравнить две картинки? Отправлено: m_ax от Июнь 17, 2014, 20:10 Вообще то у QImage уже есть оператор равенства..
Так что можно проще: Код
Название: Re: Как быстро сравнить две картинки? Отправлено: PavelVX от Июнь 18, 2014, 04:40 Вообще то у QImage уже есть оператор равенства.. Спору нет, знак равенства есть. Но как я уже показал выше, берем одно и тоже изображение, сохраняем, читаем, получаем уже немного другое изображение :)Так что можно проще: Код
Название: Re: Как быстро сравнить две картинки? Отправлено: Igors от Июнь 18, 2014, 08:57 Самый простой формат - bmp, в нем каждый пиксель картинки описывается тремя числами - красная, синяя и зеленая компоненты. Т.о. два изображения формата bmp можно сравнять попиксельно (с учетом того, что они имеют одинаковую битность). Почти наоборот - только jpg по умолчанию "химичит", остальные сохраняют "один в один", т.е. без потерь. Проще всего сохранять в png.Все остальные форматы - это форматы с потерей информации. Вообще каждый формат имеет опции (под-форматы), но они используются довольно редко. По дефаулту png точно lossless Название: Re: Как быстро сравнить две картинки? Отправлено: PavelVX от Июнь 18, 2014, 09:44 Ну с bmp фокус прокатил. Все сравнивается корректно. С другими форматами эксперементировать не буду. Смысла нет. Потом только оптимизация поможет :)
И кстати, img1==img2 отрабатывается порядка в два раза быстрее, чем по пиксельное сравнение. Поэтому, в начале, проверяю на равенство, если нет, то процент из по пиксельного сравнения. Кстати, с ходу не нашел в методах: а как делать наложение на другое изображение по маске(AND, OR, XOR)? Название: Re: Как быстро сравнить две картинки? Отправлено: Igors от Июнь 18, 2014, 10:08 Кстати, с ходу не нашел в методах: а как делать наложение на другое изображение по маске(AND, OR, XOR)? Это не в QImage а в рисовании, см QPainter::setCompositionModeНазвание: Re: Как быстро сравнить две картинки? Отправлено: Hrundel от Июль 16, 2014, 18:06 При этом желательно быть уверенным, что сверяемые изображения не содержат Watermark. Иначе два визуально одинаковых изображения могут быть обозначены как неодинаковые. Но, тут уже больше зависит от цели, что нужно - сравнивать визуальную картинку или фактические различия данных?
Название: Re: Как быстро сравнить две картинки? Отправлено: deMax от Август 13, 2014, 14:16 Почти наоборот - только jpg по умолчанию "химичит", остальные сохраняют "один в один", т.е. без потерь. Проще всего сохранять в png. Для векторной графики png даже лучше будет, и весит иногда меньше. Еще jpeg2000 в режиме без потерь был.p.s. А зачем вообще сравнивать картинки, может лучше сравнить исходные файлы html+jpg? И чтобы много не хранить можно использовать хэш суммы, это покажет что есть изменения, правда не скажет какие. Места будет копейки занимать. |