Skip to content

Commit

Permalink
knowlton sketch
Browse files Browse the repository at this point in the history
  • Loading branch information
brightredchilli committed Nov 15, 2017
1 parent 4c4fe46 commit 8da8934
Show file tree
Hide file tree
Showing 17 changed files with 290 additions and 0 deletions.
33 changes: 33 additions & 0 deletions bin/data/scenes/yingKnowlton/exampleCode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

void draw() {

currentVideo = getVideo([[videoNum]]).draw();

for (int i = 0; i < [[iterations]]; i++) {

if (random() < [[mixRatio]]) {
targetImage = currentVideo;
} else {
targetImage = originalImage;
}

for (int i = 0; i < imageWidth; i++) {
for (int j = 0; j < imageHeight; j++) {

int randX = random(0, imageWidth);
int randY = random(0, imageHeight);

// randomly swap a pixel
sourceImageAfterSwap = sourceImage.swapPixels(i,j, randX, randY);

if (distanceToOriginal(sourceImageAfterSwap) <
distanceToOriginal(sourceImage)) {
sourceImage = sourceImageAfterSwap;
}
}
}


}
sourceImage.draw();
}
Binary file added bin/data/scenes/yingKnowlton/sfpc-final_640.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
15 changes: 15 additions & 0 deletions recoded.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
2AAF4613693D9695224E47EA /* annMolnarRectangles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D790E5FFA07829E87D5854B1 /* annMolnarRectangles.cpp */; };
2CDF949125CD5802082364F3 /* mattKnowlton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A39AE0D2FA3A4C9F76FC4E61 /* mattKnowlton.cpp */; };
2DE293FAAF850C0ABF02DB62 /* exampleScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59429ADBB14FCD19148E74FB /* exampleScene.cpp */; };
2E55175E1FBC8D0300D6B8C9 /* yingKnowlton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E55175D1FBC8CFD00D6B8C9 /* yingKnowlton.cpp */; };
2E555A4FA8AD6EA2CA95AACF /* loloWhitney.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6397CED8F069F8CCB13C01F /* loloWhitney.cpp */; };
2E6C274B1FBA494600D54DC9 /* zzSushiScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E6C27491FBA48AC00D54DC9 /* zzSushiScene.cpp */; };
310ED8BB549B244C0DFB0FA1 /* mgsVeraMolnarLineStudy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA88C1467946DA7D2C11601B /* mgsVeraMolnarLineStudy.cpp */; };
Expand Down Expand Up @@ -246,6 +247,8 @@
2BAEA0543B2829CB46F35032 /* mgsRileyEllipsesAndSquares.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 30; name = mgsRileyEllipsesAndSquares.cpp; path = src/scenes/mgsRileyEllipsesAndSquares/mgsRileyEllipsesAndSquares.cpp; sourceTree = SOURCE_ROOT; };
2DB66B4D75A388D55904F54F /* fernandoWhitney2.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 30; name = fernandoWhitney2.h; path = src/scenes/fernandoWhitney2/fernandoWhitney2.h; sourceTree = SOURCE_ROOT; };
2E3CEE46463AC03FCB57EC56 /* loloVera.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 30; name = loloVera.h; path = src/scenes/loloVera/loloVera.h; sourceTree = SOURCE_ROOT; };
2E55175C1FBC8CFD00D6B8C9 /* yingKnowlton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = yingKnowlton.h; sourceTree = "<group>"; };
2E55175D1FBC8CFD00D6B8C9 /* yingKnowlton.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = yingKnowlton.cpp; sourceTree = "<group>"; };
2E6C27491FBA48AC00D54DC9 /* zzSushiScene.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = zzSushiScene.cpp; sourceTree = "<group>"; };
2E6C274A1FBA48AC00D54DC9 /* zzSushiScene.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = zzSushiScene.h; sourceTree = "<group>"; };
2F409986A645F575A744FC98 /* EstherKnowltonScene.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 30; name = EstherKnowltonScene.h; path = src/scenes/EstherKnowltonScene/EstherKnowltonScene.h; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -713,6 +716,16 @@
name = mgsCooperSymbols;
sourceTree = "<group>";
};
2E55175B1FBC8CFD00D6B8C9 /* yingKnowlton */ = {
isa = PBXGroup;
children = (
2E55175C1FBC8CFD00D6B8C9 /* yingKnowlton.h */,
2E55175D1FBC8CFD00D6B8C9 /* yingKnowlton.cpp */,
);
name = yingKnowlton;
path = scenes/yingKnowlton;
sourceTree = "<group>";
};
2E6C27481FBA48AC00D54DC9 /* zzSushiScene */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -788,6 +801,7 @@
36BF1C038F5AEC4D85473FE4 /* scenes */ = {
isa = PBXGroup;
children = (
2E55175B1FBC8CFD00D6B8C9 /* yingKnowlton */,
B0822B3B1FB786C900007B2D /* Guillermo_Whitney_catalogue_1 */,
B0822B311FB565DC00007B2D /* stacyButterflies */,
B0822B2D1FB5646A00007B2D /* diegoScene_01 */,
Expand Down Expand Up @@ -2226,6 +2240,7 @@
D391E4FB2414857BD467D9E8 /* gif_font.c in Sources */,
B0822AE51FB5491200007B2D /* ofxMidiMessage.cpp in Sources */,
149FF2205EB6D2EB34272D36 /* gif_hash.c in Sources */,
2E55175E1FBC8D0300D6B8C9 /* yingKnowlton.cpp in Sources */,
FFBFC666B626901721B1798A /* gifalloc.c in Sources */,
928A7D091FBB5BDE003A2403 /* zzEggScene.cpp in Sources */,
F3339D42B1A22AEF847B1F85 /* quantize.c in Sources */,
Expand Down
2 changes: 2 additions & 0 deletions src/sceneManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
#include "diegoScene_01.h"
#include "stacyButterflies.h"
#include "EstherMolnarScene.h"
#include "yingKnowlton.h"

// these are food related scenes

Expand Down Expand Up @@ -188,6 +189,7 @@ void sceneManager::setup(){
scenes.push_back(new annMolnarRectangles());
scenes.push_back(new weiWhitney());
scenes.push_back(new yumiNishida01());
scenes.push_back(new yingKnowlton());


#endif
Expand Down
195 changes: 195 additions & 0 deletions src/scenes/yingKnowlton/yingKnowlton.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@

#include "yingKnowlton.h"

void yingKnowlton::setup(){

originalImage.load("scenes/yingKnowlton/sfpc-final_640.png");
originalImage.setImageType(OF_IMAGE_COLOR);
sourceImage.load("scenes/yingKnowlton/sfpc-final_640.png");
sourceImage.setImageType(OF_IMAGE_COLOR);
targetScores = NULL;

ofBackground(0);

res = 4;

// note: pulled from @sfpc_nyc instagram feed
directory = ofDirectory("scenes/yingKnowlton/videos/");
directory.listDir();

playVideo(0);
center.set(dimensions.width/2, dimensions.height/2);
screenScale = dimensions.width/vidPlayer.getWidth();
screenScale *= 1.01; // MULTIPLY HERE TO MAKE EDGES BLEED PAST THE SCREEN

parameters.add(videoNum.set("videoNum", 0, 0, directory.size()));
parameters.add(iterations.set("iterations", 5000, 10, 10000));
parameters.add(mixRatio.set("mixRatio", 1, 0, 1));

setAuthor("Ying Quan Tan");
setOriginalArtist("Ken Knowlton");
loadCode("scenes/yingKnowlton/exampleCode.cpp");
}

void yingKnowlton::update(){
vidPlayer.update();
if (vidPlayer.isPlaying() && vidPlayer.getTotalNumFrames() - vidPlayer.getCurrentFrame() < 30) {
videoNum = ++videoNum % directory.size();
playVideo(videoNum);
}
if (current != videoNum) {
current = videoNum;
playVideo(videoNum);
}
}

void yingKnowlton::draw(){
ofPushMatrix();

int vidWidth = vidPlayer.getWidth() * screenScale;
int vidHeight = vidPlayer.getHeight() * screenScale;
// center the video
ofTranslate(center - ofPoint(vidWidth, vidHeight)/2);

// make sure video scales to screen.
ofScale(screenScale, screenScale);


if ((vidPlayer.isPlaying() && sourceImage.isAllocated())) {
unsigned char * vidPixels = vidPlayer.getPixels().getData();
unsigned char * originalPixels = originalImage.getPixels().getData();

ofImage &image = sourceImage;
int cols = image.getWidth() / res;
int rows = image.getHeight() / res;
int positions = cols * rows;
int bytesPerPixel = 3;

for (int it = 0; it < iterations; it++) {
unsigned char * targetPointer;
if (ofRandom(1.0) < mixRatio) {
targetPointer = vidPixels;
} else {
targetPointer = originalPixels;
}

int i = floor(ofRandom(cols)) * res;
int j = floor(ofRandom(rows)) * res;
float previousTargetScore = targetScore;
int index = (j * image.getWidth() + i) * bytesPerPixel;
int x = i / res;
int y = j / res;

int randX = floor(ofRandom(cols)) * res;
int randY = floor(ofRandom(rows)) * res;
int randIndex = (randY * image.getWidth() + randX) * bytesPerPixel;

unsigned char * from = getSubImage(image, i, j, res);
unsigned char * to = getSubImage(image, randX, randY, res);

// calculate costs
float fromScore = distance(from, targetPointer + index);
float toScore = distance(to, targetPointer + randIndex);

float afterSwapFromScore = distance(to, targetPointer + index);
float afterSwapToScore = distance(from, targetPointer + randIndex);

if (afterSwapFromScore + afterSwapToScore < fromScore + toScore) {
// perform swap
setSubImage(image, i, j, res, to);
setSubImage(image, randX, randY, res, from);
}
delete[] from;
delete[] to;
}

image.update();
image.draw(0, 0);
}
ofPopMatrix();
}

void yingKnowlton::playVideo(int index) {
vidPlayer.load(directory.getPath(index));
int cols = vidPlayer.getWidth() / res;
int rows = vidPlayer.getHeight() / res;
if (targetScores == NULL) {
targetScores = new unsigned char[cols * rows];
}
memset(targetScores,0,cols * rows);

vidPlayer.setVolume(0);
vidPlayer.play();

}

unsigned char * yingKnowlton::getSubImage(ofImage &image,
int _x,
int _y,
int maskSize) {
int bytesPerPixel = 3;
unsigned char * subImage = new unsigned char[maskSize * maskSize * bytesPerPixel];
unsigned char * data = image.getPixels().getData();

int c = 0;
for (int y = _y; y < _y + maskSize; y++) {
for (int x = _x; x < _x + maskSize; x++) {
int idx = y * image.getWidth()*bytesPerPixel + x*bytesPerPixel;
for (int i = 0; i < bytesPerPixel; i++) {
subImage[c + i] = data[idx + i];
}
c += bytesPerPixel;
}
}
return subImage;
}


void yingKnowlton::setSubImage(ofImage &image,
int _x,
int _y,
int maskSize,
unsigned char * subImage) {
int bytesPerPixel = 3;
unsigned char * data = image.getPixels().getData();
int c = 0;
for (int y = _y; y < _y + maskSize; y++) {
for (int x = _x; x < _x + maskSize; x++) {
int idx = (y * image.getWidth() + x) * bytesPerPixel;
for (int i = 0; i < bytesPerPixel; i++) {
data[idx + i] = subImage[c + i];
}
c += bytesPerPixel;
}
}
}

float yingKnowlton::distance(unsigned char * pixel1,
unsigned char * pixel2) {

float r1 = pixel1[0];
float g1 = pixel1[1];
float b1 = pixel1[2];

float r2 = pixel2[0];
float g2 = pixel2[1];
float b2 = pixel2[2];

float dist = abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2);
dist /= (255*3);
return dist;
}

float yingKnowlton::getTargetScore() {

float total = 0;
int cols = sourceImage.getWidth() / res;
int rows = sourceImage.getHeight() / res;
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
int score = targetScores[j * cols + i];
total += score;
}
}
return total;
}
45 changes: 45 additions & 0 deletions src/scenes/yingKnowlton/yingKnowlton.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include "ofMain.h"
#include "baseScene.h"

class yingKnowlton : public baseScene {

public:

void setup();
void update();
void draw();

int res;
ofVideoPlayer vidPlayer;
ofImage sourceImage;
ofImage originalImage;
ofImage targetImage;
ofPoint center;
float screenScale;
unsigned char * targetScores;
float targetScore;

unsigned char * getSubImage(ofImage &image,
int x,
int y,
int maskSize);
void setSubImage(ofImage &image,
int x,
int y,
int maskSize,
unsigned char * subImage);
float distance(unsigned char * pixel1,
unsigned char * pixel2);
float getTargetScore();

void playVideo(int index);


int current;
ofParameter < float > mixRatio;
ofParameter < int > videoNum;
ofParameter < int > iterations;
ofDirectory directory;
};

0 comments on commit 8da8934

Please sign in to comment.