2016-10-15 10 views
1

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

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

Заранее спасибо

ответ

2

Вам нужно быть осторожным с хешированием, некоторыми форматами изображений, такими как JPEG и PNG, хранить даты и время и другую информацию в изображениях, и это приведет к тому, что два одинаковых изображения будут отличаться от обычных инструментов, таких как md5 и cksum ,

Вот пример. Сделайте два изображения, оба одинаковые красные квадраты 128х128 в командной строке в терминале с ImageMagick

convert -size 128x128 xc:red a.png 
convert -size 128x128 xc:red b.png 

enter image description here enter image description here

Теперь проверьте их MD5 суммы:

md5 [ab].png 
MD5 (a.png) = b4b82ba217f0b36e6d3ba1722f883e59 
MD5 (b.png) = 6aa398d3aaf026c597063c5b71b8bd1a 

или их контрольные суммы :

cksum [ab].png 
4158429075 290 a.png 
3657683960 290 b.png 

К сожалению, они отличаются как от md5, так и от cksum. Зачем? Потому что даты разделены на 1 секунду.

Я хотел бы предложить вам использовать ImageMagick для контрольной суммы «только данные изображения», а не метаданные - если, конечно, дата не важна для вас:

identify -format %# a.png 
e74164f4bab2dd8f7f612f8d2d77df17106bac77b9566aa888d31499e9cf8564 

identify -format %# b.png 
e74164f4bab2dd8f7f612f8d2d77df17106bac77b9566aa888d31499e9cf8564 

Теперь они оба то же, потому что изображение одно и то же - только метаданные отличаются.

Конечно, вы можете быть более заинтересованы в «Перцепционная HASHING» где вы просто получить представление о том, если два изображения «выглядят одинаково». Если да, посмотрите here.

Или вы можете быть заинтересованы в том, чтобы допускать небольшие различия в яркости, ориентации или обрезке - это совсем другая тема.

0

Там же много способов, вы можете достичь этого, но самое простое было бы преобразовать изображение в строку base64, а затем использовать стандартную библиотеку хэширования. В питона он будет выглядеть примерно так:

import base64 
import md5 



with open("foo.png", "rb") as image_file: 
    encoded_string = base64.b64encode(image_file.read()) 
    m = md5.new() 
    m.update(encoded_string) 
    fingerprint = m.hexdigest() 
    print(fingerprint) 

Если вы просто думать о хэш-функции, как превращение одного (возможно большой) строку в другой, вы должны быть в порядке. В приведенном выше коде m.update() просто превращает encoded_string (очень большую строку base64) в меньшую шестую строку, которую мы получаем, вызывая m.hexdigest().

Вы можете прочитать документы python для библиотеки md5 here, но должно быть что-то похожее на любом языке, который вы используете.

0

Если вы заинтересованы в поиске рядом с дубликатами, которые включают в себя изображения, которые были изменены, вы можете применить разницу хэширования. Подробнее о хешировании here. Код ниже отредактирован из сообщения Real Python блога, чтобы заставить его работать на python 3. Он использует связанную выше хэш-библиотеку, которая имеет информацию о разных типах хэширования. Вы должны иметь возможность просто копировать и вставлять скрипты и запускать их непосредственно из командной строки без редактирования сценариев.

Этот первый скрипт (index.py) создает хеш разницы для каждого изображения, а затем помещает хеш в полку или постоянный словарь, к которому вы можете получить доступ позже, как к базе данных, вместе с именами файлов изображений, которые имеют хэш:

from PIL import Image 
import imagehash 
import argparse 
import shelve 
import glob 

# This is just so you can run it from the command line 
ap = argparse.ArgumentParser() 
ap.add_argument('-d', '--dataset', required = True, 
       help = 'path to imput dataset of images') 

ap.add_argument('-s', '--shelve', required = True, 
       help = 'output shelve database') 
args = ap.parse_args() 

# open the shelve database 
db = shelve.open(args.shelve, writeback = True) 

# loop over the image dataset 
for imagePath in glob.glob(args.dataset + '/*.jpg'): 
    # load the image and compute the difference in hash 
    image = Image.open(imagePath) 
    h = str(imagehash.dhash(image)) 
    print(h) 

    # extract the filename from the path and update the database using the hash 
    # as the key and the filename append to the list of values 

    filename = imagePath[imagePath.rfind('/') + 1:] 
    db[h] = db.get(h, []) + [filename] 

db.close() 

Выполнить в командной строке:

python index.py --dataset ./image_directory --shelve db.shelve 

Run в Jupyter ноутбук

%run index.py --dataset ./image_directory --shelve db.shelve 

Теперь все хранится на полке, вы можете запросить полку с именем файла изображения, которое вы хотите проверить, и распечатает имена файлов изображений, которые соответствуют, а также откройте соответствующие изображения (search.py):

from PIL import Image 
import imagehash 
import argparse 
import shelve 

# arguments for command line 
ap = argparse.ArgumentParser() 
ap.add_argument("-d", "--dataset", required=True, 
      help="path to dataset of images") 
ap.add_argument("-s", "--shelve", required=True, 
      help="output the shelve database") 
ap.add_argument("-q", "--query", required=True, 
      help="path to the query image") 
args = ap.parse_args() 

# open the shelve database 
db = shelve.open(args.shelve) 

# Load the query image, compute the difference image hash, and grab the images 
# from the database that have the same hash value 
query = Image.open(args.query) 
h = str(imagehash.dhash(query)) 
filenames = db[h] 
print("found {} images".format(len(filenames))) 

# loop over the images 
for filename in filenames: 
    print(filename) 
    image = Image.open(args.dataset + "/" + filename) 
    image.show() 

# close the shelve database 
db.close() 

Выполнить в командной строке, чтобы просмотреть image_directory для изображений с той же хэш, как ./directory/someimage.jpg

python search.py —dataset ./image_directory —shelve db.shelve —query ./directory/someimage.jpg 

Опять же, это модифицированный из Real Python блоге связанного выше, которая написана для python2.7, и должны выработайте коробку! Просто измените командную строку так, как вам нужно. Если я правильно помню, проблема с python 2/3 была только с argparse, а не с библиотеками изображений.

 Смежные вопросы

  • Нет связанных вопросов^_^