154 lines
No EOL
4.2 KiB
Python
154 lines
No EOL
4.2 KiB
Python
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': 'zelfgenoegzaamheid',
|
|
'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 |