Browse Source

added querying

master
cailean 4 months ago
parent
commit
c756613651
  1. 2
      .vscode/c_cpp_properties.json
  2. 48434
      bin/data/json/embeddings.json
  3. BIN
      bin/data/new_tree.bin
  4. BIN
      bin/data/vp-tree.bin
  5. BIN
      bin/image-to-mesh
  6. 4
      image-to-mesh.code-workspace
  7. 5
      src/Bullet.cpp
  8. 4
      src/Bullet.h
  9. 24
      src/network/Request.h
  10. 16
      src/network/Server.cpp
  11. 9
      src/network/Server.h
  12. 157
      src/ofApp.cpp
  13. 29
      src/ofApp.h
  14. 38
      src/vp/VP.cpp
  15. 14
      src/vp/VP.h

2
.vscode/c_cpp_properties.json

@ -118,7 +118,7 @@
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxVideoRecorder/src",
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxOsc/*",
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxNetwork/src/*",
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxTSNE/src/*",
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxTSNE/src/**",
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxPiMapper/src/*",
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxXmlSettings/src",
"/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/addons/ofxXmlSettings/libs",

48434
bin/data/json/embeddings.json

File diff suppressed because it is too large

BIN
bin/data/new_tree.bin

Binary file not shown.

BIN
bin/data/vp-tree.bin

Binary file not shown.

BIN
bin/image-to-mesh

Binary file not shown.

4
image-to-mesh.code-workspace

@ -107,7 +107,9 @@
"__bit_reference": "cpp",
"filesystem": "cpp",
"executor": "cpp",
"timer": "cpp"
"timer": "cpp",
"buffer": "cpp",
"socket": "cpp"
}
}
}

5
src/Bullet.cpp

@ -1,6 +1,6 @@
#include "Bullet.h"
void Bullet::setup(){
void Bullet::setup(vector<Node>& _nodes){
/* setup camera & world */
camera_start_pos = ofVec3f(0, -3.f, -40.f);
camera_end_position = glm::vec3(ofRandom(-100, 100), ofRandom(-100, 100), ofRandom(0, 0));
@ -25,6 +25,9 @@ void Bullet::setup(){
shader.load("shaders/vertex_snap");
/* assign nodes */
nodes = _nodes;
std::cout << workerThreads.size() << std::endl;
}

4
src/Bullet.h

@ -13,11 +13,13 @@ struct Node {
ofImage img;
ofTexture tex;
glm::vec3 scale;
glm::vec3 tsne_position;
vector<float> raw_embedding;
};
class Bullet{
public:
void setup();
void setup(vector<Node>& _nodes);
void update();
void draw();
void addMesh(ofMesh _mesh, ofMesh _simple_mesh, ofTexture _tex);

24
src/network/Request.h

@ -21,6 +21,30 @@ struct Embedding {
bool operator!=(const Embedding &other) const {
return emotions != other.emotions;
}
// New method to convert emotions to vector<float>
std::vector<float> to_vector() const {
std::vector<float> result;
result.reserve(emotions.size()); // Reserve space for efficiency
// Define the order of emotions
const std::vector<std::string> emotion_order = {
"angry", "disgust", "fear", "happy", "sad", "surprise", "neutral"
};
// Fill the vector in the defined order
for (const auto& emotion : emotion_order) {
auto it = emotions.find(emotion);
if (it != emotions.end()) {
result.push_back(it->second);
} else {
// If an emotion is missing, push 0.0f
result.push_back(0.0f);
}
}
return result;
}
};
/* Vantage point query structure */

16
src/network/Server.cpp

@ -4,7 +4,6 @@ void Server::start(){
std::cout << "Initialising TCP sever" << std::endl;
server.setup(port);
osc_sender.setup(OSC_HOST, OSC_PORT);
//http.setup(http_ip, http_port, http_page);
is_active = true;
previous_embedding = embedding;
last_change_time = std::chrono::steady_clock::now();
@ -52,7 +51,7 @@ void Server::update(ofFbo& esp_comp){
addOrUpdateClient(id, value, ip_address, true);
std::cout << ip_address << " : " << id << std::endl;
//std::cout << ip_address << " : " << id << std::endl;
}
@ -140,11 +139,18 @@ void Server::print(){
/* check if the controllers are in use */
void Server::checkActivity(){
if (previous_embedding.emotions["neutral"] != embedding.emotions["neutral"]) { // Check if embedding has changed
if (previous_embedding.emotions != embedding.emotions) { // Check if embedding has changed
last_change_time = std::chrono::steady_clock::now(); // Reset the timer if there is a change
previous_embedding = embedding; // Update the previous embedding to the current one
is_active = true;
//sendHttpRequest();
/* send a query to search the closest embedding in the vp-tree */
vector<vector<float>> vp_queries;
vp_queries.push_back(embedding.to_vector());
vector<int> ids = tree.query(vp_queries, 1);
chosen_node = &nodes[ids[0]];
ofLogNotice() << chosen_node->tsne_position;
} else {
// Calculate the time since the last change
auto now = std::chrono::steady_clock::now();
@ -227,7 +233,7 @@ void Server::sendImagesToClients(vector<ofImage>& imgs){
// Send RGB pixels as raw bytes & check if the ip addresses align -> get id
for(const auto& c_pair : clients){
std::cout << c_pair.first << std::endl;
//std::cout << c_pair.first << std::endl;
if(c_pair.second.ip_address == server.getClientIP(i)){
unsigned char* image_data = esp_pixels[c_pair.first].getData();

9
src/network/Server.h

@ -7,6 +7,7 @@
#include <chrono>
#include "ofxOsc.h"
#include "../vp/VP.h"
#include "../Bullet.h"
#define OSC_HOST "127.0.0.1"
#define OSC_PORT 9002
@ -19,8 +20,8 @@ struct ClientInfo {
class Server{
public:
Server(int _port, Embedding& _embedding, VP& _tree, bool debug, std::string _http_ip, int _http_port, std::string _http_page)
: port(_port), embedding(_embedding), tree(_tree), debug(debug), http_ip(_http_ip), http_port(_http_port), http_page(_http_page) {}
Server(int _port, Embedding& _embedding, VP& _tree, vector<Node>& _nodes, bool debug, std::string _http_ip, int _http_port, std::string _http_page)
: port(_port), embedding(_embedding), tree(_tree), debug(debug), nodes(_nodes), http_ip(_http_ip), http_port(_http_port), http_page(_http_page) {}
void start();
void update(ofFbo& esp_comp);
@ -42,7 +43,9 @@ class Server{
bool debug;
bool is_active;
Embedding embedding;
VP tree;
VP& tree;
vector<Node>& nodes;
Node* chosen_node;
Request http;
std::string http_ip;

157
src/ofApp.cpp

@ -3,17 +3,6 @@
//--------------------------------------------------------------
void ofApp::setup(){
const int vectorCount = 10000;
const int dimension = 7;
const int queryCount = 10;
const int k = 5; // Number of nearest neighbors to find
auto vectors = vp_tree.generateRandomVectors(vectorCount, dimension);
vpt::VpTree tree = vp_tree.buildTree(vectors);
vp_tree.saveTree("./data/vp-tree.bin", tree);
/* allocated fbo's */
map_fbo.allocate((ofGetWindowWidth() / 3) * 2, ofGetWindowHeight(), GL_RGB);
portrait_fbo.allocate((ofGetWindowWidth() / 3) * 1, ofGetWindowHeight(), GL_RGBA);
@ -49,7 +38,7 @@ void ofApp::setup(){
ORTCHAR_T* modelPath = "/home/cailean/Desktop/openframeworks/of_v0.12.0_linux64gcc6_release/apps/myApps/image-to-mesh/bin/data/models/depth_anything_v2_vits.onnx";
/* setup */
bullet.setup();
//bullet.setup(nodes);
depth_onnx.Setup(modelPath, true, true);
depth_onnx_esp.Setup(modelPath, true, true);
@ -57,21 +46,6 @@ void ofApp::setup(){
depth_thread.setup(&model_image, &model_outptut_fbo, &depth_onnx);
depth_esp.setup(&model_image_esp, &model_esp_out_fbo, &depth_onnx_esp);
/* vp-test */
auto queries = server->generateRandomVectors(queryCount, dimension);
for (const auto& query : queries) {
auto [distances, indices] = tree.getNearestNeighbors(query, k);
// Uncomment the following lines to print results for each query
std::cout << "Query: ";
for (double d : query) std::cout << d << " ";
std::cout << "\nNearest neighbors:\n";
for (int i = 0; i < k; ++i) {
std::cout << " Index: " << indices[i] << ", Distance: " << distances[i] << "\n";
}
}
/* mesh generation test */
std::string path = "images";
@ -95,17 +69,19 @@ void ofApp::setup(){
vector<ofMesh> mesh_list;
// vector<ofMesh> mesh_list;
for(auto& img : images){
mesh_list = mesh_generator.generateSimplifiedMesh(img);
bullet.addMesh(mesh_list[0], mesh_list[1], img.getTexture());
mesh_list.clear();
}
// for(auto& img : images){
// mesh_list = mesh_generator.generateSimplifiedMesh(img);
// bullet.addMesh(mesh_list[0], mesh_list[1], img.getTexture());
// mesh_list.clear();
// }
last_updated_time = ofGetElapsedTimef();
server = std::make_unique<Server>(6762, embed, vp_tree, false, "192.168.0.253", 2000, "search");
createNodes("data/json/embeddings.json");
server = std::make_unique<Server>(6762, embed, vp_tree, nodes, false, "192.168.0.253", 2000, "search");
server->start();
}
@ -144,7 +120,7 @@ void ofApp::update(){
std::cout << "Model did not run" << std::endl;
}
bullet.update();
//bullet.update();
}
//--------------------------------------------------------------
@ -153,7 +129,7 @@ void ofApp::draw(){
ofPushStyle();
map_fbo.begin();
ofClear(ofColor::grey);
bullet.draw();
//bullet.draw();
map_fbo.end();
ofPopStyle();
@ -251,59 +227,102 @@ void ofApp::getNearestImages(){
model_image_esp.setFromPixels(esp_comp_pixels);
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
void ofApp::createNodes(std::string json_path){
}
/* read in json */
json = ofLoadJson(json_path);
//--------------------------------------------------------------
void ofApp::keyReleased(int key){
}
if(!json.is_array()){
ofLogError() << "json is not array";
return;
} else {
ofLogNotice() << "json loaded";
}
//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){
/* setup nodes */
for(const auto& j : json){
if(j.contains("vector") && j["vector"].is_array()){
Node n;
n.img.load(j["image"]);
std::vector<float> t_embedding;
for (const auto& value: j["vector"]){
if(value.is_number()){
t_embedding.push_back(value.get<float>());
} else {
ofLogError() << "Vector value is not a number";
}
}
n.raw_embedding = t_embedding;
nodes.push_back(n);
}
}
ofLogNotice() << "node count: " << nodes.size();
}
/* build vp_tree */
auto vectors = createDoubleVectorFromNodes(nodes);
vp_tree.buildTree(vectors);
ofLogNotice() << "vpt built";
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
/* run tsne */
vector<vector<float>> tsne_input;
std::vector<std::vector<double>> tsne_points;
}
for(const auto& n : nodes){
tsne_input.push_back(n.raw_embedding);
}
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
}
tsne_points = tsne.run(tsne_input, dims, perplexity, theta, normalise, runManually);
//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){
for(size_t i = 0; i < tsne_points.size(); i++){
const auto& vec = tsne_points[i];
auto& n = nodes[i];
n.tsne_position = (glm::vec3(vec[0] * tsne_scale, vec[1] * tsne_scale, -5.0f));
}
}
/* vp-test */
// auto queries = server->generateRandomVectors(10, 7);
//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){
// int k = 5;
}
// vector<vector<float>> test_vectors;
//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){
// // Set up random number generator
// std::random_device rd;
// std::mt19937 gen(rd());
// std::uniform_real_distribution<> dis(0.0, 1.0); // Random floats between -1 and 1
}
// for (int i = 0; i < 1; ++i) {
// std::vector<float> vec;
// for (int j = 0; j < 7; ++j) {
// vec.push_back(static_cast<float>(dis(gen)));
// }
// test_vectors.push_back(vec);
// }
//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){
// std::cout << test_vectors.size() << std::endl;
// vector<int> q_index = vp_tree.query(test_vectors, 5);
}
//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){
std::vector<std::vector<double>> ofApp::createDoubleVectorFromNodes(const std::vector<Node>& nodes) {
std::vector<std::vector<double>> result;
result.reserve(nodes.size());
}
for (const auto& node : nodes) {
std::vector<double> doubleVector;
doubleVector.reserve(node.raw_embedding.size());
//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){
for (const float& value : node.raw_embedding) {
doubleVector.push_back(static_cast<double>(value));
}
result.push_back(std::move(doubleVector));
}
return result;
}
void ofApp::exit(){

29
src/ofApp.h

@ -10,6 +10,7 @@
#include "onnx/ModelThread.h"
#include "network/Request.h"
#include "network/Server.h"
#include "ofxTSNE.h"
class ofApp : public ofBaseApp{
@ -18,18 +19,8 @@ class ofApp : public ofBaseApp{
void update();
void draw();
void getNearestImages();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void mouseEntered(int x, int y);
void mouseExited(int x, int y);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
void createNodes(std::string json_path);
std::vector<std::vector<double>> createDoubleVectorFromNodes(const std::vector<Node>& nodes);
void exit();
ofEasyCam cam;
@ -52,6 +43,7 @@ class ofApp : public ofBaseApp{
ofPlanePrimitive plane;
ofTexture bayer;
VP vp_tree;
/* onnx */
@ -72,5 +64,18 @@ class ofApp : public ofBaseApp{
vector<ofFbo> esp_images;
ofPixels esp_comp_pixels;
float last_updated_time;
/* nodes */
ofJson json;
vector<Node> nodes;
ofxTSNE tsne;
int dims = 2;
float perplexity = 20;
float theta = 0.2;
bool normalise = true;
bool runManually = false;
float tsne_scale = 1000;
};

38
src/vp/VP.cpp

@ -23,9 +23,39 @@ vpt::VpTree VP::loadTree(std::string path){
void VP::saveTree(std::string filename, vpt::VpTree& tree){
tree.save(filename);
ofLogNotice() << "vpt saved";
}
vpt::VpTree VP::buildTree(std::vector<vpt::Vector> vectors){
vpt::VpTree tree(vectors);
return tree;
}
void VP::buildTree(std::vector<vpt::Vector> vectors){
t = std::make_unique<vpt::VpTree>(vectors);
saveTree("./data/new_tree.bin", *t);
}
vector<int> VP::query(vector<vector<float>> _embedding, int k){
vector<int> indexes;
vector<vector<double>> query_double;
for (const auto& vec : _embedding) {
vector<double> temp;
temp.reserve(vec.size());
for (float f : vec) {
temp.push_back(static_cast<double>(f));
}
query_double.push_back(std::move(temp));
}
for (const auto& q : query_double) {
auto [distances, indices] = t->getNearestNeighbors(q, k);
std::cout << "Query: ";
for (double d : q) std::cout << d << " ";
std::cout << "\nNearest neighbors:\n";
for (int i = 0; i < k; ++i) {
indexes.push_back(indices[i]);
}
}
return indexes;
}

14
src/vp/VP.h

@ -4,11 +4,17 @@
#include <random>
#include <chrono>
#include "VpTree.hpp"
#include "ofMain.h"
class VP{
public:
std::vector<std::vector<double>> generateRandomVectors(int count, int dimension);
vpt::VpTree loadTree(std::string path);
void saveTree(std::string filename, vpt::VpTree& tree);
vpt::VpTree buildTree(std::vector<vpt::Vector> vectors);
std::vector<std::vector<double>> generateRandomVectors(int count, int dimension);
vpt::VpTree loadTree(std::string path);
void saveTree(std::string filename, vpt::VpTree& tree);
void buildTree(std::vector<vpt::Vector> vectors);
void setVPTree(vpt::VpTree _tree);
vector<int> query(vector<vector<float>> _embedding, int k);
std::unique_ptr<vpt::VpTree> t;
};

Loading…
Cancel
Save