image-match est, en un mot, un moteur de recherche d'images. Vous pouvez enregistrer n'importe quelle image et trouver l'image en utilisant l'image comme clé. Il est également possible d'effectuer une recherche d'images à une vitesse extrêmement élevée en combinant avec Elasticsearch.
article | La description |
---|---|
Date de vérification | 2016.04.08 |
OS | Mac OS X 10.10.5 |
Python | 2.7.11 |
Elasticsearch | 2.2.1 |
$ brew install py2cairo cairo elasticsearch
$ pip install numpy scipy image_match
Essayons un exemple de README de correspondance d'image.
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))
Je vais essayer.
$ python first.py
0.220951701409
0.684462753815
0.422527138625
Si vous spécifiez l'URL de l'image cible, vous pouvez obtenir l'image et effectuer une recherche. Cela prendra un certain temps, c'est donc une bonne idée de le supprimer à l'avance avec curl
etc. et de spécifier directement le chemin du fichier.
with Elasticsearch Utilisons-le avec 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]
Après avoir démarré Elasticsearch, exécutez le script suivant.
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"
}
]
Plus le nombre de «score» est grand (plus petit, plus proche de «dist»), plus les images sont similaires.
Recommended Posts