search
LoginSignup
9
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

写真からランドマークを検出して住所情報を自動取得させてみた

概要

いろいろなAPIを利用して、自動で、写真からランドマークを検出し、住所情報も取得した。

利用したAPI

t.jpg

Vision API

vision api.png

https://cloud.google.com/vision/?hl=ja
Googleが提供している画像コンテンツ解析API
写真に写っているランドマークを検出するLANDMARK_DETECTIONや、写っているものを識別してラベルとして返すLABEL_DETECTION、テキスト検出や、顔検出、ロゴサーチ、セーフサーチなどの機能がある。
今回はLANDMARK_DETECTIONを利用して、ランドマークとその緯度経度を検出させる。

事前準備

下記URLに従って、VisionAPIを有効化する必要がある。
https://cloud.google.com/vision/docs/before-you-begin?hl=ja

ローカル環境でPythonなどのライブラリ経由で利用するため、IAMでの認証設定・ライブラリインストールも必要。
https://cloud.google.com/vision/docs/libraries?hl=ja#client-libraries-install-python

Google Maps API

google maps api.jpg

https://cloud.google.com/maps-platform/?hl=ja
Webサイト上にGoogle Mapを載せたり、住所から緯度経度を、緯度経度から住所を取得できたりするAPI。
今回利用したのは、緯度経度から住所情報を取得するGeocoding API
一点注意が必要なのが、レスポンスはすべて英語となっており、日本語での住所情報が欲しい場合は他のAPIを利用する必要がある。

事前準備

同じくGoogle Maps APIを有効化する必要がある。
Google Maps APIは、VisionAPIと違ってAPI Keyが必須なので注意。
参考:Google Maps API を使ってみた

Geo API

geoapi.png

http://geoapi.heartrails.com/
緯度経度から住所情報を取得するAPI。
こちらは日本に特化したものとなっており、日本語で住所情報を取得可能。

試してみた

ターゲット

伏見稲荷大社の写真で試してみる。

fushimi-inari.jpg

住所は〒612-0882 京都府京都市伏見区深草藪之内町68である。

Vision API

今回はpython3

>>> import os, io
>>> from google.cloud import vision
>>> from google.cloud.vision import types
>>> client = vision.ImageAnnotatorClient()
>>> file_name = "Desktop/fushimi-inari.jpg"
>>> with io.open(file_name, 'rb') as image_file:
...     content = image_file.read()
... 
>>> image = types.Image(content=content)
>>> response = client.landmark_detection(image=image)
>>> response.landmark_annotations[0]
mid: "/m/05ldrm"
description: "Fushimi Inari-Taisha"
score: 0.7252039909362793
bounding_poly {
  vertices {
    x: 165
    y: 193
  }
  vertices {
    x: 928
    y: 193
  }
  vertices {
    x: 928
    y: 781
  }
  vertices {
    x: 165
    y: 781
  }
}
locations {
  lat_lng {
    latitude: 34.967139
    longitude: 135.77301
  }
}

見事、descriptionにあるように、ランドマークとしてFushimi Inari-Taishaが検出された。
scoreは確度、bounding_polyは検出された位置を示している。
そして、locationとして緯度経度も取得できた。

Google Maps API

>>> import googlemaps
>>> from pprint import pprint
>>> GOOGLE_MAPS_API_KEY="your API key"
>>> gmaps = googlemaps.Client(key=GOOGLE_MAPS_API_KEY)
>>> latitude = response.landmark_annotations[0].locations[0].lat_lng.latitude
>>> longitude = response.landmark_annotations[0].locations[0].lat_lng.longitude
>>> result = gmaps.reverse_geocode((latitude, longitude))
>>> pprint(result)
[{'address_components': [{'long_name': '68',
                          'short_name': '68',
                          'types': ['premise']},
                         {'long_name': 'Fukakusa Yabunouchichō',
                          'short_name': 'Fukakusa Yabunouchichō',
                          'types': ['political',
                                    'sublocality',
                                    'sublocality_level_2']},
                         {'long_name': 'Fushimi-ku',
                          'short_name': 'Fushimi-ku',
                          'types': ['political',
                                    'sublocality',
                                    'sublocality_level_1']},
                         {'long_name': 'Kyōto-shi',
                          'short_name': 'Kyōto-shi',
                          'types': ['locality', 'political']},
                         {'long_name': 'Kyōto-fu',
                          'short_name': 'Kyōto-fu',
                          'types': ['administrative_area_level_1',
                                    'political']},
                         {'long_name': 'Japan',
                          'short_name': 'JP',
                          'types': ['country', 'political']},
                         {'long_name': '612-0882',
                          'short_name': '612-0882',
                          'types': ['postal_code']}],
  'formatted_address': '68 Fukakusa Yabunouchichō, Fushimi-ku, Kyōto-shi, '
                       'Kyōto-fu 612-0882, Japan',
  'geometry': {'location': {'lat': 34.96718810000001, 'lng': 135.7732651},
               'location_type': 'ROOFTOP',
               'viewport': {'northeast': {'lat': 34.96853708029151,
                                          'lng': 135.7746140802915},
                            'southwest': {'lat': 34.96583911970851,
                                          'lng': 135.7719161197085}}},
  'place_id': 'ChIJ7-v-BhUPAWAR3z0uXSNuPO8',
  'plus_code': {'compound_code': 'XQ8F+V8 Kyoto, Kyoto Prefecture, Japan',
                'global_code': '8Q6QXQ8F+V8'},
  'types': ['street_address']},
 {'address_components': ...以後省略

formatted_addressが住所情報で、構成する要素がaddress_componentsに格納されている。

取得できた住所は、8 Fukakusa Yabunouchichō, Fushimi-ku, Kyōto-shi, Kyōto-fu 612-0882, Japan
英語ではあるが、正しい住所情報を取得できた。

geoAPI

続いて、getAPIで日本語での住所情報も取得する。
APIのエンドポイントはhttp://geoapi.heartrails.com/api/json。ここにGETすればよい
必要なパラメータはこちら

パラメータ
method searchByGeoLocation(固定)
x 経度
y 緯度
>>> url = "http://geoapi.heartrails.com/api/json?method=searchByGeoLocation"
>>> params = {
...         "x": longitude,
...         "y": latitude
...     }
>>> import requests
>>> r = requests.get(url, params=params)
>>> pprint(r.json())
{'response': {'location': [{'city': '京都市伏見区',
                            'city_kana': 'きょうとしふしみく',
                            'distance': 71.82043454757451,
                            'postal': '6120882',
                            'prefecture': '京都府',
                            'town': '深草薮之内町',
                            'town_kana': 'ふかくさやぶのうちちょう',
                            'x': '135.772224',
                            'y': '34.967102'},
                           {'city': '京都市伏見区',
                            'city_kana': 'きょうとしふしみく',
                            'distance': 173.26500637918542,
                            'postal': '6120881',
                            'prefecture': '京都府',
                            'town': '深草稲荷御前町',
                            'town_kana': 'ふかくさいなりおんまえちょう',
                            'x': '135.771117',
                            'y': '34.967266'},
                           {'city': '京都市伏見区',
                            'city_kana': 'きょうとしふしみく',
                            'distance': 238.45040420335357,
                            'postal': '6120888',
                            'prefecture': '京都府',
                            'town': '深草大門町',
                            'town_kana': 'ふかくさだいもんちょう',
                            'x': '135.772471',
                            'y': '34.965043'},
                           {'city': '京都市伏見区',
                            'city_kana': 'きょうとしふしみく',
                            'distance': 247.53084931789914,
                            'postal': '6120807',
                            'prefecture': '京都府',
                            'town': '深草稲荷中之町',
                            'town_kana': 'ふかくさいなりなかのちょう',
                            'x': '135.77084',
                            'y': '34.968474'},
                           {'city': '京都市伏見区',
                            'city_kana': 'きょうとしふしみく',
                            'distance': 282.43664119023936,
                            'postal': '6120806',
                            'prefecture': '京都府',
                            'town': '深草開土町',
                            'town_kana': 'ふかくさかいどちょう',
                            'x': '135.773046',
                            'y': '34.969676'},
                           {'city': '京都市伏見区',
                            'city_kana': 'きょうとしふしみく',
                            'distance': 283.5300564540047,
                            'postal': '6120805',
                            'prefecture': '京都府',
                            'town': '深草開土口町',
                            'town_kana': 'ふかくさかいどぐちちょう',
                            'x': '135.774601',
                            'y': '34.969327'},
                           {'city': '京都市伏見区',
                            'city_kana': 'きょうとしふしみく',
                            'distance': 290.88767776536855,
                            'postal': '6120889',
                            'prefecture': '京都府',
                            'town': '深草直違橋十一丁目',
                            'town_kana': 'ふかくさすじかいばし11ちょうめ',
                            'x': '135.770897',
                            'y': '34.965182'},
                           {'city': '京都市伏見区',
                            'city_kana': 'きょうとしふしみく',
                            'distance': 311.7538119765497,
                            'postal': '6120013',
                            'prefecture': '京都府',
                            'town': '深草祓川町',
                            'town_kana': 'ふかくさはらいがわちょう',
                            'x': '135.769595',
                            'y': '34.967245'},
                           {'city': '京都市伏見区',
                            'city_kana': 'きょうとしふしみく',
                            'distance': 320.4272613869519,
                            'postal': '6120808',
                            'prefecture': '京都府',
                            'town': '深草稲荷榎木橋町',
                            'town_kana': 'ふかくさいなりえのきばしちょう',
                            'x': '135.770798',
                            'y': '34.969375'},
                           {'city': '京都市伏見区',
                            'city_kana': 'きょうとしふしみく',
                            'distance': 330.8874458592692,
                            'postal': '6120811',
                            'prefecture': '京都府',
                            'town': '深草笹山町',
                            'town_kana': 'ふかくさささやまちょう',
                            'x': '135.776632',
                            'y': '34.967298'}]}}

日本語での住所情報として、京都市伏見区深草薮之内町が取得できた。

最後に

個人開発した旅行写真紹介サイト【Where to Visit?】では、このAPI連携を利用して、写真の住所情報やランドマークを自動登録しているので、ぜひ見てみてください。

参照:GAE×DjangoでWebサービスを開発してみた

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
9
Help us understand the problem. What are the problem?