Browse Source

tsne added

master
cailean 2 months ago
parent
commit
12cd2778ac
  1. 4
      .vscode/c_cpp_properties.json
  2. 89
      Demo.code-workspace
  3. 8
      Demo.qbs
  4. 2
      addons.make
  5. 9
      src/Player.cpp
  6. 2
      src/Player.h
  7. 76
      src/TSNEMap.cpp
  8. 14
      src/TSNEMap.h
  9. 1
      src/ofApp.cpp

4
.vscode/c_cpp_properties.json

@ -7,7 +7,6 @@
"/usr/local/include", "/usr/local/include",
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/",
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1",
"${workspaceRoot}/../../../addons/ofxGui",
"${workspaceRoot}/../../../libs/openFrameworks", "${workspaceRoot}/../../../libs/openFrameworks",
"${workspaceRoot}/../../../libs/openFrameworks/3d", "${workspaceRoot}/../../../libs/openFrameworks/3d",
"${workspaceRoot}/../../../libs/openFrameworks/app", "${workspaceRoot}/../../../libs/openFrameworks/app",
@ -71,6 +70,7 @@
"/usr/local/include", "/usr/local/include",
"/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed", "/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
"/usr/include/x86_64-linux-gnu", "/usr/include/x86_64-linux-gnu",
"${workspaceRoot}/../../../addons/ofxTSNE/src}",
"${workspaceRoot}/../../../libs/openFrameworks", "${workspaceRoot}/../../../libs/openFrameworks",
"${workspaceRoot}/../../../libs/openFrameworks/3d", "${workspaceRoot}/../../../libs/openFrameworks/3d",
"${workspaceRoot}/../../../libs/openFrameworks/app", "${workspaceRoot}/../../../libs/openFrameworks/app",
@ -106,7 +106,7 @@
"/usr/include/gstreamer-1.0", "/usr/include/gstreamer-1.0",
"/usr/include/glib-2.0", "/usr/include/glib-2.0",
"${workspaceRoot}", "${workspaceRoot}",
"${workspaceRoot}/../../../addons/ofxGui/src" "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxTSNE/src"
], ],
"browse": { "browse": {
"limitSymbolsToIncludedHeaders": true, "limitSymbolsToIncludedHeaders": true,

89
Demo.code-workspace

@ -10,92 +10,5 @@
"path": "${workspaceRoot}/../../../../addons" "path": "${workspaceRoot}/../../../../addons"
} }
], ],
"settings": { "settings": {}
"files.associations": {
"ostream": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"any": "cpp",
"array": "cpp",
"atomic": "cpp",
"strstream": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"cfenv": "cpp",
"charconv": "cpp",
"chrono": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"expected": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"regex": "cpp",
"source_location": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ranges": "cpp",
"semaphore": "cpp",
"shared_mutex": "cpp",
"span": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp",
"format": "cpp",
"stdfloat": "cpp",
"__nullptr": "cpp"
}
}
} }

8
Demo.qbs

@ -12,8 +12,14 @@ Project{
name: { return FileInfo.baseName(sourceDirectory) } name: { return FileInfo.baseName(sourceDirectory) }
files: [ files: [
'src/ImageViewer.cpp',
'src/ImageViewer.h',
'src/Player.cpp', 'src/Player.cpp',
'src/Player.h', 'src/Player.h',
'src/Request.cpp',
'src/Request.h',
'src/TSNEMap.cpp',
'src/TSNEMap.h',
'src/main.cpp', 'src/main.cpp',
'src/ofApp.cpp', 'src/ofApp.cpp',
'src/ofApp.h', 'src/ofApp.h',
@ -22,6 +28,8 @@ Project{
of.addons: [ of.addons: [
'ofxGui', 'ofxGui',
'ofxGui', 'ofxGui',
'ofxTSNE',
'ofxTSNE',
] ]
// additional flags for the project. the of module sets some // additional flags for the project. the of module sets some

2
addons.make

@ -1,2 +1,4 @@
ofxGui ofxGui
ofxGui ofxGui
ofxTSNE
ofxTSNE

9
src/Player.cpp

@ -110,6 +110,8 @@ void Player::setupGUI(){
gui.add(currentFrameLabel.setup("Current Frame", ofToString(playerCurrentFrame))); gui.add(currentFrameLabel.setup("Current Frame", ofToString(playerCurrentFrame)));
gui.add(currentVideoLabel.setup("Video Name", videoPath)); gui.add(currentVideoLabel.setup("Video Name", videoPath));
gui.add(audioToggle.setup("Audio", false));
currentVector.angry = angrySlider; currentVector.angry = angrySlider;
currentVector.disgust = disgustSlider; currentVector.disgust = disgustSlider;
currentVector.fear = fearSlider; currentVector.fear = fearSlider;
@ -147,5 +149,12 @@ void Player::updateGUI(){
lastVector = currentVector; lastVector = currentVector;
} }
if(audioToggle){
videoPlayer.setVolume(1);
} else {
videoPlayer.setVolume(0);
}
currentFrameLabel = ofToString(playerCurrentFrame); currentFrameLabel = ofToString(playerCurrentFrame);
} }

2
src/Player.h

@ -41,6 +41,8 @@ class Player {
ofxFloatSlider surpriseSlider; ofxFloatSlider surpriseSlider;
ofxFloatSlider neutralSlider; ofxFloatSlider neutralSlider;
ofxToggle audioToggle;
ofxLabel currentFrameLabel; ofxLabel currentFrameLabel;
ofxLabel currentVideoLabel; ofxLabel currentVideoLabel;
ofxLabel currentIndexLabel; ofxLabel currentIndexLabel;

76
src/TSNEMap.cpp

@ -6,13 +6,73 @@ TSNEMap::TSNEMap(){
} }
void TSNEMap::setup(){ void TSNEMap::setup(){
for (int i = 0; i < 5; ++i) { setupNodes();
// Setup FBO
fbo.allocate(ofGetWindowWidth() / 3, ofGetWindowHeight() / 3 * 2, GL_RGBA);
cam.removeAllInteractions();
cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_XY,OF_MOUSE_BUTTON_LEFT);
cam.enableOrtho();
// Setup top-down orthographic camera
cam.setNearClip(-1000000);
cam.setFarClip(1000000);
}
void TSNEMap::setupTSNE(std::string jsonPath){
// Load in JSON
jsonEmbeddings = ofLoadJson(jsonPath);
// Check if JSON is an array
if (!jsonEmbeddings.is_array()) {
ofLogError() << "JSON is not an array";
return;
}
// Loop through each entry in the JSON array
for (const auto& entry : jsonEmbeddings) {
// Check if the entry has a "vector" field
if (entry.contains("vector") && entry["vector"].is_array()) {
std::vector<float> vec;
// Loop through each value in the "vector" field
for (const auto& value : entry["vector"]) {
// Check if the value is a number and add it to the vector
if (value.is_number()) {
vec.push_back(value.get<float>());
} else {
ofLogError() << "Vector value is not a number";
}
}
// Add the extracted vector to the list
embeddings.push_back(vec);
} else {
ofLogError() << "Entry does not contain a valid 'vector' field";
}
}
// Run tsne
tsnePoints = tsne.run(embeddings, dims, perplexity, theta, normalise, runManually);
// Output the vectors to the console (for debugging)
for (const auto& vec : tsnePoints) {
for (float value : vec) {
std::cout << value << " ";
}
std::cout << std::endl;
}
}
void TSNEMap::setupNodes(){
int idx = 0;
for (const auto& vec : tsnePoints) {
ofImage img; ofImage img;
ImageObject obj; ImageObject obj;
ofPlanePrimitive plane; ofPlanePrimitive plane;
img.load("images/happy.png"); // what image?
img.load(jsonEmbeddings[idx]["image"]);
int imageW = image.getWidth(); int imageW = image.getWidth();
int imageH = image.getHeight(); int imageH = image.getHeight();
@ -47,7 +107,7 @@ void TSNEMap::setup(){
} }
plane.set(planeW, planeH); // Random width and height plane.set(planeW, planeH); // Random width and height
plane.setPosition(ofRandom(-200, 200), ofRandom(-200, 200), 0); // Random position on XZ plane plane.setPosition((vec[0] * 5000) - 2500, (vec[1] * 5000) - 2500, 0); // Random position on XZ plane
plane.setResolution(2, 2); plane.setResolution(2, 2);
plane.mapTexCoordsFromTexture(img.getTexture()); plane.mapTexCoordsFromTexture(img.getTexture());
@ -61,16 +121,10 @@ void TSNEMap::setup(){
obj.phaseY = ofRandom(0, TWO_PI); // Random phase obj.phaseY = ofRandom(0, TWO_PI); // Random phase
objects.push_back(obj); objects.push_back(obj);
idx++;
} }
// Setup FBO
fbo.allocate(ofGetWindowWidth() / 3, ofGetWindowHeight() / 3 * 2, GL_RGBA);
cam.removeAllInteractions();
cam.addInteraction(ofEasyCam::TRANSFORM_TRANSLATE_XY,OF_MOUSE_BUTTON_LEFT);
cam.enableOrtho();
// Setup top-down orthographic camera
cam.setNearClip(-1000000);
cam.setFarClip(1000000);
} }
void TSNEMap::update(){ void TSNEMap::update(){

14
src/TSNEMap.h

@ -2,6 +2,7 @@
#define _TSNEMAP #define _TSNEMAP
#include "ofMain.h" #include "ofMain.h"
#include "ofxTSNE.h"
struct ImageObject { struct ImageObject {
float speedX; float speedX;
@ -25,6 +26,8 @@ class TSNEMap{
void setTexture(std::string imagePath); void setTexture(std::string imagePath);
void updateCameraProjection(); void updateCameraProjection();
void keyPressed(int key); void keyPressed(int key);
void setupTSNE(std::string jsonPath);
void setupNodes();
ofFbo fbo; ofFbo fbo;
vector<ofPlanePrimitive> planes; vector<ofPlanePrimitive> planes;
@ -34,6 +37,17 @@ class TSNEMap{
ofImage image; ofImage image;
float zoomLevel; float zoomLevel;
ofxTSNE tsne;
ofJson jsonEmbeddings;
vector<vector<float> > embeddings;
vector<vector<double> > tsnePoints;
int dims = 2;
float perplexity = 20;
float theta = 0.2;
bool normalise = true;
bool runManually = false;
TSNEMap(); TSNEMap();
}; };

1
src/ofApp.cpp

@ -9,6 +9,7 @@ void ofApp::setup(){
ofSetVerticalSync(true); ofSetVerticalSync(true);
player.setup(); player.setup();
imageViewer.setup(); imageViewer.setup();
map.setupTSNE("embeddings.json");
map.setup(); map.setup();
} }

Loading…
Cancel
Save