Keeping your installations running forever on OSX

August 27th, 2013

Recently I had to build a Kiosk style app for a client, implementing Kinect gesture tracking. I decided to use OpenNI for this, but being a little bit unstable, the app was crashing from time to time, and because I live in Bulgaria and the client is in Canada, it was really hard for me to debug the problem and also the crashes were rare and unpredictable. So I decided just to restart the app everytime it crashes.

At first I just made another app, which sole purpose was to “ping” the main app via OSC and if the app does not “pong” back, it will just run the main app again.

// Basic code to run the app
string theApp = "PATH_TO_APP";
string command = "/usr/bin/open \""+theApp+"\"";
system(command.c_str()); 

It worked ok, without actually crashing the main app. But here is the problem, when the app crashes, it will bring up the Crash Report pop-up and until someone dismiss it, you can not launch the app again. So the solution is to disable the Crash Report dialog, which you can do through Terminal with the following commands:

defaults write com.apple.CrashReporter DialogType none
sudo defaults write com.apple.CrashReporter DialogType none

To be honest, I am not exactly sure, if you should run this as root or just as your user, but just in case, you could do both. Have in mind that this will take effect after couple of minutes.

Ok after fixing the Crash Report issue, one more thing we must do is to keep the app on top of everything. If you are using the app in fullscreen mode, you could sort this out with just running the app in full screen on startup, but in my case the app was running in window mode, so in order to keep it on top, we must use the power of Apple Script. I could not find a different solution, NSWindow setLevel: did not work for some reason.

// I found this on Openframeworks Forum: http://forum.openframeworks.cc/index.php?topic=4764.0
// so the full credit goes to "stephanschulz"

string myAppName = "AppName";
char myScript[255];
sprintf(myScript, "osascript -e 'tell app \"System Events\"' -e 'set theApps to every process whose name contains \"%s\"' -e 'set theApp to item 1 of theApps' -e 'set frontmost of theApp to true' -e 'end tell'",myAppName.c_str());
std::system(myScript);

Run the above function every 5 minutes, so you could be sure, if any system pop-ups appears, the app will go on top of them. At last you could use the ofSetWindowPosition(0,0) (if you are using Openframeworks) to place the app’s window at a constant position everytime it starts.

If anybody has some other methods to keep their apps running, please comment below or drop me a line!

Finding joint angle with atan2()

August 8th, 2013

Here is a short Processing example how to use atan2(), it’s pretty simple, but I still find some people not using it correctly.


PVector v1 = new PVector(0,0);

void setup() {
  size(600,600);
}

void draw() {
  background(0);
  stroke(255);
  
  pushMatrix();
  translate(width/2, height/2);
  
  PVector mouseVector = new PVector(mouseX - width/2, mouseY - height/2);
  PVector nMouseVector = mouseVector.get();
  
  nMouseVector.normalize();
  
  float angle =degrees( atan2(nMouseVector.y, nMouseVector.x));
  
  if(angle < 0) {
    angle += 360; 
  }

  line(0,0,mouseVector.x, mouseVector.y);
  line(0,0,100,0);
 
  text(angle, mouseVector.x, mouseVector.y);
  popMatrix();

  
}

Simple Shape Matching with kNearest and OpenCV

May 27th, 2013

Here is a short demo of how to do a simple shape matching using the “K Nearest Neighbors” algorithm implementation that comes with OpenCV 2.4.

The process of recognition is very simple, first you need to convert some shapes to a sets of points. Then you must train and label the kNearest class with the point sets. Then you could draw some points to the screen and use the find_nearest() function to see which label does the drawn point set will match best.

Here are some code snippets for every task above:

Convert image to a point set

vector<cv::Point> points;
ofImage im;

im.loadImage("shape.jpg");

cv::Mat original;
original = ofxCv::toCv(im).clone();

// 1-channel convert
if(original.channels() == 3) {
	cv::cvtColor(original, original, CV_RGB2GRAY);
} else if(original.channels() == 4) {
	cv::cvtColor(original, original, CV_RGBA2GRAY);
}

cv::Canny(original, original, 0, 100.0);

cv::Mat dilateKernel(cv::Size(3,3), CV_8UC1, cv::Scalar(1));
cv::dilate(original, original, dilateKernel);
	
vector<vector<cv::Point> > foundc;
cv::findContours(original, foundc,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, cv::Point(0,0));
if(foundc.size() >0) {
	points = foundc[0];
} 

Training kNearest

cv::KNearest *knn;

cv::Mat trainingData(points.size(), 2, CV_32FC1);
cv::Mat trainingClasses(points.size(), 1, CV_32FC1);

// we fill the training data with the points set
// if we have couple of shapes, we must fill all points into one trainingData set
// and label accordingly

for(int i=0;i<points.size();i++) {
     trainingData.at<float>(i,0) = points[i].x;
     trainingData.at<float>(i,1) = points[i].y;
     trainingClasses.at<float>(i,0) = 1; // we label the shape as "1", the next added shape point set should be labeled as "2" and etc.
}
// train the algorithm
knn = new kNearest(trainingData, trainingClasses);

Find Matches


// points that are drawn on screen
vector<cv::Point> drawnPoints;

cv::Mat testData(drawnPoints.size(),2,CV_32FC1);
for(int i=0;i<drawnPoints.size();i++) {
      testData.at<float>(i,0) = drawnPoints[i].x;
      testData.at<float>(i,0) = drawnPoints[i].y;
}

// found will return the label that is closer to the drawn points
int found = knn->find_nearest(testData,1);

You could check out a working example at: https://github.com/kamend/kNN_ShapeMatch

Digital Merzbau

April 30th, 2013

Recently I stumbled upon this article http://www.gooood.hk/_d273178665.htm, which is about a simple proceses of generating complex forms from primitives. I couldn’t find any information, beside the instructions, so I decided to make my own implementation inside Openframeworks. The program takes OBJ files as input, then you could divide, extrude or intrude all mesh polygons and at the end save the mesh as an OBJ for importing and rendering in your favourite 3D program (Cinema 4d in my case). I plan to release the code and the program as binary as soon, as clean it up a little bit.

Here are some test renders:

face2

deer_crystal

flower

head2

inside

And just a demo of the program:

Screen Shot 2013-04-30 at 7.01.41 PM

You could follow all my experiments at: http://kamend.tumblr.com or http://pinterest.com/dimitroff/

My favorite Wolfram CA rulesets

April 17th, 2013

After watching Daniel Shiffman’s great video lecture about Wolfram’s Cellular Automata (this is plural for Cellular Automaton), I got inspired to try all rulesets one by one and see the results. Here are screenshots of my favorite ones:

WolframCA_Rule105

WolframCA_Rule101

WolframCA_Rule89

WolframCA_Rule75

WolframCA_Rule73

WolframCA_Rule45

WolframCA_Rule54

WolframCA_Rule57

WolframCA_Rule62

WolframCA_Rule30

WolframCA_Rule139

WolframCA_Rule137

WolframCA_Rule135

WolframCA_Rule129

WolframCA_Rule110

WolframCA_Rule151

WolframCA_Rule153

WolframCA_Rule163

WolframCA_Rule167

WolframCA_Rule169

WolframCA_Rule242

WolframCA_Rule215

WolframCA_Rule214

WolframCA_Rule193

WolframCA_Rule182

Kinect Delaunay

April 9th, 2013

Some fun with Delaunay Triangulation and Kinect 3D Meshes. I really love that pencil drawn like look of the images.

Kinect Delaunay from Kamen Dimitrov on Vimeo.

For the curious, here is the Openframeworks project on GitHub: https://github.com/kamend/KinectDelaunay

USB3 Extender for Pointgrey Flea3

March 19th, 2013

If anybody is looking for a good USB3 extender for their PointGrey Flea3 cam, here is one that works at full 5Gbps speed and it’s not very expensive:

Startech 10m M/F USB 3.0 Active Extension Cable

Absolut Blank

December 6th, 2012

I am happy to report our little documentary from the installation we did for the Absolut Blank campaign in Bulgaria. This is probably my favorite project for this year and really like to thank Absolut for giving us the freedom to do everything the way we wanted!

ABSOLUT BLANK | PHORMATIK from PHORMATIK on Vimeo.

Of course everything interactive was done inside Openframeworks!

My new project: Arcade “Scratch” Machine

December 4th, 2012

Here is how to turn your turntable into a game console!

Arcade “Scratch” Machine from Kamen Dimitrov on Vimeo.

More info about the project: http://www.kamend.com/projects/arcade-scratch-machine/

Few more hi-res screenshots, because the video from my camera turned out a little bit “shitty” :)

My experience with Kinect installations

November 27th, 2012

I have spent the last year, building couple of different Kinect installations, so in this post I would like to share some tips and points, which might seem rather obvious, but can be easily forgotten when building and designing your interaction software and patterns.

The Kinect IR camera does not work correctly in daylight, because the Sun emits a lot of IR light. I was really surprised the first time I had this problem and then I felt rather stupid :)

The IR light emitted by the laser gets reflected by leather clothes, shoes, so don’t get surprised when someone dressed with leather have holes in their depth image or have trouble with skeleton tracking.

Define your area of interaction, I think this is really important! You can use led strips to restrict the area, where the user gets detected and where the user must stay. The last time we used three flashlights pointing at each other, people though that they were the motion sensors and were pretty impressed, so you could definitely do some experimentation there. Defining strict borders is good, because people will know immediately where they have to stay to interact and all other people won’t interfere with the camera. Another cool trick, if you are using OpenNI and you want to restrict some parts on the left and right side, is stick tape on the sides of the IR camera.

If you are using Skeleton tracking, usually it takes like 5 secs, until the user skeleton gets detected and calibrated, so you should provide some kind of a feedback during that time, loading board or some kind of a message, that the user has been detected. People expect immediate feedback!

Mind the short people and kids! This was my first mistake with our first installation, people has to rise their hands in order to activate some elements in the installation. Software wise, I was just detecting when the blob passes certain vertical threshold, so when some kids came to try it, they could not reach the threshold.

People love their “shadow”! There is something magical, about seeing your silhouette in a different color or form, people just love that, especially if they are at a party. They will dance their ass off :) So even though sometimes rigged characters are fun, consider implementing some blobs.

I will try to add some more tips along the way, but if somebody has something else to share, please feel free to comment!