[PYTHON] Verwendung von Image-Match

Einführung

image-match ist kurz gesagt eine Bildsuchmaschine. Sie können jedes Bild registrieren und das Bild anhand des Bildes als Schlüssel finden. Durch die Kombination mit Elasticsearch ist es auch möglich, eine Bildsuche mit extrem hoher Geschwindigkeit durchzuführen.

Voraussetzungen

Artikel Erläuterung
Überprüfungsdatum 2016.04.08
OS Mac OS X 10.10.5
Python 2.7.11
Elasticsearch 2.2.1

Vorbereitungen

$ brew install py2cairo cairo elasticsearch
$ pip install numpy scipy image_match

Wie benutzt man

Versuchen Sie, Bilder zu vergleichen

Versuchen wir ein Beispiel für README mit Bildübereinstimmung.

first.py


from image_match.goldberg import ImageSignature

gis = ImageSignature()
# a = gis.generate_signature('https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg/687px-Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg')
a = gis.generate_signature('687px-Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg')
#b = gis.generate_signature('https://pixabay.com/static/uploads/photo/2012/11/28/08/56/mona-lisa-67506_960_720.jpg')
b = gis.generate_signature('mona-lisa-67506_960_720.jpg')

print(gis.normalized_distance(a, b))

c = gis.generate_signature('https://upload.wikimedia.org/wikipedia/commons/e/e0/Caravaggio_-_Cena_in_Emmaus.jpg')
print(gis.normalized_distance(a, c))

d = gis.generate_signature('https://c2.staticflickr.com/8/7158/6814444991_08d82de57e_z.jpg')
print(gis.normalized_distance(a, d))

Ich werde es versuchen.

$ python first.py
0.220951701409
0.684462753815
0.422527138625

Wenn Sie die URL für das Zielbild angeben, können Sie das Bild abrufen und suchen. Es wird einige Zeit dauern, daher ist es eine gute Idee, es im Voraus mit "curl" usw. zu löschen und den Dateipfad direkt anzugeben.

with Elasticsearch Verwenden wir es mit Elasticsearch.

$ elasticsearch
[2016-04-08 15:18:47,952][INFO ][node                     ] [Alexander Lexington] version[2.2.1], pid[59417], build[d045fc2/2016-03-09T09:38:54Z]
[2016-04-08 15:18:47,952][INFO ][node                     ] [Alexander Lexington] initializing ...
[2016-04-08 15:18:48,945][INFO ][plugins                  ] [Alexander Lexington] modules [lang-expression, lang-groovy], plugins [], sites []
[2016-04-08 15:18:48,998][INFO ][env                      ] [Alexander Lexington] using [1] data paths, mounts [[/ (/dev/disk1)]], net usable_space [69.9gb], net total_space [232.6gb], spins? [unknown], types [hfs]
[2016-04-08 15:18:48,998][INFO ][env                      ] [Alexander Lexington] heap size [990.7mb], compressed ordinary object pointers [true]
[2016-04-08 15:18:48,999][WARN ][env                      ] [Alexander Lexington] max file descriptors [10240] for elasticsearch process likely too low, consider increasing to at least [65536]
[2016-04-08 15:18:52,884][INFO ][node                     ] [Alexander Lexington] initialized
[2016-04-08 15:18:52,884][INFO ][node                     ] [Alexander Lexington] starting ...
[2016-04-08 15:18:53,095][INFO ][transport                ] [Alexander Lexington] publish_address {127.0.0.1:9300}, bound_addresses {[fe80::1]:9300}, {[::1]:9300}, {127.0.0.1:9300}
[2016-04-08 15:18:53,109][INFO ][discovery                ] [Alexander Lexington] elasticsearch_hattori-h/FnX_ySN8RP2my8GcBTZsvw
[2016-04-08 15:18:56,148][INFO ][cluster.service          ] [Alexander Lexington] new_master {Alexander Lexington}{FnX_ySN8RP2my8GcBTZsvw}{127.0.0.1}{127.0.0.1:9300}, reason: zen-disco-join(elected_as_master, [0] joins received)
[2016-04-08 15:18:56,182][INFO ][http                     ] [Alexander Lexington] publish_address {127.0.0.1:9200}, bound_addresses {[fe80::1]:9200}, {[::1]:9200}, {127.0.0.1:9200}
[2016-04-08 15:18:56,182][INFO ][node                     ] [Alexander Lexington] started
[2016-04-08 15:18:56,230][INFO ][gateway                  ] [Alexander Lexington] recovered [0] indices into cluster_state
[2016-04-08 15:34:22,441][INFO ][cluster.metadata         ] [Alexander Lexington] [images] creating index, cause [auto(index api)], templates [], shards [5]/[1], mappings [image]
[2016-04-08 15:34:22,889][INFO ][cluster.routing.allocation] [Alexander Lexington] Cluster health status changed from [RED] to [YELLOW](reason: [shards started [[images][4]] ...]).
[2016-04-08 15:34:22,998][INFO ][cluster.metadata         ] [Alexander Lexington] [images] update_mapping [image]

Führen Sie nach dem Starten von Elasticsearch das folgende Skript aus.

first_with_es.py


import json
from elasticsearch import Elasticsearch
from image_match.elasticsearch_driver import SignatureES

es = Elasticsearch()
ses = SignatureES(es)

image_set = (
    'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg/687px-Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg',
    'https://pixabay.com/static/uploads/photo/2012/11/28/08/56/mona-lisa-67506_960_720.jpg',
    'https://upload.wikimedia.org/wikipedia/commons/e/e0/Caravaggio_-_Cena_in_Emmaus.jpg',
    'https://c2.staticflickr.com/8/7158/6814444991_08d82de57e_z.jpg',
)
for img in image_set:
    print("add image to Elasticsearch. img=%s" % img)
    ses.add_image(img)


search_image_set = (
    'https://pixabay.com/static/uploads/photo/2012/11/28/08/56/mona-lisa-67506_960_720.jpg',
    'http://i.imgur.com/CVYBCCy.jpg',
    'http://i.imgur.com/T5AusYd.jpg',
)
for img in search_image_set:
    print("=== search %s ===" % img)
    print(json.dumps(ses.search_image(img, all_orientations=True), indent=2))
$ first_with_es.py
add image to Elasticsearch. img=https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg/687px-Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg
add image to Elasticsearch. img=https://pixabay.com/static/uploads/photo/2012/11/28/08/56/mona-lisa-67506_960_720.jpg
add image to Elasticsearch. img=https://upload.wikimedia.org/wikipedia/commons/e/e0/Caravaggio_-_Cena_in_Emmaus.jpg
add image to Elasticsearch. img=https://c2.staticflickr.com/8/7158/6814444991_08d82de57e_z.jpg
=== search https://pixabay.com/static/uploads/photo/2012/11/28/08/56/mona-lisa-67506_960_720.jpg ===
[
  {
    "path": "https://pixabay.com/static/uploads/photo/2012/11/28/08/56/mona-lisa-67506_960_720.jpg ",
    "score": 2.435569,
    "dist": 0.0,
    "id": "AVP0lC4XSbcGjA3_XZUG"
  },
  {
    "path": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg/687px-Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg ",
    "score": 0.029808408,
    "dist": 0.22095170140933634,
    "id": "AVP0lCRBSbcGjA3_XZUF"
  },
  {
    "path": "https://c2.staticflickr.com/8/7158/6814444991_08d82de57e_z.jpg ",
    "score": 0.004886414,
    "dist": 0.42325822368808808,
    "id": "AVP0lDflSbcGjA3_XZUI"
  }
]
=== search http://i.imgur.com/CVYBCCy.jpg ===
[
  {
    "path": "https://pixabay.com/static/uploads/photo/2012/11/28/08/56/mona-lisa-67506_960_720.jpg ",
    "score": 0.20739666,
    "dist": 0.15454905655638429,
    "id": "AVP0lC4XSbcGjA3_XZUG"
  },
  {
    "path": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg/687px-Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg ",
    "score": 0.016346568,
    "dist": 0.24980626832071956,
    "id": "AVP0lCRBSbcGjA3_XZUF"
  },
  {
    "path": "https://c2.staticflickr.com/8/7158/6814444991_08d82de57e_z.jpg ",
    "score": 0.0031033582,
    "dist": 0.43156216266051023,
    "id": "AVP0lDflSbcGjA3_XZUI"
  }
]
=== search http://i.imgur.com/T5AusYd.jpg ===
[
  {
    "path": "https://pixabay.com/static/uploads/photo/2012/11/28/08/56/mona-lisa-67506_960_720.jpg ",
    "score": 1.5544797,
    "dist": 0.069116439263706961,
    "id": "AVP0lC4XSbcGjA3_XZUG"
  },
  {
    "path": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg/687px-Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg ",
    "score": 0.029808408,
    "dist": 0.22484320805049718,
    "id": "AVP0lCRBSbcGjA3_XZUF"
  },
  {
    "path": "https://c2.staticflickr.com/8/7158/6814444991_08d82de57e_z.jpg ",
    "score": 0.004886414,
    "dist": 0.42394015619010844,
    "id": "AVP0lDflSbcGjA3_XZUI"
  }
]

Je größer die Anzahl der "Punkte" (kleiner, näher an "dist") ist, desto ähnlicher sind die Bilder.

Recommended Posts

Verwendung von Image-Match
Wie benutzt man Python-Shell
Hinweise zur Verwendung von tf.data
Verwendung von virtualenv
Wie benutzt man Seaboan?
Wie man Shogun benutzt
Verwendung von Pandas 2
Verwendung von Virtualenv
Verwendung von numpy.vectorize
Verwendung von pytest_report_header
Wie man teilweise verwendet
Wie man Bio.Phylo benutzt
Verwendung von SymPy
Wie man x-means benutzt
Verwendung von WikiExtractor.py
Verwendung von IPython
Verwendung von virtualenv
Wie benutzt man Matplotlib?
Verwendung von iptables
Wie benutzt man numpy?
Verwendung von TokyoTechFes2015
Wie benutzt man venv
Verwendung des Wörterbuchs {}
Wie benutzt man Pyenv?
Verwendung der Liste []
Wie man Python-Kabusapi benutzt
Verwendung von OptParse
Verwendung von return
Wie man Imutils benutzt
Verwendung von Qt Designer
Verwendung der Suche sortiert
[gensim] Verwendung von Doc2Vec
python3: Verwendung der Flasche (2)
Verstehen Sie, wie man Django-Filter verwendet
Verwendung des Generators
[Python] Verwendung von Liste 1
Verwendung von FastAPI ③ OpenAPI
Wie benutzt man Python Argparse?
Verwendung von IPython Notebook
Wie man Pandas Rolling benutzt
[Hinweis] Verwendung von virtualenv
Verwendung von Redispy-Wörterbüchern
Python: Wie man pydub benutzt
[Python] Verwendung von checkio
[Go] Verwendung von "... (3 Perioden)"
So bedienen Sie GeoIp2 von Django
[Python] Verwendung von input ()
Wie benutzt man den Dekorateur?
[Einführung] Verwendung von open3d
Wie benutzt man Python Lambda?
So verwenden Sie Jupyter Notebook
[Python] Verwendung von virtualenv
python3: Verwendung der Flasche (3)
python3: Wie man eine Flasche benutzt
So verwenden Sie Google Colaboratory
Verwendung von Python-Bytes
Verwendung von cron (persönliches Memo)