from peewee import * from playhouse.sqlite_ext import SqliteExtDatabase import datetime import json import numpy as np def coloursToJson(colours): colours2 = [(list(colour[0]), colour[1]) for colour in colours] return json.dumps(colours2) def jsonToColours(string): data = json.loads(string) return [(np.array(d[0]), d[1]) for d in data] db = SqliteExtDatabase('images.db') class ColoursField(TextField): # db_field = 'colour' def db_value(self, value): if value is None: return None return coloursToJson(value) def python_value(self, value): if value is None: return None return jsonToColours(value) class JsonField(TextField): # db_field = 'colour' def db_value(self, value): if value is None: return None return json.dumps(value) def python_value(self, value): if value is None: return None return json.loads(value) class BaseModel(Model): class Meta: database = db class Emotion(BaseModel): name = CharField(unique=True) class Group(BaseModel): name = CharField(unique=True) class Artwork(BaseModel): author = CharField(null=True) age = SmallIntegerField(index=True, null=True) gender = FixedCharField(max_length=1, null=True) # we should not really use this one group = ForeignKeyField(Group, related_name='artworks', index=True) emotion = ForeignKeyField(Emotion, related_name='artworks', index=True) created_date = DateTimeField(default=datetime.datetime.now) filename = CharField() width = IntegerField(null=True) height = IntegerField(null=True) colours = ColoursField(null=True) # serialised colours + percentages: [([r,g,b], percentage), ...] faces = JsonField(null=True) # Serialised MS data def getThumbPath(self): return 'thumbs/%s.jpg' % self.id def getAges(): r = Artwork.select(fn.Distinct(Artwork.age)).dicts() return [a['age'] for a in r] def getEmotionCountsFromArtworks(artworks): emotions = {} for artwork in artworks: e = artwork.emotion.name if e == 'onbekend': continue if e in emotions: emotions[e] += 1 else: emotions[e] = 1 return emotions def getEmotionFractionsFromArtworks(artworks): emotions = getEmotionCountsFromArtworks(artworks) total = sum(emotions.values()) for e in emotions: emotions[e] = emotions[e] / total return emotions def getAgeFractionsFromArtworks(artworks): ages = {} for artwork in artworks: age = artwork.age if age in ages: ages[age] += 1 else: ages[age] = 1 total = sum(ages.values()) for age in ages: ages[age] = ages[age] / total return ages def getGroupFractionsFromArtworks(artworks): groups = {} for artwork in artworks: group = artwork.group.name if group in groups: groups[group] += 1 else: groups[group] = 1 total = sum(groups.values()) for group in groups: groups[group] = groups[group] / total return groups emotionTranslations = { 'anger': 'boos', 'contempt': 'minachting', 'disgust': 'walging', 'fear': 'angst', 'happiness': 'geluk', 'surprise': 'verbazing', 'sadness': 'verdriet', 'neutral': 'neutraal', } def getFaceFractionsFromArtworks(artworks): emotions = {} for artwork in artworks: if artwork.faces is None or len(artwork.faces) < 1: continue for face in artwork.faces: for emotion, score in face['scores'].items(): if emotion in emotions: emotions[emotion] += score else: emotions[emotion] = score total = sum(emotions.values()) defEmotions = {} for emotion in emotions: emotions[emotion] = emotions[emotion] / total if emotions[emotion] > .02: defEmotions[emotionTranslations[emotion]] = emotions[emotion] total = sum(defEmotions.values()) for emotion in defEmotions: defEmotions[emotion] = defEmotions[emotion] / total return defEmotions