Add subtractions and auto updating
This commit is contained in:
parent
74470e61b3
commit
ce7dfc28ea
5 changed files with 486 additions and 319 deletions
|
@ -4,6 +4,7 @@ import tornado.ioloop
|
||||||
import os
|
import os
|
||||||
|
|
||||||
web_dir = os.path.join(os.path.split(__file__)[0], 'www')
|
web_dir = os.path.join(os.path.split(__file__)[0], 'www')
|
||||||
|
output_dir = os.path.join(os.path.split(__file__)[0], 'output')
|
||||||
|
|
||||||
# This is our WebSocketHandler - it handles the messages
|
# This is our WebSocketHandler - it handles the messages
|
||||||
# from the tornado server
|
# from the tornado server
|
||||||
|
@ -27,6 +28,7 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
||||||
|
|
||||||
application = tornado.web.Application([
|
application = tornado.web.Application([
|
||||||
(r"/ws", WebSocketHandler),
|
(r"/ws", WebSocketHandler),
|
||||||
|
(r"/output/(.*)", tornado.web.StaticFileHandler, {"path": output_dir}),
|
||||||
(r"/(.*)", tornado.web.StaticFileHandler, {"path": web_dir, "default_filename": 'index.html'}),
|
(r"/(.*)", tornado.web.StaticFileHandler, {"path": web_dir, "default_filename": 'index.html'}),
|
||||||
],debug=True)
|
],debug=True)
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,9 @@ from websocket import create_connection
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
logger = logging.getLogger('portraits')
|
||||||
|
|
||||||
camera = picamera.PiCamera()
|
camera = picamera.PiCamera()
|
||||||
camera.rotation = 180
|
camera.rotation = 180
|
||||||
camera.resolution = (1920, 1080)
|
camera.resolution = (1920, 1080)
|
||||||
|
@ -24,6 +27,8 @@ outputResolution = (1000, 1000)
|
||||||
genders = ['male', 'female', 'unknown']
|
genders = ['male', 'female', 'unknown']
|
||||||
perspectives = ['side', 'front']
|
perspectives = ['side', 'front']
|
||||||
gender_perspectives = [g+"_"+p for p in perspectives for g in genders]
|
gender_perspectives = [g+"_"+p for p in perspectives for g in genders]
|
||||||
|
# we also want dedicated composites for the perspectives
|
||||||
|
gender_perspectives.extend(perspectives)
|
||||||
|
|
||||||
curdir = os.path.dirname(os.path.abspath(__file__))
|
curdir = os.path.dirname(os.path.abspath(__file__))
|
||||||
tmpimage = '/tmp/piimage.jpg'
|
tmpimage = '/tmp/piimage.jpg'
|
||||||
|
@ -42,6 +47,8 @@ environment = {
|
||||||
'LD_PRELOAD': '/usr/lib/arm-linux-gnueabihf/libopencv_core.so.2.4',
|
'LD_PRELOAD': '/usr/lib/arm-linux-gnueabihf/libopencv_core.so.2.4',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateGoesOk = True;
|
||||||
|
|
||||||
def updateStats(type, name, count, image_filename):
|
def updateStats(type, name, count, image_filename):
|
||||||
params = {
|
params = {
|
||||||
'type': type,
|
'type': type,
|
||||||
|
@ -49,35 +56,41 @@ def updateStats(type, name, count, image_filename):
|
||||||
'time': int(time.time()),
|
'time': int(time.time()),
|
||||||
'case_count': int(count),
|
'case_count': int(count),
|
||||||
}
|
}
|
||||||
try:
|
# try:
|
||||||
ws = create_connection("ws://localhost:8888/ws")
|
# ws = create_connection("ws://localhost:8888/ws")
|
||||||
js = json.dumps({
|
# js = json.dumps({
|
||||||
'type': type,
|
# 'type': type,
|
||||||
'name': name,
|
# 'name': name,
|
||||||
'img_src': os.path.basename(image_filename),
|
# 'img_src': os.path.basename(image_filename),
|
||||||
'case_count': int(count),
|
# 'case_count': int(count),
|
||||||
})
|
# })
|
||||||
ws.send(js)
|
# ws.send(js)
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
raise
|
# raise
|
||||||
|
|
||||||
url = 'https://artstats.rubenvandeven.com/composites/views.php'
|
url = 'https://artstats.rubenvandeven.com/composites/views.php'
|
||||||
|
try:
|
||||||
if count % 10 == 0:
|
if count % 10 == 0:
|
||||||
# only send every one in x image, so that the server never can
|
# only send every one in x image, so that the server never can
|
||||||
# retrace _exact_ faces by comparing the sent frames.
|
# retrace _exact_ faces by comparing the sent frames.
|
||||||
with open(image_filename) as fp:
|
with open(image_filename) as fp:
|
||||||
print('send request including image')
|
logger.info('send request including image')
|
||||||
r = requests.post(
|
r = requests.post(
|
||||||
url ,
|
url ,
|
||||||
files={'image': fp},
|
files={'image': fp},
|
||||||
params=params
|
params=params
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print('send request')
|
logger.info('send request')
|
||||||
r = requests.post(
|
r = requests.post(
|
||||||
url,
|
url,
|
||||||
params=params
|
params=params
|
||||||
)
|
)
|
||||||
|
updateGoesOk = True
|
||||||
|
except Exception as e:
|
||||||
|
updateGoesOk = False
|
||||||
|
logger.critical("Error when updating statistics")
|
||||||
|
logger.exception(e)
|
||||||
|
|
||||||
class CompositeImage:
|
class CompositeImage:
|
||||||
def __init__(self, name, resolution):
|
def __init__(self, name, resolution):
|
||||||
|
@ -102,7 +115,7 @@ class CompositeImage:
|
||||||
self.count = i
|
self.count = i
|
||||||
name = self.get_frame_filename(self.count)
|
name = self.get_frame_filename(self.count)
|
||||||
img_file = os.path.join(dir, name)
|
img_file = os.path.join(dir, name)
|
||||||
print("\trestore {}".format(img_file))
|
logger.info("\trestore {}".format(img_file))
|
||||||
self.image = np.array(Image.open(img_file)).astype('float64')
|
self.image = np.array(Image.open(img_file)).astype('float64')
|
||||||
self.state_dirty = False
|
self.state_dirty = False
|
||||||
|
|
||||||
|
@ -112,12 +125,15 @@ class CompositeImage:
|
||||||
def get_frame_filename(self, i):
|
def get_frame_filename(self, i):
|
||||||
return "{}-{}x{}-{}.png".format(self.name, self.resolution[0], self.resolution[1], i)
|
return "{}-{}x{}-{}.png".format(self.name, self.resolution[0], self.resolution[1], i)
|
||||||
|
|
||||||
|
def get_current_filename(self):
|
||||||
|
return self.get_frame_filename(self.count)
|
||||||
|
|
||||||
def save_image(self, dir):
|
def save_image(self, dir):
|
||||||
if self.state_dirty is False:
|
if self.state_dirty is False:
|
||||||
|
# don't save if no changes are made since last save
|
||||||
return
|
return
|
||||||
|
|
||||||
name = self.get_frame_filename(self.count)
|
name = self.get_current_filename()
|
||||||
filename = os.path.join(dir, name)
|
filename = os.path.join(dir, name)
|
||||||
self.get_image().save(filename)
|
self.get_image().save(filename)
|
||||||
|
|
||||||
|
@ -140,6 +156,9 @@ class CompositeCollection:
|
||||||
def get_pickle_filename(self):
|
def get_pickle_filename(self):
|
||||||
return os.path.join(self.target_dir, self.id + ".p")
|
return os.path.join(self.target_dir, self.id + ".p")
|
||||||
|
|
||||||
|
def get_json_filename(self):
|
||||||
|
return os.path.join(self.target_dir, "composites.json")
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
pickle_file_name = self.get_pickle_filename()
|
pickle_file_name = self.get_pickle_filename()
|
||||||
# if os.path.exists(pickle_file_name):
|
# if os.path.exists(pickle_file_name):
|
||||||
|
@ -151,7 +170,7 @@ class CompositeCollection:
|
||||||
composites[name] = CompositeImage(name, self.size)
|
composites[name] = CompositeImage(name, self.size)
|
||||||
composites[name].restore( data['c'][name], self.target_dir)
|
composites[name].restore( data['c'][name], self.target_dir)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Create new composite", e)
|
logger.info("Create new composite", e)
|
||||||
for name in self.names:
|
for name in self.names:
|
||||||
composites[name] = CompositeImage(name, self.size)
|
composites[name] = CompositeImage(name, self.size)
|
||||||
|
|
||||||
|
@ -163,9 +182,31 @@ class CompositeCollection:
|
||||||
data['c'][name] = self.composites[name].count
|
data['c'][name] = self.composites[name].count
|
||||||
|
|
||||||
with open( self.get_pickle_filename(), "wb" ) as fp:
|
with open( self.get_pickle_filename(), "wb" ) as fp:
|
||||||
print("Save", data)
|
logger.info("Save", data)
|
||||||
pickle.dump( data, fp )
|
pickle.dump( data, fp )
|
||||||
|
|
||||||
|
self.save_json()
|
||||||
|
|
||||||
|
def save_json(self):
|
||||||
|
"""
|
||||||
|
Save statistics as json
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
for name in self.composites:
|
||||||
|
data[name] = {
|
||||||
|
'count': self.composites[name].count,
|
||||||
|
'img': self.composites[name].get_current_filename()
|
||||||
|
}
|
||||||
|
|
||||||
|
with open( self.get_json_filename(), "w" ) as fp:
|
||||||
|
logger.debug("Json to {}".format(self.get_json_filename()))
|
||||||
|
json.dump(data, fp)
|
||||||
|
|
||||||
|
ws = create_connection("ws://localhost:8888/ws")
|
||||||
|
ws.send("update")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def save_img(self, name):
|
def save_img(self, name):
|
||||||
self.get(name).save_image(self.target_dir)
|
self.get(name).save_image(self.target_dir)
|
||||||
|
|
||||||
|
@ -192,19 +233,22 @@ class CompositeCollection:
|
||||||
for i in range(start, end):
|
for i in range(start, end):
|
||||||
filename = os.path.join(self.target_dir, c.get_frame_filename(i))
|
filename = os.path.join(self.target_dir, c.get_frame_filename(i))
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
print("Clean {}".format(filename))
|
logger.info("Clean {}".format(filename))
|
||||||
os.unlink(filename)
|
os.unlink(filename)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def append_face(row, image, composites):
|
def append_face(row, image, composites):
|
||||||
# degrees to distinguish side (as we will never be able to use 90 :-( )
|
# degrees to distinguish side (as we will never be able to use 90 :-( )
|
||||||
suffix = 'side' if abs(float(row['yaw'])) > 20 else 'front'
|
# Plus, we now have a wide angle lens.
|
||||||
# print('yaw:', float(row['yaw']))
|
suffix = 'side' if abs(float(row['yaw'])) > 12 else 'front'
|
||||||
name = "{}_{}".format(row['gender'], suffix)
|
names = [suffix, "{}_{}".format(row['gender'], suffix)]
|
||||||
|
|
||||||
|
compositesToUse = []
|
||||||
|
for name in names:
|
||||||
if name not in composites.names:
|
if name not in composites.names:
|
||||||
return
|
return
|
||||||
composite = composites.get(name)
|
compositesToUse.append(composites.get(name))
|
||||||
|
|
||||||
# TODO: matrix transform the image, to skew the face into being a flat-ish surface
|
# TODO: matrix transform the image, to skew the face into being a flat-ish surface
|
||||||
# This might yield less blurry composites
|
# This might yield less blurry composites
|
||||||
|
@ -228,16 +272,17 @@ def append_face(row, image, composites):
|
||||||
# PIL.Image handles cropping outside the canvas by filling with black/transparent
|
# PIL.Image handles cropping outside the canvas by filling with black/transparent
|
||||||
x = face_x + dx
|
x = face_x + dx
|
||||||
y = face_y + dy
|
y = face_y + dy
|
||||||
print('crop')
|
logger.debug('crop')
|
||||||
i = image.crop((x,y, x + size_x, y + size_y))
|
i = image.crop((x,y, x + size_x, y + size_y))
|
||||||
|
|
||||||
if suffix == 'side' and float(row['yaw']) < 0:
|
if suffix == 'side' and float(row['yaw']) < 0:
|
||||||
print('\tflip')
|
logger.debug('\tflip')
|
||||||
i = i.transpose(Image.FLIP_LEFT_RIGHT)
|
i = i.transpose(Image.FLIP_LEFT_RIGHT)
|
||||||
|
|
||||||
print('add')
|
for composite in compositesToUse:
|
||||||
|
logger.debug('add')
|
||||||
composite.addFace(i)
|
composite.addFace(i)
|
||||||
print('added')
|
logger.debug('added')
|
||||||
|
|
||||||
composites = CompositeCollection(gender_perspectives, outputResolution, os.path.join(curdir, 'output'))
|
composites = CompositeCollection(gender_perspectives, outputResolution, os.path.join(curdir, 'output'))
|
||||||
|
|
||||||
|
@ -250,7 +295,7 @@ while True:
|
||||||
img = Image.open(tmpimage)
|
img = Image.open(tmpimage)
|
||||||
os.unlink(tmpimage)
|
os.unlink(tmpimage)
|
||||||
with open(tmpimageResults) as csvfile:
|
with open(tmpimageResults) as csvfile:
|
||||||
print("open csv")
|
logger.debug("open csv")
|
||||||
data = csv.DictReader(csvfile)
|
data = csv.DictReader(csvfile)
|
||||||
faces = 0
|
faces = 0
|
||||||
for row in data:
|
for row in data:
|
||||||
|
@ -258,15 +303,14 @@ while True:
|
||||||
# not a valid face
|
# not a valid face
|
||||||
continue
|
continue
|
||||||
faces += 1
|
faces += 1
|
||||||
print("append face")
|
logger.info("append face")
|
||||||
append_face(row, img, composites)
|
append_face(row, img, composites)
|
||||||
|
|
||||||
if faces > 0:
|
if faces > 0:
|
||||||
print("save :-)")
|
logger.info("save :-)")
|
||||||
for name in composites.names:
|
for name in composites.names:
|
||||||
print("\tsave img '{}'".format(name))
|
logger.info("\tsave img '{}'".format(name))
|
||||||
c = composites.save_img(name)
|
c = composites.save_img(name)
|
||||||
# save pickle after images, so they can be restored
|
# save pickle after images, so they can be restored
|
||||||
composites.save()
|
composites.save()
|
||||||
composites.clean()
|
composites.clean()
|
||||||
# TODO: trigger output update
|
|
||||||
|
|
100
www/composite_loader.js
Normal file
100
www/composite_loader.js
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
class Face {
|
||||||
|
constructor(id) {
|
||||||
|
this.id = id;
|
||||||
|
this.value = 0;
|
||||||
|
// this.name = name;
|
||||||
|
this.imgEls = [];
|
||||||
|
this.valueEls = [];
|
||||||
|
|
||||||
|
let els = document.querySelectorAll(`[data-face='${this.id}']`);
|
||||||
|
for(let el of els) {
|
||||||
|
if(el.tagName == 'IMG') {
|
||||||
|
this.imgEls.push(el);
|
||||||
|
} else {
|
||||||
|
this.valueEls.push(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addImgEl(el) {
|
||||||
|
this.imgEls.push(el)
|
||||||
|
}
|
||||||
|
|
||||||
|
addValueEl(el) {
|
||||||
|
this.valueEls.push(el)
|
||||||
|
}
|
||||||
|
|
||||||
|
update(imgUrl, value) {
|
||||||
|
for(let el of this.valueEls) {
|
||||||
|
el.textContent = new Intl.NumberFormat("nl").format(value);
|
||||||
|
}
|
||||||
|
for(let el of this.imgEls) {
|
||||||
|
el.src = imgUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bar {
|
||||||
|
constructor(el) {
|
||||||
|
this.el = el;
|
||||||
|
this.values = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
setValue(id, value) {
|
||||||
|
this.values[id] = value;
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
for(let id in this.values) {
|
||||||
|
let el = document.getElementById('graph--' + id);
|
||||||
|
if(!el) continue;
|
||||||
|
|
||||||
|
let nrEls = el.getElementsByClassName('nr');
|
||||||
|
for(let nrEl of nrEls) {
|
||||||
|
nrEl.textContent = new Intl.NumberFormat("nl").format(this.values[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
el.style.flex = parseInt(this.values[id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var bar = new Bar(document.getElementById('graph'));
|
||||||
|
|
||||||
|
var faces = {
|
||||||
|
'front': new Face('front'),
|
||||||
|
'side': new Face('side'),
|
||||||
|
'male_front': new Face('male_front'),
|
||||||
|
'female_front': new Face('female_front'),
|
||||||
|
'unknown_front': new Face('unknown_front'),
|
||||||
|
'male_side': new Face('male_side'),
|
||||||
|
'female_side': new Face('female_side'),
|
||||||
|
'unknown_side': new Face('unknown_side')
|
||||||
|
}
|
||||||
|
|
||||||
|
var update = function() {
|
||||||
|
let req = new XMLHttpRequest();
|
||||||
|
req.addEventListener("load", function(e){
|
||||||
|
let data = JSON.parse(this.responseText);
|
||||||
|
console.log(data);
|
||||||
|
for(let name in data){
|
||||||
|
faces[name].update('/output/'+data[name]['img'], data[name]['count']);
|
||||||
|
}
|
||||||
|
|
||||||
|
bar.setValue('male', data['male_front']['count'] + data['male_side']['count'])
|
||||||
|
bar.setValue('female', data['female_front']['count'] + data['female_side']['count'])
|
||||||
|
bar.setValue('unknown', data['unknown_front']['count'] + data['unknown_side']['count'])
|
||||||
|
});
|
||||||
|
req.open("GET", "/output/composites.json?v=" + Date.now());
|
||||||
|
req.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
var socket = new ReconnectingWebSocket("ws://"+window.location.hostname+":"+window.location.port+"/ws")
|
||||||
|
socket.addEventListener('message', function (event) {
|
||||||
|
//trigger update
|
||||||
|
update();
|
||||||
|
});
|
||||||
|
|
||||||
|
update();
|
353
www/index.html
353
www/index.html
|
@ -9,291 +9,164 @@
|
||||||
<h1>Specimens <span class='of'>of</span> Discriminatory Composite Portraiture</h1>
|
<h1>Specimens <span class='of'>of</span> Discriminatory Composite Portraiture</h1>
|
||||||
<section id='gender'>
|
<section id='gender'>
|
||||||
<h2>Gender Differentiation<span class='star'>*</span></h2>
|
<h2>Gender Differentiation<span class='star'>*</span></h2>
|
||||||
|
<div class='gender-wrap'>
|
||||||
<div class='genders'>
|
<div class='genders'>
|
||||||
|
<div id="front">
|
||||||
|
<div class='composite' id="front--f">
|
||||||
|
<img data-face="female_front" src="unknown_side-1000x1000-3.png">
|
||||||
|
<div class='cases'><span class='type'>female</span> <span class='cases--nr' data-face="female_front">12.320</span> cases</div>
|
||||||
|
</div>
|
||||||
|
<div class='composite' id="front--u">
|
||||||
|
<img data-face="unknown_front" src="unknown_side-1000x1000-3.png">
|
||||||
|
<div class='cases'><span class='type'>unknown</span> <span class='cases--nr' data-face="unknown_front">100</span> cases</div>
|
||||||
|
</div>
|
||||||
|
<div class='composite' id="front--m">
|
||||||
|
<img data-face="male_front" src="unknown_side-1000x1000-3.png">
|
||||||
|
<div class='cases'><span class='type'>male</span> <span class='cases--nr' data-face="male_front">120</span> cases</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="general">
|
||||||
|
<div class='composite' id="side--composite">
|
||||||
|
<img data-face="side" src="unknown_side-1000x1000-3.png">
|
||||||
|
<div class='cases'><span class='cases--nr' data-face="side">100</span> side faces</div>
|
||||||
|
</div>
|
||||||
|
<div class='composite' id="front--composite">
|
||||||
|
<img data-face="front" src="unknown_side-1000x1000-3.png">
|
||||||
|
<div class='cases'><span class='cases--nr' data-face="front">100</span> front faces</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="side">
|
||||||
|
<div class='composite' id="side--m">
|
||||||
|
<img data-face="male_side" src="unknown_side-1000x1000-3.png">
|
||||||
|
<div class='cases'><span class='type'>male</span> <span class='cases--nr' data-face="male_side">120</span> cases</div>
|
||||||
|
</div>
|
||||||
|
<div class='composite' id="side--u">
|
||||||
|
<img data-face="unknown_side" src="unknown_side-1000x1000-3.png">
|
||||||
|
<div class='cases'><span class='type'>unknown</span> <span class='cases--nr' data-face="unknown_side">100</span> cases</div>
|
||||||
|
</div>
|
||||||
|
<div class='composite' id="side--f">
|
||||||
|
<img data-face="female_side" src="unknown_side-1000x1000-3.png">
|
||||||
|
<div class='cases'><span class='type'>female</span> <span class='cases--nr' data-face="female_side">12.320</span> cases</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<svg
|
<svg
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
id="lines--front"
|
||||||
id="svg954"
|
|
||||||
version="1.1"
|
version="1.1"
|
||||||
viewBox="0 0 269.68921 171.03902"
|
viewBox="0 0 59.548019 116.38292"
|
||||||
height="171.03902mm"
|
height="116.38292mm"
|
||||||
width="249.68921mm">
|
width="59.548019mm">
|
||||||
<defs
|
|
||||||
id="defs948" />
|
|
||||||
<g
|
<g
|
||||||
transform="translate(-479.74467,99.971886)"
|
transform="translate(679.89306,124.0486)"
|
||||||
id="layer1">
|
id="layer1">
|
||||||
<path
|
|
||||||
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
d="m 707.56274,47.386401 c -39.08004,0 -26.35353,-98.175942 -59.54802,-98.175942"
|
|
||||||
id="path919" />
|
|
||||||
<path
|
|
||||||
id="path921"
|
|
||||||
d="m 707.56274,-67.970339 c -39.08004,0 -26.35353,17.180798 -59.54802,17.180798"
|
|
||||||
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
|
||||||
<path
|
|
||||||
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
||||||
d="m 707.56274,-8.6440273 c -39.08004,0 -26.35353,-42.1455137 -59.54802,-42.1455137"
|
|
||||||
id="path923" />
|
|
||||||
<path
|
<path
|
||||||
id="path836"
|
id="path836"
|
||||||
d="m 540.57238,-79.730199 c 70.83004,0 26.35353,98.17594 59.54801,98.17594"
|
d="m -679.89306,-123.53551 c 70.83005,0 26.35353,98.175937 59.54802,98.175937"
|
||||||
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
<path
|
<path
|
||||||
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
d="m 540.57238,35.626541 c 39.08004,0 26.35352,-17.1808 59.54801,-17.1808"
|
d="m -679.89306,-8.1787728 c 39.08005,0 26.35353,-17.1808002 59.54802,-17.1808002"
|
||||||
id="path838" />
|
id="path838" />
|
||||||
<path
|
<path
|
||||||
id="path840"
|
id="path840"
|
||||||
d="m 540.57238,-23.699793 c 39.08004,0 26.35352,42.145534 59.54801,42.145534"
|
d="m -679.89306,-67.505107 c 39.08005,0 26.35353,42.145534 59.54802,42.145534"
|
||||||
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
<image
|
|
||||||
y="-98.78492"
|
|
||||||
x="488.05942"
|
|
||||||
id="image826"
|
|
||||||
xlink:href="unknown_side-1000x1000-3.png"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
height="51.730377"
|
|
||||||
width="51.730377" />
|
|
||||||
<use
|
|
||||||
height="100%"
|
|
||||||
width="100%"
|
|
||||||
transform="translate(-4.5528998e-7,57.022051)"
|
|
||||||
id="use828"
|
|
||||||
xlink:href="#image826"
|
|
||||||
y="0"
|
|
||||||
x="0" />
|
|
||||||
<use
|
|
||||||
height="100%"
|
|
||||||
width="100%"
|
|
||||||
transform="translate(-4.5528998e-7,58.005791)"
|
|
||||||
id="use830"
|
|
||||||
xlink:href="#use828"
|
|
||||||
y="0"
|
|
||||||
x="0" />
|
|
||||||
<image
|
|
||||||
width="49.769428"
|
|
||||||
height="49.769428"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
xlink:href="unknown_side-1000x1000-3.png"
|
|
||||||
id="use834"
|
|
||||||
x="597.66241"
|
|
||||||
y="-20.339062" />
|
|
||||||
<image
|
|
||||||
width="53.440414"
|
|
||||||
height="53.440414"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
xlink:href="unknown_side-1000x1000-3.png"
|
|
||||||
id="image910"
|
|
||||||
x="687.51868"
|
|
||||||
y="-99.971886" />
|
|
||||||
<image
|
|
||||||
y="-41.172611"
|
|
||||||
x="687.51868"
|
|
||||||
id="image913"
|
|
||||||
xlink:href="unknown_side-1000x1000-3.png"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
height="53.440414"
|
|
||||||
width="53.440414" />
|
|
||||||
<image
|
|
||||||
width="53.440414"
|
|
||||||
height="53.440414"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
xlink:href="unknown_side-1000x1000-3.png"
|
|
||||||
id="image915"
|
|
||||||
x="687.51868"
|
|
||||||
y="17.626713" />
|
|
||||||
<image
|
|
||||||
width="49.769428"
|
|
||||||
height="51.32375"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
xlink:href="unknown_side-1000x1000-3.png"
|
|
||||||
id="image917"
|
|
||||||
x="597.66241"
|
|
||||||
y="-82.246162" />
|
|
||||||
<text
|
|
||||||
id="text927"
|
|
||||||
y="63.765812"
|
|
||||||
x="542.91345"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:5.96850729px;line-height:1.25;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:var(--primary-color);fill-opacity:1;stroke:none;stroke-width:0.14921269"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:5.96850729px;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.14921269"
|
|
||||||
y="63.765812"
|
|
||||||
x="542.91345"
|
|
||||||
id="tspan925">20 cases</tspan></text>
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:0.80000001;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:var(--primary-color);fill-opacity:1;stroke:none;stroke-width:0.18306924"
|
|
||||||
x="541.38544"
|
|
||||||
y="1.2943537"
|
|
||||||
id="text931"><tspan
|
|
||||||
id="tspan929"
|
|
||||||
x="541.38544"
|
|
||||||
y="1.2943537"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:0.80000001;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.18306924">1.200</tspan><tspan
|
|
||||||
id="tspan939"
|
|
||||||
x="541.38544"
|
|
||||||
y="7.1525693"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:0.80000001;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.18306924">cases</tspan></text>
|
|
||||||
<text
|
|
||||||
id="text935"
|
|
||||||
y="-48.44733"
|
|
||||||
x="540.32709"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:1.25;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:var(--primary-color);fill-opacity:1;stroke:none;stroke-width:0.18306924"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.18306924"
|
|
||||||
y="-48.44733"
|
|
||||||
x="540.32709"
|
|
||||||
id="tspan933">120 cases</tspan></text>
|
|
||||||
<path
|
|
||||||
id="path937"
|
|
||||||
d="M 540.57238,-79.730199 Z"
|
|
||||||
style="fill:none;stroke:var(--primary-color);stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:1.25;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:var(--primary-color);fill-opacity:1;stroke:none;stroke-width:0.18306924"
|
|
||||||
x="603.58911"
|
|
||||||
y="37.606449"
|
|
||||||
id="text972"><tspan
|
|
||||||
id="tspan970"
|
|
||||||
x="603.58911"
|
|
||||||
y="37.606449"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.18306924">1.340 cases</tspan></text>
|
|
||||||
<text
|
|
||||||
id="text976"
|
|
||||||
y="-24.546719"
|
|
||||||
x="608.34381"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:1.25;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:var(--primary-color);fill-opacity:1;stroke:none;stroke-width:0.18306924"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.18306924"
|
|
||||||
y="-24.546719"
|
|
||||||
x="608.34381"
|
|
||||||
id="tspan974">800 cases</tspan></text>
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:1.25;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:var(--primary-color);fill-opacity:1;stroke:none;stroke-width:0.18306924"
|
|
||||||
x="479.47293"
|
|
||||||
y="-66.438972"
|
|
||||||
id="text1006"><tspan
|
|
||||||
id="tspan1004"
|
|
||||||
x="479.47293"
|
|
||||||
y="-66.438972"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.18306924">M</tspan></text>
|
|
||||||
<text
|
|
||||||
id="text1010"
|
|
||||||
y="-13.522312"
|
|
||||||
x="480.53125"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:1.25;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:var(--primary-color);fill-opacity:1;stroke:none;stroke-width:0.18306924"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.18306924"
|
|
||||||
y="-13.522312"
|
|
||||||
x="480.53125"
|
|
||||||
id="tspan1008">F</tspan></text>
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:1.25;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:var(--primary-color);fill-opacity:1;stroke:none;stroke-width:0.18306924"
|
|
||||||
x="481.06042"
|
|
||||||
y="44.686024"
|
|
||||||
id="text1014"><tspan
|
|
||||||
id="tspan1012"
|
|
||||||
x="481.06042"
|
|
||||||
y="44.686024"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.18306924">?</tspan></text>
|
|
||||||
<text
|
|
||||||
id="text1018"
|
|
||||||
y="-66.438972"
|
|
||||||
x="742.99786"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:1.25;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:var(--primary-color);fill-opacity:1;stroke:none;stroke-width:0.18306924"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.18306924"
|
|
||||||
y="-66.438972"
|
|
||||||
x="742.99786"
|
|
||||||
id="tspan1016">M</tspan></text>
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:1.25;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:var(--primary-color);fill-opacity:1;stroke:none;stroke-width:0.18306924"
|
|
||||||
x="744.05621"
|
|
||||||
y="-13.522312"
|
|
||||||
id="text1022"><tspan
|
|
||||||
id="tspan1020"
|
|
||||||
x="744.05621"
|
|
||||||
y="-13.522312"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.18306924">F</tspan></text>
|
|
||||||
<text
|
|
||||||
id="text1026"
|
|
||||||
y="44.686024"
|
|
||||||
x="744.58539"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;line-height:1.25;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:var(--primary-color);fill-opacity:1;stroke:none;stroke-width:0.18306924"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:7.32276964px;font-family:'CMU Serif';-inkscape-font-specification:'CMU Serif, Medium';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.18306924"
|
|
||||||
y="44.686024"
|
|
||||||
x="744.58539"
|
|
||||||
id="tspan1024">?</tspan></text>
|
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
id="lines--side"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 59.548019 116.38292"
|
||||||
|
height="116.38292mm"
|
||||||
|
width="59.548019mm">
|
||||||
|
<g
|
||||||
|
transform="translate(679.89306,124.0486)"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
id="path836"
|
||||||
|
d="m -679.89306,-123.53551 c 70.83005,0 26.35353,98.175937 59.54802,98.175937"
|
||||||
|
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m -679.89306,-8.1787728 c 39.08005,0 26.35353,-17.1808002 59.54802,-17.1808002"
|
||||||
|
id="path838" />
|
||||||
|
<path
|
||||||
|
id="path840"
|
||||||
|
d="m -679.89306,-67.505107 c 39.08005,0 26.35353,42.145534 59.54802,42.145534"
|
||||||
|
style="fill:none;stroke:var(--primary-color);stroke-width:1.02617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section id='differences'>
|
<section id='differences'>
|
||||||
<div class='gender'>
|
<div>
|
||||||
<h2>Distinctive traits</h2>
|
<div class='gender explanation'>
|
||||||
|
<!-- <p>Distinctive traits</p> -->
|
||||||
|
<h3>composite subtraction</h3>
|
||||||
|
<p>An examination of discriminatory traits in gender differentation.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class='gender'>
|
<div class='gender'>
|
||||||
<img src="unknown_side-1000x1000-3.png"><img src="unknown_side-1000x1000-3.png">
|
<div class='diff-layer'>
|
||||||
|
<img data-face="male_front" src="unknown_side-1000x1000-3.png"><img data-face="male_side" src="unknown_side-1000x1000-3.png">
|
||||||
|
</div>
|
||||||
|
<div class='original-layer'>
|
||||||
|
<img data-face="front" src="unknown_side-1000x1000-3.png"><img data-face="side" src="unknown_side-1000x1000-3.png">
|
||||||
|
</div>
|
||||||
|
<div class='label'>Male</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class='gender'>
|
||||||
|
<div class='diff-layer'>
|
||||||
|
<img data-face="unknown_front" src="unknown_side-1000x1000-3.png"><img data-face="unknown_side" src="unknown_side-1000x1000-3.png">
|
||||||
|
</div>
|
||||||
|
<div class='original-layer'>
|
||||||
|
<img data-face="front" src="unknown_side-1000x1000-3.png"><img data-face="side" src="unknown_side-1000x1000-3.png">
|
||||||
|
</div>
|
||||||
|
<div class='label'>Unknown</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='gender'>
|
<div class='gender'>
|
||||||
<img src="unknown_side-1000x1000-3.png"><img src="unknown_side-1000x1000-3.png">
|
<div class='diff-layer'>
|
||||||
|
<img data-face="female_front" src="unknown_side-1000x1000-3.png"><img data-face="female_side" src="unknown_side-1000x1000-3.png">
|
||||||
</div>
|
</div>
|
||||||
<div class='gender'>
|
<div class='original-layer'>
|
||||||
<img src="unknown_side-1000x1000-3.png"><img src="unknown_side-1000x1000-3.png">
|
<img data-face="front" src="unknown_side-1000x1000-3.png"><img data-face="side" src="unknown_side-1000x1000-3.png">
|
||||||
</div>
|
</div>
|
||||||
|
<div class='label'>Female</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div id='bar-wrap'>
|
||||||
|
<section id='legend'>
|
||||||
|
<div class='legend legend--female'>Female</div>
|
||||||
|
<div class='legend legend--unknown'>Unknown</div>
|
||||||
|
<div class='legend legend--male'>Male</div>
|
||||||
</section>
|
</section>
|
||||||
<section id='graph'>
|
<section id='graph'>
|
||||||
<div id='graph--male' data-width="30%">
|
<div id='graph--female'>
|
||||||
<div class='wrap'><div class='background'></div></div>
|
<div class='wrap'><div class='background'></div></div>
|
||||||
<div class='cases'><span class='nr'>0</span> <span class='txt'>cases</span></div>
|
<div class='cases'><span class='nr'>0</span> <span class='txt'>cases</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div id='graph--female' data-width="30%">
|
<div id='graph--unknown'>
|
||||||
<div class='wrap'><div class='background'></div></div>
|
<div class='wrap'><div class='background'></div></div>
|
||||||
<div class='cases'><span class='nr'>0</span> <span class='txt'>cases</span></div>
|
<div class='cases'><span class='nr'>0</span> <span class='txt'>cases</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div id='graph--unknown' data-width="30%">
|
<div id='graph--male'>
|
||||||
<div class='wrap'><div class='background'></div></div>
|
<div class='wrap'><div class='background'></div></div>
|
||||||
<div class='cases'><span class='nr'>0</span> <span class='txt'>cases</span></div>
|
<div class='cases'><span class='nr'>0</span> <span class='txt'>cases</span></div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<!-- <section id='ethnicity'>
|
|
||||||
<h2>Reinforced Ethnical Stereotypes</h2>
|
|
||||||
<div id='graph'>
|
|
||||||
<div id='graph--black-african'>
|
|
||||||
<div class='background'></div>
|
|
||||||
<div class='cases'><span class='nr'>0</span> <span class='txt'>cases</span></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id='graph--caucasian'>
|
|
||||||
<div class='background'></div>
|
|
||||||
<div class='cases'><span class='nr'>0</span> <span class='txt'>cases</span></div>
|
|
||||||
</div>
|
|
||||||
<div id='graph--east-asian'>
|
|
||||||
<div class='background'></div>
|
|
||||||
<div class='cases'><span class='nr'>0</span> <span class='txt'>cases</span></div>
|
|
||||||
</div>
|
|
||||||
<div id='graph--hispanic'>
|
|
||||||
<div class='background'></div>
|
|
||||||
<div class='cases'><span class='nr'>0</span> <span class='txt'>cases</span></div>
|
|
||||||
</div>
|
|
||||||
<div id='graph--south-asian'>
|
|
||||||
<div class='background'></div>
|
|
||||||
<div class='cases'><span class='nr'>0</span> <span class='txt'>cases</span></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section> -->
|
|
||||||
<div id='affdex'>* according to the 2018 edition of Affectiva's gender detection toolkit</div>
|
<div id='affdex'>* according to the 2018 edition of Affectiva's gender detection toolkit</div>
|
||||||
<div id='signature'>
|
<div id='signature'>
|
||||||
<!-- — -->
|
<!-- — -->
|
||||||
Ruben van de Ven
|
Ruben van de Ven
|
||||||
<!-- — -->
|
<!-- — -->
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/javascript" src="reconnecting-websocket.min.js"></script>
|
||||||
|
<script type="text/javascript" src="composite_loader.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
178
www/styles.css
178
www/styles.css
|
@ -6,6 +6,7 @@
|
||||||
html{
|
html{
|
||||||
/* filter: invert(1); */
|
/* filter: invert(1); */
|
||||||
background: var(--secundary-color);
|
background: var(--secundary-color);
|
||||||
|
/* background-color: darkred; */
|
||||||
}
|
}
|
||||||
body{
|
body{
|
||||||
font-family: "CMU Serif";
|
font-family: "CMU Serif";
|
||||||
|
@ -34,7 +35,7 @@ html{
|
||||||
padding: 20px 0 20px 0;
|
padding: 20px 0 20px 0;
|
||||||
}
|
}
|
||||||
section#gender{
|
section#gender{
|
||||||
height: 44%;
|
height: 47%;
|
||||||
border-bottom: solid 4px var(--primary-color);
|
border-bottom: solid 4px var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ html{
|
||||||
font-size: 40%;
|
font-size: 40%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -12px;
|
top: -27px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.genders{
|
.genders{
|
||||||
|
@ -63,11 +64,6 @@ html{
|
||||||
#gender h2{
|
#gender h2{
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ethnicity h2{
|
|
||||||
/* letter-spacing: 2px; */
|
|
||||||
}
|
|
||||||
|
|
||||||
#affdex{
|
#affdex{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: calc(100% - 18px);
|
top: calc(100% - 18px);
|
||||||
|
@ -85,15 +81,68 @@ html{
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.genders {
|
||||||
|
display: flex;
|
||||||
|
/* flex-direction: row; */
|
||||||
|
justify-content: space-between;
|
||||||
|
/* vertical align: */
|
||||||
|
align-items: center;
|
||||||
|
margin: 30px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.gender-wrap{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.genders > div{
|
||||||
|
font-size: 20pt;
|
||||||
|
width: 195px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.genders .composite img{
|
||||||
|
width: 100%;
|
||||||
|
/* height: 180px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .genders #front--composite{
|
||||||
|
margin-top: 10px;
|
||||||
|
} */
|
||||||
|
|
||||||
|
.genders #front--composite{
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.genders .type{
|
||||||
|
text-transform: uppercase;;
|
||||||
|
display:block;
|
||||||
|
margin-top: -45px;
|
||||||
|
}
|
||||||
|
|
||||||
#graph{
|
#graph{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
margin: 0 20px;
|
margin: 0 20px;
|
||||||
padding-top: 50px;
|
padding-top: 50px;
|
||||||
clear:both;
|
clear:both;
|
||||||
|
font-size: 22pt;
|
||||||
}
|
}
|
||||||
#graph > div{
|
#graph > div{
|
||||||
width: 33%;
|
flex: 1;
|
||||||
|
min-width: 5%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#lines--side, #lines--front{
|
||||||
|
position: absolute;
|
||||||
|
top: 100px;
|
||||||
|
left: 200px;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
#lines--side{
|
||||||
|
top: 120px;
|
||||||
|
left: 580px;
|
||||||
|
transform: scale(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,28 +176,73 @@ html{
|
||||||
|
|
||||||
#graph .cases{
|
#graph .cases{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
text-wrap: wrap;
|
||||||
|
height: 1.2em;;
|
||||||
}
|
}
|
||||||
|
|
||||||
#differences{
|
#differences{
|
||||||
border-bottom: solid 4px var(--primary-color);
|
border-bottom: solid 4px var(--primary-color);
|
||||||
padding-bottom: 50px;
|
padding-bottom: 10px;
|
||||||
|
display:flex;
|
||||||
|
height: 497px;
|
||||||
}
|
}
|
||||||
#differences::after{
|
#differences::after{
|
||||||
content: '';
|
content: '';
|
||||||
clear:both;
|
clear:both;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
#differences .gender {
|
#differences .gender {
|
||||||
width: 50%;
|
font-size: 18pt;
|
||||||
margin: 50px 0 0 0;
|
}
|
||||||
float:left;
|
#differences > div{
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
#differences .gender {
|
||||||
|
width: 100%;
|
||||||
|
margin: 40px 0 0 0;
|
||||||
|
/* float:left; */
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
#differences .gender + .gender{
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
#differences .gender.explanation {
|
||||||
|
text-align: left;
|
||||||
|
text-transform: none;
|
||||||
|
padding-left: 85px;
|
||||||
|
padding-right: 50px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
#differences .gender.explanation h3{
|
||||||
|
margin: 60px 0 0 0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
#differences .gender.explanation p{
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#differences .gender.explanation + .gender{
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#differences .gender .diff-layer{
|
||||||
|
position: absolute;
|
||||||
|
top:0;
|
||||||
|
right:0;
|
||||||
|
left:0;
|
||||||
|
mix-blend-mode: difference;
|
||||||
|
}
|
||||||
|
|
||||||
|
#differences .gender .original-layer img{
|
||||||
|
/* black yields no difference for blend-mode */
|
||||||
|
border-color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
#differences .gender img{
|
#differences .gender img{
|
||||||
width: 180px;
|
width: 170px;
|
||||||
height: 180px;
|
height: 170px;
|
||||||
border: solid 2px var(--primary-color);
|
border: solid 2px var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,3 +250,57 @@ html{
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#bar-wrap{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#legend{
|
||||||
|
position: absolute;
|
||||||
|
border-top: solid 4px var(--primary-color);
|
||||||
|
border-right: solid 4px var(--primary-color);
|
||||||
|
border-bottom: solid 1px var(--secundary-color);
|
||||||
|
background-color: var(--secundary-color);
|
||||||
|
bottom: calc(100%);
|
||||||
|
left:0;
|
||||||
|
width: 46%;
|
||||||
|
padding: 20px 22px 0 22px;
|
||||||
|
font-size: 20pt;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#legend div{
|
||||||
|
display: inline-block;
|
||||||
|
text-transform: uppercase;
|
||||||
|
position: relative;
|
||||||
|
top: 15px;
|
||||||
|
font-size: 18pt;
|
||||||
|
}
|
||||||
|
#legend div::before{
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
border: solid 2px var(--primary-color);
|
||||||
|
outline: 2px solid var(--secundary-color);
|
||||||
|
margin-right: 10px;
|
||||||
|
background-image:url('texture-cross.png');
|
||||||
|
background-size: 12px;
|
||||||
|
filter:invert(1);
|
||||||
|
font-size: 15pt;
|
||||||
|
/* vertical-align: baseline; */
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
|
||||||
|
}
|
||||||
|
#legend div:nth-child(2)::before{
|
||||||
|
background-image:url('texture-diagonal.png');
|
||||||
|
background-size: 12px;
|
||||||
|
}
|
||||||
|
#legend div:nth-child(3)::before{
|
||||||
|
background-image:url('texture-ball.png');
|
||||||
|
background-size: 12px;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue