sketch-a-day/s305/bienal.py

190 wiersze
4.8 KiB
Python

import json
from collections import namedtuple
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
def http_get(url):
response = urlopen(url)
return response.read()
def get_deep_ai_caption_position(img_width, img_height, caption):
"""
Deep AI scales image limiting a max of 800 for height or width
Here we're reversing this scale so we can draw the boxes in the image
"""
scale = 1 / (float(800) / max(img_width, img_height))
box = caption['bounding_box']
top = int(box[0] * scale)
left = int(box[1] * scale)
right = int(left + box[3] * scale)
bottom = int(top + box[2] * scale)
return (top, left), (bottom, right)
AWS = namedtuple('AWS', ['faces', 'celebs', 'labels'])
IBM = namedtuple('IBM', ['faces', 'main'])
GOOGLE = namedtuple('Google', [
'web_detection',
'text_annotations',
'full_text_annotation',
'label_annotation',
'crop_hint_annotation',
'safe_search_annotation',
'image_properties_annotation',
])
AZURE = namedtuple('Azure', [
"faces",
"tags",
"adult",
"color",
"categories",
"description",
])
DEEP_AI = namedtuple('DeepAI', ['dense_cap'])
CLARIFAI = namedtuple('Clarifai', [
"nsfw",
"general",
"moderation",
"celebrities",
"demographics",
])
class ImageAnalysis():
"""
Holds an image dict and exposes it via an API
"""
def __init__(self, data):
self.data = data
def __getitem__(self, key):
return self.data[key]
@property
def aws(self):
data = self.data['amazonRekog']
return AWS(
data.get('faces', {}),
data.get('celebs', {}),
data.get('labels', {}),
)
@property
def ibm(self):
data = self.data['ibmwatson']
return IBM(
data.get('faces', {}),
data.get('main', {})
)
@property
def google(self):
data = self.data['googlecloud']
return GOOGLE(
data.get('webDetection', {}),
data.get('textAnnotations', {}),
data.get('fullTextAnnotation', {}),
data.get('labelAnnotations', {}),
data.get('cropHintsAnnotation', {}),
data.get('safeSearchAnnotation', {}),
data.get('imagePropertiesAnnotation', {}),
)
@property
def azure(self):
data = self.data['microsoftazure']['main']
return AZURE(
data.get('faces', {}),
data.get('tags', {}),
data.get('adult', {}),
data.get('color', {}),
data.get('categories', {}),
data.get('description', {}),
)
@property
def deep_ai(self):
return DEEP_AI(self.data['deepAi'].get('DenseCap', {}))
@property
def clarifai(self):
data = self.data['clarifai']
return CLARIFAI(
data.get('nsfw', {}),
data.get('general', {}),
data.get('moderation', {}),
data.get('celebrities', {}),
data.get('demographics', {}),
)
def __repr__(self):
return '<(Image) ID {} >'.format(self.data['pk'])
class Collection():
"""
Holds an image dict and exposes it via an API
"""
def __init__(self, data):
self.data = data
def __getitem__(self, key):
return self.data[key]
@property
def images(self):
if 'images' not in self.data:
api = ArtDecoderApi()
self.data = api.get_collection(self.data['id'])
return [ImageAnalysis(i) for i in self.data['images']]
def __repr__(self):
return '<(Collection) ID {} >'.format(self.data['id'])
class ArtDecoderApi():
HOST = 'art-decoder.bienal.berinfontes.com'
def _url(self, path, secure=True):
if secure:
protocol = 'https://'
else:
protocol = 'http://'
return protocol + self.HOST + path
def get_all_collections(self):
content = http_get(self._url('/api/collection'))
return json.loads(content)
def get_collection(self, col_id):
path = '/api/collection/{}'.format(col_id)
content = http_get(self._url(path))
return json.loads(content)
def get_collection_image(self, col_id, image_id):
path = '/api/collection/{}/image/{}'.format(col_id, image_id)
content = http_get(self._url(path))
return json.loads(content)
class BienalClient():
def __init__(self):
self.api = ArtDecoderApi()
def get_all_collections(self):
return [Collection(c) for c in self.api.get_all_collections()]
def get_collection(self, col_id):
return Collection(self.api.get_collection(col_id))
def get_collection_image(self, col_id, image_id):
return ImageAnalysis(self.api.get_collection_image(col_id, image_id))