Created
July 24, 2023 19:37
-
-
Save alshakero/a38e64aab74198cc5d58e0d94e5c9f19 to your computer and use it in GitHub Desktop.
Faces from the world
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import processing.sound.*; | |
String path = "/Users/omaralshaker/Work.nosync/Personal/processingart/faces/"; | |
String facesPath = "/Users/omaralshaker/Work.nosync/Personal/midi/portraits-resized/portraits/"; | |
String facesDataFilePath = "/Users/omaralshaker/Work.nosync/Personal/midi/faces-results/full.json"; | |
Face[] faces = new Face[400]; | |
SoundFile sound; | |
class Face { | |
PVector rightEye; | |
PVector leftEye; | |
PImage image; | |
public String name; | |
public Face(JSONObject obj) { | |
this.image = loadImage(facesPath + obj.getString("image")); | |
this.rightEye = this.centerPoint(obj.getJSONArray("right_eye")); | |
this.leftEye = this.centerPoint(obj.getJSONArray("left_eye")); | |
this.name = obj.getString("image") ; | |
} | |
private PVector centerPoint(JSONArray points) { | |
float sumX = 0; | |
float sumY = 0; | |
for(int i = 0; i < points.size(); i++) { | |
sumX += points.getJSONArray(i).getInt(0); | |
sumY += points.getJSONArray(i).getInt(1); | |
} | |
int x = (int)(sumX / (float)points.size()); | |
int y = (int)(sumY / (float)points.size()); | |
return new PVector(x, y); | |
} | |
} | |
Amplitude amp; | |
int faceIndex = 0; | |
int bands = 6; | |
float[] spectrum = new float[bands]; | |
void setup() { | |
colorMode(RGB, 255); | |
size(1080, 1920); | |
amp = new Amplitude(this); | |
var facesData = loadJSONArray(facesDataFilePath); | |
int index = 0; | |
for(int i = 0; i < 400; i++) { | |
var obj = facesData.getJSONObject(i); | |
File f = new File(facesPath + obj.getString("image")); | |
if(f.exists()) { | |
faces[index++] = new Face(obj); | |
} | |
} | |
sound = new SoundFile(this, path + "Grosso.mp3"); | |
sound.play(); | |
sound.jump(165); | |
amp.input(sound); | |
} | |
int flipThreshold() { | |
if(millis() < 12 * 1000) { | |
return 400; | |
} if (millis() < 28 * 1000) { | |
return 300; | |
} if (millis() < 34 * 1000) { | |
return 200; | |
} | |
if (millis() > 50 * 1000) { | |
return 100; | |
} | |
return 300; | |
} | |
PVector lastLeftEyePoint; | |
PVector lastRightEyePoint; | |
int requiredEyeGap = 300; | |
int leftEyeX = 300; | |
int leftEyeY = 400; | |
int lastFlip = 0; | |
float angleX = 0; | |
float angleY = 0; | |
void draw() { | |
if(amp.analyze() > 0.378 && millis() - lastFlip > flipThreshold()) { | |
leftEyeX = 300 + (int)(sin(angleX) * 300); | |
leftEyeY = 400 + (int)(sin(angleY) * 400); | |
angleX += 0.002; | |
angleY += 0.002; | |
lastFlip = millis(); | |
var face = faces[faceIndex]; | |
PImage faceImage = face.image; | |
PVector leftEyePoint = face.leftEye; | |
PVector rightEyePoint = face.rightEye; | |
float eyeGap = rightEyePoint.x - leftEyePoint.x; | |
float resizeNeeded = requiredEyeGap / eyeGap; | |
float angle = atan((float)(rightEyePoint.y - leftEyePoint.y) / (float)(rightEyePoint.x - leftEyePoint.x)); | |
try { | |
faceImage.resize((int)((resizeNeeded * (float)faceImage.width)), 0); | |
leftEyePoint.mult(resizeNeeded); | |
rightEyePoint.mult(resizeNeeded); | |
} catch(Exception e) { | |
println("image failed: " + path); | |
} | |
int translationX = (int)(leftEyeX - leftEyePoint.x); | |
int translationY = (int)(leftEyeY - leftEyePoint.y); | |
pushMatrix(); | |
translate(translationX + leftEyePoint.x, translationY + leftEyePoint.y); | |
rotate(-angle); | |
int start = millis(); | |
image(faceImage, -leftEyePoint.x, -leftEyePoint.y); | |
println(face.name, millis() - start); | |
faces[faceIndex].image = null; | |
popMatrix(); | |
faceIndex++; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment