I had a think about the algorithm we might use for the phase camera measurement. MATLAB has an fft function that will allow us to extract the data that we need with a single command.
We record a series of images from a camera and put them into a 3D array or movie, image_arr, where the array parameters are [x-position, y-position, time], i.e. a 2D slice is a single frame from the camera. Then we can do an FFT on that object with the syntax, f3D = fft(image_arr, [ ], 3), which only does the FFT on the temporal components. The resulting object is a 3D array where each 2D slice is an 2D array of amplitude and phase information across the image for a single temporal frequency of the movie.
So if we recorded a movie for 1s where the sample rate is 58Hz, then the 1st frame of f3D is just a DC image of the movie, the 2nd frame are the complex 1Hz components of the movie, etc all the way up to 29Hz.
Suppose then that we have a image, part of which is being modulated, e.g. a chopper wheel rotating at 20 or 24Hz, or a laser beam profile which contains a 1kHz beat between a sideband and a reference beam. All we have to do is sample at at least twice that modulation frequency, run the command in MATLAB, and then we immediately get an image which contains the phase and magnitude information that we're interested in (in the appropriate 2D slice o the FFT).
As an example, I recorded 58 frames of data from a camera, sampling at 58Hz, which was looking at a spinning chopper wheel. There was a white sheet of paper behind the wheel which was illuminated from behind by a flashlight. The outer ring was chopping at 24Hz and the inner ring was chopping at 20Hz. I stuck all the images into the 3D array in MATLAB, did the transformation and picked out the DC, 20Hz and 24Hz signals. The results are shown in the attached PDFs which are:
You can, and I have, run the MATLAB engine from C directly. This will allow you to transfer the data from the camera to MATLAB directly in memory, rather than via the disk, but it does need proper memory allocation to avoid segmentation faults - that was too frustrating for me in the short term. In this case, the 58 frames were recorded to a file as a contiguous block of data which I then loaded into MATLAB, so it was slower than it might've otherwise been. Also the computer I was running this on was a bit of a clunker so it took a bit of time to do the FFT.
The data rate from the camera was 58fps x (1024 x 1024) pixels per frame x 2 bytes per pixel = 116MB per second. If we were to use this technique in a LIGO phase camera, where we want to measure a modulation which is around 1kHz, then we'd need a sample rate of at least 2kHz, so we're looking at at least a 30x reduction in the resolution. This is okay though - the original phase camera had only ~4000 spatial samples. So we could use, for instance, the Dalsa Falcon VGA300 HG which can give 2000 frames per second when the region of interest is limited to 64 pixels high.
% load a raw data file into MATLAB
fid = fopen('phase_camera_data.dat');
n1 = 750;
A3D = ones(n1, n1, 58);
for jj = 1:58
A = fread(fid, [1024, 1024], 'uint16');
A3D(:,:,jj) = A((512-floor(n1/2)):(512-floor(n1/2))+n1-1, ...