sublimated

Making cvCalcCovarMatrix act like MATLAB

For an online Mahalanobis distance calculator, Connsynn set out to use OpenCV’s built in functions. However to her surprise there were few good examples of computing covariance matrices with OpenCV and fewer whose results matched MATLAB and Mathematica’s output. Just to save other folks the trouble, below is a quick test program. You can verify that its results match WolframAlpha’s for Covariance[{{38, 55, 49},{43, 54, 4}}]

#include <iostream>
#include <fstream>
#include <cv.h>
#include <highgui.h>

using namespace std;
using namespace cv; 

// OpenCV Covariance Example
// Chye Connsynn and Carson Reynolds March 23, 2011
// An example that computes a covariance matrix
// Tested using OpenCV 2.2 on OS X 10.6.7

int main( int argc, char** argv ) {
  // Input matrix size
  const int rows = 2;
  const int cols = 3;  

  // Input matrix
  float x[rows][cols] = {{38, 55, 49},
			 {43, 54, 4}};

  // Place input into CvMat**
  CvMat** input = new CvMat*[rows];		
  for(int i=0; i<rows; i++) {
    input[i] = cvCreateMat(1, cols, CV_32FC1);
    for(int j=0; j<cols; j++) {
      cvmSet(input[i], 0, j, x[i][j]);
    }
  }

  // Covariance matrix is N x N,
  // where N is input matrix column size
  const int n = cols;

  // Output variables passed by reference
  CvMat* output = cvCreateMat(n, n, CV_32FC1);
  CvMat* meanvec = cvCreateMat(1, rows, CV_32FC1);

  // Calculate covariance matrix
  cvCalcCovarMatrix((const void **) input, \
		    rows, output, meanvec, CV_COVAR_NORMAL);

  //Show result
  cout << "Covariance matrix:" << endl;
  for(int i=0; i<n; i++) {
    for(int j=0; j<n; j++) {
      cout << "(" << i << "," << j << "): ";
      // normalize by n - 1 so that results are the same 
      // as MATLAB's cov() and Mathematica's Covariance[]
      printf ("%f ", cvGetReal2D(output,i,j) / (rows - 1));
      cout << "\t";
    }
    cout << endl;      
  }
  return(0);
}

Using the terminal to monitor bandwidth and processor utilization on remote machines

Now that I have started working with some custom Linux kernels for the Gumstix Overo, I find I often need to keep a build machine churning. This wouldn’t really go smoothly without the following small command-line tools:

    htop: visually displays processor utilization
    iftop: same as the above, but for bandwidth instead

Recombining the above, you can keep a remote computer busily working and look at a glance at how your build is progressing.

Benchmarking frames per second when using OpenCV’s cvCaptureFromCAM

I find myself benchmarking a lot of cameras these days. Oddly, the OpenCV stuff (e.g. CV_CAP_PROP_POS_MSEC) which you’d tend to use seems to work well for recorded video files but not live capture. But no matter, an FPS meter is a trivial undertaking:

#include <cv.h>    
#include <highgui.h>

#include <time.h>
#include <stdio.h>

using namespace std;

int main(int argc, char** argv)
{
  // OpenCV Capture object to grab frames
  CvCapture *capture = cvCaptureFromCAM(0);

  // start and end times
  time_t start, end;

  // fps calculated using number of frames / seconds
  double fps;

  // frame counter
  int counter = 0;

  // floating point seconds elapsed since start
  double sec;

  // start the clock
  time(&start);
  
  while(cvGrabFrame(capture))
    {
      // grab a frame
      IplImage *frame = cvRetrieveFrame(capture);

      // see how much time has elapsed
      time(&end);

      // calculate current FPS
      ++counter;		
      sec = difftime (end, start);      
      
      fps = counter / sec;

      // will print out Inf until sec is greater than 0
      printf("FPS = %.2f\n", fps);
    }
	
  cvReleaseCapture(&capture);
  return 0;
}

Maybe Connsynn will find this an interesting alternative to her FPS calculation approach?

Shuffled standard input or shuffled files

Every now and then I like to shuffle a file or a directory. Here is a trivial shuffle script in Ruby:

#!/usr/bin/ruby

# output randomly shuffled lines from the file passed as an argument
# or input fed to standard input
# ex: ls | shuffle.rb 
# This produces a randomly shuffled directory

# a modified version of the code from http://bit.ly/dUdAb9
# shuffle modified from "Programming in Ruby" by Thomas and Hunt

# get the lines:
if ARGV.size == 1
  lines = IO.readlines(ARGV[0])
elsif not ARGF.eof?
  lines = ARGF.readlines
else
  abort "usage: shuffle.rb <file>"
end

# pick a random line, remove it, and print it
lines.size.times do
  print lines.delete_at(rand(lines.size))
end

Image Difference with OpenCV

Connsynn and I are working on a system to track tears. As part of it, we built a very quick image difference program to track motion between frames (to find things like blinks). As there wasn’t a clear example of using cvAbsDiff (which is a bit better than cvSub) we thought it’d be good to post ours. The program, image-diff.cpp follows:

#include <cv.h>
#include <highgui.h>

int main ( int argc, char **argv )
{
  // use first camera attached to computer
  CvCapture *capture;
  capture = cvCaptureFromCAM( 0 );
  assert( capture );

  // image data structures
  IplImage *img1;	
  IplImage *img2;
  IplImage *imggray1;
  IplImage *imggray2;
  IplImage *imggray3;
		
  // get the camera image size
  IplImage *imgsize;
  imgsize = cvQueryFrame( capture );
  if( !imgsize ) return -1;

  // grayscale buffers
  imggray1 = cvCreateImage( cvGetSize( imgsize ), IPL_DEPTH_8U, 1);
  imggray2 = cvCreateImage( cvGetSize( imgsize ), IPL_DEPTH_8U, 1);
  imggray3 = cvCreateImage( cvGetSize( imgsize ), IPL_DEPTH_8U, 1);
  
  int key = 0;
  while ( key != 'q' ) {
    // load image one
    img1 = cvQueryFrame( capture );	
 
   // convert rgb to grayscale
    cvCvtColor( img1, imggray1, CV_RGB2GRAY );
    
    // quit if user press 'q' and wait a bit between images
    key = cvWaitKey( 500 );
    
    // load image two
    img2 = cvQueryFrame( capture );

    // convert rgb to grayscale
    cvCvtColor( img2, imggray2, CV_RGB2GRAY );
    
    // compute difference
    cvAbsDiff( imggray1, imggray2, imggray3 );
    
    // display difference
    cvNamedWindow( "video", 1 );
    cvShowImage( "video", imggray3 );
  }

  // release camera and clean up resources when "q" is pressed
  cvReleaseCapture( &capture );
  cvDestroyWindow( "video" );
  return 0;
}

Here is a Makefile which uses g++ and assumes you have OpenCV installed. For it to work properly, the file above needs to be saved as image-diff.cpp in the same directory as the Makefile. It was tested using OS X and Macports, but will probably also work on Ubuntu, Linux, or anything with g++, pkg-config and OpenCV.

NAME = image-diff
CC = g++
CFLAGS = -Wall -g -O0 `pkg-config --cflags opencv`
LIBS = `pkg-config --libs opencv`

all:
	$(CC) $(CFLAGS) $(LIBS) $(NAME).cpp -o $(NAME)

UPDATE: 12/12/2011 added simplified Makefile, fixed image color conversion ordering bug

Online Textbooks: Downloading and Merging Multiple Chapters

Sometimes clueful authors provide PDF copies of their texts for free. Oft-times these same folks link a separate PDF for each chapter, which is convenient for browsing but annoying if you want to copy the whole text for off-line browsing and reference.

Case in point, Cain has a great list of online math texts. He has also co-authored with Herod a nice Multivariable Calculus text.

An elementary programming exercise: download each chapter as quickly as possible and assemble them into a single PDF. My own answer:


# grab the PDFs linked from the book's webpage
wget -r --no-directories --no-parent -A.pdf http://people.math.gatech.edu/~cain/notes/calculus.html
# join the PDFs
pdftk *.pdf cat output multivariable-calculus.pdf

2010 or MMX

There it is. Gazing in the mirrors on our shoes to see what pops
out. Hobnobbing with the hyper-colored 90s, 20 years later.

Standard Issue:

(1) The Radio Dept. [Clinging to a Scheme]
(2) Bikini [RIPJDS]
(3) Caribou [Swim]
(4) Deerhunter [Halcyon Digest]
(5) Small Black [New Chain]
(6) Crystal Castles [Crytstal Castles]
(7) Robyn [Body Talk]
(8) Sufjan Stevens [The Age of Adz]
(9) Baths [Cerulean]
(10) Konono Nº1 [Assume Crash Position]

Honorable Mention:

Everything Everything [Man Alive]
Halfby [The Island of Curiosity]
Kanye West [My Beautiful Dark Twisted Fantasy]
Optimo (Espacio) [fabric 52]
Love is All [Two Thousand and Ten Injuries]

Albums that I only really started listening to this year, but came out sometime before then:

John Cage [Sonatas and Interludes]
Neon Indian [Psychic Chasms]
Bitte Orca [Dirty Projectors]
Empire of the Sun [Walking on a Dream]
Benjamin Britten [Peter Grimes]

Also, check out this ranking
thread
at the populist site, reddit.

An OpenCL hello world using cuda on arch linux

I’ve been maintaining cuda on arch linux for about a year now. One thing I’ve always wanted is a simple hello world example to get going. Recently, I found an OpenCL hello world written for Linux.

Here is a quick set of instructions to build and run the hello world on arch linux:

1) Install cuda using yaourt. (If you haven’t installed yaourt do so with these instructions).

yaourt -S cuda

2) After cuda is installed, download the hello world source file:

wget http://donkey.vernier.se/~yann/hellocl.c

3) Compile the file using nvcc:

nvcc -lOpenCL hellocl.c -o helloworld

4) If that succeeds, try to run the example:

./helloworld

It ought to output the following:

Uryyb, Jbeyq!
Hello, World!

Now you have a simple, working example of OpenCL code. Hope that helps get you hacking your GPU.

Emacs with Japanese Apple Keyboards

Previously, I found a quick hack to cause the ¥ key on Apple Macbooks to emit a backslash in Emacs, which is handy for programming.

It turns out that works only with Macbooks and not other Apple system / keyboard combos. After some more research, I found another workaround to get backslashes out of Emacs in general and Aquamacs in particular. On the off-chance that you’re not a Japanese reader, add the following line to your .emacs file:

(setq ns-alternate-modifier 'option)

This will cause the option key with yen key (⌥+¥) to send a backslash. This work-around more closely imitates OS X behavior with Japanese keyboards.

Update:

The previous solution overrides the use of option for the meta-key. After asking for some help on stackoverflow, I found this as a better workaround:

(global-set-key (quote [134217893]) "\\")

This causes ⌥+¥ to output \ as expected without overriding the meta-key.

How many physical cores on Linux

Suppose you want to write a script which parallelizes building a large program. You could just assume that everyone has dual-core, but that would saturate a single core and under-utilize a hex core. A smarter method would be to set N in make’s -jN to be proportional to the number of physical cores in your computer. Over at how-to geek there is a script which gets close. However, when you have a hyperthreaded processor, their technique will over-report the number of actual cores. Here is a slightly more complex script which will extract the number of cores from cpuinfo:

grep "$cpu cores" /proc/cpuinfo | head -n 1 | cut -d ' ' -f 3

If you execute this on a Core i7 the script finds the actual number of physical cores:

$ grep "$cpu cores" /proc/cpuinfo | head -n 1 | cut -d ' ' -f 3
4