C# Сравнение двух картинок

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by noxjoker, 6 Jun 2010.

  1. noxjoker

    noxjoker Member

    Joined:
    7 Aug 2009
    Messages:
    189
    Likes Received:
    24
    Reputations:
    0
    Здравствуйте, нужен совет.
    Я делаю скриншот получаю картинку, делаю второй скриншот и нужно узнать какая была разница с первым и вторым скриншотом.

    Решение
    1. По пикселям – долгий вариант.
    2. По байтам – проблема, поскольку файлы всегда разные по размеру.


    Возможно решение поставить фиксированный размер на скриншот.
    :confused:
     
    #1 noxjoker, 6 Jun 2010
    Last edited: 6 Jun 2010
  2. scrat

    scrat кодер

    Joined:
    8 Apr 2007
    Messages:
    625
    Likes Received:
    541
    Reputations:
    3
    Что если поделить картинку на зоны, скажем на 4. Потом сравнивать каждую зону с каждой, если они разные, поделить зону ещё раз и сравнить каждую часть.
     
    1 person likes this.
  3. noxjoker

    noxjoker Member

    Joined:
    7 Aug 2009
    Messages:
    189
    Likes Received:
    24
    Reputations:
    0
    scrat а как сравнивать? По пиксельно долго ...
     
  4. scrat

    scrat кодер

    Joined:
    8 Apr 2007
    Messages:
    625
    Likes Received:
    541
    Reputations:
    3
    погугли ещё по запросу «image diff», может найдёшь какую библиотеку.
     
  5. scrat

    scrat кодер

    Joined:
    8 Apr 2007
    Messages:
    625
    Likes Received:
    541
    Reputations:
    3
    вырезать и сравнить md5
     
  6. BrainDeaD

    BrainDeaD Elder - Старейшина

    Joined:
    9 Jun 2005
    Messages:
    774
    Likes Received:
    292
    Reputations:
    214
    scrat, какое это даст приемущество перед проверкой целой картинки? 1 = 4/4
     
  7. noxjoker

    noxjoker Member

    Joined:
    7 Aug 2009
    Messages:
    189
    Likes Received:
    24
    Reputations:
    0
    Допустим они разные мне ж, потом нужно что-то заменить в первой картинке!

    Например:

    Если по пиксельное, то я узнаю какие пиксели разные потом изменяю их в первой картинке и получаю копию второй.
     
  8. scrat

    scrat кодер

    Joined:
    8 Apr 2007
    Messages:
    625
    Likes Received:
    541
    Reputations:
    3
    в том то и дело, что может быть и 3/4 и 2/4 и 1/4.
     
  9. Ra$cal

    Ra$cal Elder - Старейшина

    Joined:
    16 Aug 2006
    Messages:
    670
    Likes Received:
    185
    Reputations:
    78
    для чего сравнивать надо? просто узнать о наличии различий(тогда можно обходить попиксельно но с изменяемым шагом до первой разницы, например проверяем каждый сотый пиксел, если совпали, то сдвигаем на один пиксель и заново проходим, и так 100 раз для проверки всей картинки. на худой конец никто не отменял многоядерность, плюс на хабре была тема про медленность попиксельной обработки
    http://habrahabr.ru/blogs/net/92016/
    http://habrahabr.ru/blogs/net/60085/

    Если же обработка пикселов с разными значениями чтобы выравнять картинки - только попиксельный проход.
     
  10. BrainDeaD

    BrainDeaD Elder - Старейшина

    Joined:
    9 Jun 2005
    Messages:
    774
    Likes Received:
    292
    Reputations:
    214
    а, понял. в смысле, если 1/4 различна, то не нужно продолжать проверку. тогда вопрос в том, сколько частей оптимально? ведь проверить 1/8 быстрее, чем 1/4, и проверка может быть завершена уже после первой зоны. но в худшем случае придётся провести 8 проверок. так же можно уменьшить зону до пикселя, что усугубит ситуацийю для worst case, но сильно улучшит для best case.
     
    #10 BrainDeaD, 6 Jun 2010
    Last edited: 6 Jun 2010
  11. Ra$cal

    Ra$cal Elder - Старейшина

    Joined:
    16 Aug 2006
    Messages:
    670
    Likes Received:
    185
    Reputations:
    78
    это зависит от конкретных типов картинок, так же нужно учитывать зоны с высокой вероятностью изменений. В самом худшем случае такая проверка проиграет последовательной накладные расходы на организацию проверок и выборок областей, что, все таки, мелочи.

    Интересно все таки узнать, какого рода картинки проверяются - фото, скриншоты, или еще что.
     
  12. noxjoker

    noxjoker Member

    Joined:
    7 Aug 2009
    Messages:
    189
    Likes Received:
    24
    Reputations:
    0
    scrat очень помог.

    Решение для меня такое:

    Это сравнение части картинки с другой частью картинки не пиксели, а md5.
    В итоге мы получаем. Если md5 1 части 1 картинки != md5 1 части 2 картинки тогда эта часть разная.

    Таким образом, можно выйти из ситуации.


    Моя задача была сравнение скриншотов.
    Так же решение задачи это ставить фиксированный размер на скрины и сравнивать байты но, увы, я не знаю, как это сделать.
     
    #12 noxjoker, 6 Jun 2010
    Last edited: 6 Jun 2010
  13. Ra$cal

    Ra$cal Elder - Старейшина

    Joined:
    16 Aug 2006
    Messages:
    670
    Likes Received:
    185
    Reputations:
    78
    Объясните мне, зачем мд5? Вы берете пиксели, например 1000, прогоняете через мд5, проверяете мд5, берете 1000 пикселей второго изображдения, прогоняете мд5, сравниваете. Если немножко посчитать, вся выгода проверки заключается не в мд5, а в разбиении картинки, и мд5 здесь как раз лишнее движение, ибо он так же обходит массив пикеслей. Т.е. немножко подумав получаем, что если мы сравним 1000 пикселей мимо мд5 мы получим тот же эффект, только без лишних телодвижений. Или вы думаете мд5 магическим образом получает хэш без обхода массива?
     
  14. Ra$cal

    Ra$cal Elder - Старейшина

    Joined:
    16 Aug 2006
    Messages:
    670
    Likes Received:
    185
    Reputations:
    78
    Code:
    Pixel oldPixels[];
    Pixel newPixels[];
    
    for(int curPixIndex = 0; i < 1000; curPixIndex++){
        if(oldPixels[curPixIndex] != newPixels[curPixIndex])
            return false;
        return true;
    }
    это вариант без мд5. теперь с мд5
    return md5(oldPixels) == md5(newPixels);

    а md5 имеем

    Code:
    md5(Pixels[] pixels)
    {
    foreach(Pixel pixel in pixels){
    ...
    }
    Итого - два цикла при расчете мд5 вместо одного прямого сравнения. Прямое сравнение прерывается если пиксели не совпали. мд5 же гарантированно досчитает до конца. Считайте профит сами.
     
  15. scrat

    scrat кодер

    Joined:
    8 Apr 2007
    Messages:
    625
    Likes Received:
    541
    Reputations:
    3
    Ra$cal, хэш будет браться от байтов сжатого изображения. Но тут ещё затраты на сжатие.
     
  16. noxjoker

    noxjoker Member

    Joined:
    7 Aug 2009
    Messages:
    189
    Likes Received:
    24
    Reputations:
    0
    Сотри.

    Есть первая картинка мы просто берем ее скрин.
    [​IMG]
    Вторая картинка это скрин с изменением, например, вылезло окно.
    [​IMG]
    Мы должны узнать, где вылезло это окно, но мы ж не хотим сравнивать попиксельно и не хотим весь скрин кидать. Мы делим вторую картинку, например на 4 части.
    [​IMG]
    Узнаем хеши каждой части. Если эти хеши совпадают тогда это не та часть а если ода из частей не совпала тогда эта та часть и ее мы кидаем себе и просто налажуем на первую картинку.
     
  17. Ra$cal

    Ra$cal Elder - Старейшина

    Joined:
    16 Aug 2006
    Messages:
    670
    Likes Received:
    185
    Reputations:
    78
    Тут надо понять, важно просто отличие найти, или просто факт разницы. Ибо разница в сжатых не даст координату пикселя отличающегося. Раньше ТС чтото писал про замену пиксела.

    ТС, еще раз почитай что я написал про хеш. На личсточке можешь погонять тестовый пример 10х10 например.
     
  18. scrat

    scrat кодер

    Joined:
    8 Apr 2007
    Messages:
    625
    Likes Received:
    541
    Reputations:
    3
    Вопрос стоит в том, что будет затратнее: сжатие N-частей и сравнение хешей сжатого, или попиксельное/хешовое сравнение разжатых байтов.

    В принципе никто не мешает объединить оба подхода. Как я понимаю, для маленьких кусков изображения быстрее будет попиксельное сравнение, а вот большую картинку можно для начала поделить на много кусков, сжать их, и сравнить их хеши с хешами предыдущих.
     
  19. scrat

    scrat кодер

    Joined:
    8 Apr 2007
    Messages:
    625
    Likes Received:
    541
    Reputations:
    3
    Кстати, а что мешает просто проксорить расжатые варианты? Быстро и получится чёрная картинка, кроме разных мест.
     
  20. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    вариант предложенный scrat'ом - напоминаеи алгоритм бинарного поиска. ваще-то очень даже тру
    далее, ТС как считать хэш собрался?
    Стандартными способами?
    Тогда если операцию проводить часто, а в твоем случае так и выглядит, то лучше проводить проверку самому, и оптимизировать ее, а иначе смысла нет, т.к. вычисление md5 - такая же долгая операция, которую ты изначально не хотел.