From c062e52ad21440b69ec7096e37b0fc3346465328 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Thu, 13 Mar 2014 16:21:36 +0000 Subject: working with flann --- offsetProject/config.make | 4 +- offsetProject/src/imageStore.h | 198 +++++++++++++++++++++++------------------ offsetProject/src/ofApp.cpp | 12 ++- 3 files changed, 121 insertions(+), 93 deletions(-) (limited to 'offsetProject') diff --git a/offsetProject/config.make b/offsetProject/config.make index f34a338..6edaada 100644 --- a/offsetProject/config.make +++ b/offsetProject/config.make @@ -78,7 +78,7 @@ ################################################################################ # PROJECT_LDFLAGS=-Wl,-rpath=./libs -PROJECT_LDFLAGS= -ljsoncpp +PROJECT_LDFLAGS= -ljsoncpp -lflann ################################################################################ # PROJECT DEFINES @@ -140,5 +140,5 @@ PROJECT_LDFLAGS= -ljsoncpp # (default) PROJECT_CC = (blank) # Note: Leave a leading space when adding list items with the += operator ################################################################################ -#PROJECT_CXX = colorgcc +PROJECT_CXX = g++ #PROJECT_CC = colorgcc diff --git a/offsetProject/src/imageStore.h b/offsetProject/src/imageStore.h index 5f30163..8d1b584 100644 --- a/offsetProject/src/imageStore.h +++ b/offsetProject/src/imageStore.h @@ -7,6 +7,10 @@ #include "ofMain.h" #include "ofxJSONElement.h" +#include "ofxOpenCv.h" +//#include + +using namespace cvflann; long ofToLong(const string& intString); @@ -19,15 +23,39 @@ class imageStore : public ofThread{ std::string instagram_url; ofxJSONElement response; std::map images; + vector imageptrs; deque to_update; + //Matrix dataset; doesn't need to be retained? + + //need to be able to add arbitrary data and keep it? + //see pucilar behaviour if we delete the data after indexing it + //we see some puzzling performance anomalies if we add data + //maybe rebuild the index rather than use index.addPoints() + //this way the data can be kept contiguously + //or maybe just get a pointer to vector data with an offset + vector data; + //to begin, get a single point per image + + //retain a pointer to the flann indexer + Index >* index; + + //Index > index(dataset, cv::flann::KDTreeIndexParams(4)); + imageStore(){ instagram_url = "https://api.instagram.com/v1/tags/tycleeson/media/recent?client_id=c1d74d701fdf4ddd9f8d30ee9e8f944b"; interval=5.00f; ofImage img; img.allocate(MAX_TILE_SIZE,MAX_TILE_SIZE,OF_IMAGE_COLOR); + img.clear(); + img.setUseTexture(true); + img.update(); images["000000"]=img; colours["000000"]=ofColor(0,0,0); + + } + ~imageStore(){ + delete index; } void set_interval(float _interval){ @@ -49,85 +77,66 @@ class imageStore : public ofThread{ //how to make the search algorithm faster and better //http://www.semanticmetadata.net/lire/ - /* - 1. The box nature of the image matching isn't appealing - 2. The way that the images flip quickly isn't appealing - - can we improve this by changing the screen gradually in some way? - - search tree/ octree - - each node associates an image, start with a black image - - a node owns a volume of RGB space - - new image: determine which octant it lands in - subdivide the octant in R, G or B and give half to each image - - Q: does this lead to the possibility that images end up in the wrong place? - - with the naive algorithm, we measure distance between the colours in RGB space - - it becomes a long process because the number of calculations increases exponentially - - space partitioning: we observe that the image will often be nearest to an image in the same box - although it may not be if they are at the edges - - so at each level, each node of the tree contains a list of images - - we traverse the tree and try to find the lowest level box with a match - if the lowest level box with a match has more than 1 we compute distance? - - a difference algorithm - minimise the error - this involves comparing every pixel though - - gpu? - - put every quarter of every image into an image tree - - every image has an entry on levels 1-8 - start at level 8 (most detailed) - check the leaf node ie 10110101 01101001 00110101 - if there are 1 or more images here choose one - if none go to the next level... - - ie 1011010 0110100 0011010 - if there are more than 1 images here find the nearest - if there is 1 choose it - if there are none go to the next level - - */ - - std::map colours; ofImage& get_image(const ofColor& col){ //float shortest_dist=999999.0f; int sd=1000; ofImage& im=images.begin()->second; - std::string s=images.begin()->first; - for (map::iterator it=images.begin();it!=images.end();++it){ - ofColor& c=colours[it->first]; - int rd=c.v[0]-col.v[0]; - int gd=c.v[1]-col.v[1]; - int bd=c.v[2]-col.v[2]; - //float dist=pow((float)((rd*rd)+(gd*gd)+(bd*bd)),0.5); - int dist=abs(rd)+abs(gd)+abs(bd); - if (distsecond; - s=it->first; - } - } + if( lock() ){ + std::string s=images.begin()->first; + for (map::iterator it=images.begin();it!=images.end();++it){ + ofColor& c=colours[it->first]; + int rd=c.v[0]-col.v[0]; + int gd=c.v[1]-col.v[1]; + int bd=c.v[2]-col.v[2]; + //float dist=pow((float)((rd*rd)+(gd*gd)+(bd*bd)),0.5); + int dist=abs(rd)+abs(gd)+abs(bd); + if (distsecond; + s=it->first; + } + } + unlock(); + } //cerr<<"got image "<second; + if( lock() ){ + float* test=new float[3]; + test[0]=r; + test[1]=g; + test[2]=b; + Matrix query(test,1,3); + Matrix indices(new int[1], query.rows, 1); + Matrix dists(new float[1], query.rows, 1); + index->knnSearch(query, indices, dists, 1,SearchParams(4)); + im=*imageptrs[*indices[0]]; + //int i=rand()%imageptrs.size(); + //im=images[imageptrs[i]]; + //cerr<<"returning image "< dataset(&data[0],data.size()/3,3); + index= new Index >(dataset, KDTreeIndexParams(4)); + index->buildIndex(); + + unlock(); } cout << "Api: " << instagram_url<::iterator i=images.begin();i!=images.end();++i){ - // if(i->second.isUsingTexture()){ - // drawcount++; - // } - //} - //cout<<"loaded "<::iterator i=images.begin();i!=images.end();++i){ + if(i->second.isUsingTexture()){ + drawcount++; + } + } + cout<<"loaded "<