kopia lustrzana https://github.com/villares/sketch-a-day
190 wiersze
4.8 KiB
Python
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))
|