The Python scripts (which can export to an ImageJ file) Todd Zimmerman has been working on have been on pause during the school year due to teaching demands, but I hope we can produce some custom Python scripts that people can download. Most of our process has been based off what Ken Mankoff has published on his blog, which has been followed up with a lot of trial and error.
For this post, I'll talk a little bit about the process that I used to make images like this:
These currently produce 640x480 pixel images - but I'm hoping we can tap into the raw output and expand it to 1024x768. The uncertainty in image quality jumps considerably when the sensor is more than 1 meter away from the table, so maximizing precision means sacrificing field of view. The x/y view at 1m distance is a little more than 1m, so with one sensor, we can cover about half the table. Since the very top reach of the Em2 is occupied by the flow output and the lower reach is occupied by the standpipe, you get about 60% coverage of the effective stream table. That's not bad, but we're tempted to get a 2nd Kinect and set it up so their fields of view overlap in the middle and get the upper and lower portions.
I've started using a "C-Stand" to mount the Kinect sensor more directly above the Em2 - it's much more flexible in terms of positioning than a tripod. They're not built to be lightweight. The steel tube construction is pretty bulletproof and stays put. Now I just need another one to mount some good directional lighting to help bring out texture and detail.
The Kinect is set up to dump the data to a Linux computer sitting on the back table, Todd wrote a script to run the program so we can create a specific folder to contain all the data and also add a text file with a brief description of the experimental conditions. It's very convenient - plus our naming convention of each data folder as YYYYMMDD_EXPERIMENT-TYPE means the directories are easy to sort through. Particularly useful because the narrowed view of the stream table means it's hard to tell what we were doing by the appearance of the RGB image.
To get a first look at the 3D data, there are a couple of ways to go about it. I've been using the 3D Surface Plot plugin and you can choose to open one .pgm file in ImageJ and from the top menus select "Plugins > Interactive 3D Surface Plot." You'll see the 3D viewer and options to change the color ramp, scaling, etc. But one of the reasons we go through all the effort to get the raw .pgm files is because we can combine several hundred images into a single stack and create an averaged view.
To create an image stack use the "File > Import > Image Sequence" to select the folder with a bunch* of .pgm files. You may need to allocate more memory to the program, since a stack of 1000 images is over 1GB in size.
*I used to drag a few hundred files into ImageJ and then turn those open images into a stack, but the results were unpredictable (not all the files would be included in the stack, so I would have to stack the stacks using the "Concatenate" command from the "Stack" menu.
Once I have a stack, I want to render it as a 3D surface (ImageJ uses the 16-bit grayscale values 0-64,0000 for the Z-axis values by default). I choose "Stack > Z-Project"and then pick "Average Intensity" to account for the variation of individual pixels. You can also select "Standard Deviation" or "Median" if you're curious to look at other characteristics of the data.
When in the 3D Surface Plotter, you can use one of the .ppm files to drape an RGB image onto the plot (to produce the image at the start of this post.
So what can I do right now? Here are a few examples:
You can see the lower edge drops off in this surface model.
Mapping the standard deviation, you can see where the scanner was having trouble getting data. (standing water can interfere with the IR laser the Kinect uses to measure distance).
There's a Contour Plotter plugin that you can use to map contours - haven't figured out how to export these contours directly onto the 3D image (I draped a screen shot of the contour output onto the 3D surface).
So for now, I'm making very pretty pictures with ImageJ. If I didn't want more quantified results, this might be enough. But I'd really like to tack numbers onto this output, and compare stream profiles that are produced by changing inputs like discharge and sediment supply.