I'm giving virtual machines another go...last time I tried VMware, I thought it sucked. It wasn't free, and what it did not support firewire or accelerated graphics. I don't know (yet) whether this is any better, but I'm giving VirtualBox a try. The idea is to run an eye tracking server in the virtual machine so that I run my OS X client at the same time and thus have both server/client running on one machine. This way when I travel (if I travel with this particular eye tracker), I won't have to lug two laptops around, just my Mac. We'll see how it goes. Right now I have Windows 7 installed, or rather, confined to its virtual box and the eye tracking software is running; I just need to hook it up to the eye tracker itself via USB and see if that works. I was told it would work with Parallels, but I'm going the el-cheapo route first. So far so good...if it works as I hope, then I'll post more on which eye tracker it is and how I find software development for it. Everything should work in Qt, my platform of choice. Oh...the funny thing about Windows is that of course the major part of the installation was Windows Update, what else?! You can see that yet another update was successful :P
Saturday, May 14, 2011
Tuesday, May 10, 2011
Eye tracking station upgrades
I haven't updated the blog in a while, it's been a busy semester. However, it's ending with a lab upgrade that I've been working towards for about a year now. Ever since one of the Windows machines driving one of the eye trackers gave up the ghost and died. It was an old Sun w2100z machine probably past its life expectancy. A replacement was found, but I think they nearly had to pull it out of surplus for me. So this time around instead of mucking about with very large workstations, I decided to replace both server/client at each eye tracker with a Mac Mini. You can see the two little silver boxes in the pic. Each Mac Mini has 8 G of RAM, an Intel Core Duo chip and an Nvidia GeForce 320M chip with 72 GPU cores. Not bad for such a little box! One Mac Mini will be used to run Windows to power the Tobii eye tracker, the other will be used as the client workstation. Since most of my programs work under OS X, I'm hoping that I can develop some cool eye tracking demos on them. Including real-time heatmap rendering and GPU-based scanpath comparison. I'm now just waiting for software installs on them, and testing whether the 400-800 firewire cable will work between the server and the Tobii (it should).
Monday, February 21, 2011
Let there be light!
I had a couple of blog posts in my head that I wanted to put up here, one just from just a couple of days ago, but I don't have the pics handy...instead I'm sitting here waiting for my photon mapper to finish, so I thought I'd write a bit about that...kind of a technical post. I'll try to add a brief pictorial progression so you can see what I'm talking about. At left is a basic ray-traced image that we started with this semester (in a class I'm teaching). It's fairly simple in that we have two spheres, one (the blue one, well it's sort of blue, maybe more like chrome) more reflective than the other, which is more diffuse. There are three lights in the scene but they only show up when reflected (point light sources). The ray tracer demonstrates several concepts: object-oriented hierarchy (spheres and planes are objects), recursion (the rays shot into the scene are reflected recursively), list processing (all objects are on a list), and basic file input/output. Fairly simple, an image like that takes about 3 seconds to render.
The next image in the progression would have been the same as the first, as we explored parallelism. With chip makers now producing multi-core chipsets, one may wonder how to take advantage of the multiple cores or CPUs on the chip? The ray tracer is very well suited to this because each pixel is processed the same way. If we had as many CPU cores as pixels, we could assign each on a one-to-one mapping. My desktop machine in my office has 8 cores, so a simple speedup is to let each of the 8 cores process each of the h/8 rows of pixels. The trick here is to make sure to avoid race conditions, that is, don't let any more than one core write to a piece of shared memory. The ray tracer, in its original conception, had this problem, so this turned out to be a nice exercise, complete with garbage images if done incorrectly. The solution called for each ray to maintain its own state info, which makes perfect sense thinking in parallel. Once that's done, multi-core parallelism is pretty easy, requiring basically one line of #pragma compiler directive to use OpenMP and voila! An almost k-factor speedup for k cores available. Coincidentally, the solution also leads in to the next step of the ray tracer evolution, and that is getting transmission to work right, like you see at right: we not only have reflective objects but transmissive (transparent) ones now.
Once we have the notion of independent rays (in terms of memory access anyway), then it's not a huge conceptual leap to think of photons instead of rays. These are shot from the light sources within the scene in a stochastic (random) sort of way. They reflect or transmit from/through objects just like rays, except that there's a finite number of photons—each makes its way through the scene unlike rays which recursively spawn new rays at each intersection point. Based on random conditions, photons eventually stick to surfaces, like shown at left. One of the goals of this type of photon mapping is to be able to render caustics, or focused concentration of photons, more or less. When rendering, what's important is the number of photons per unit area (why not volume?), that is, their density is what we're after. (Note: for those of you observant enough, you'll see that the photon map I have here doesn't match the other images—you're correct; this photon map, with only one light source, is what I used for debugging. It was clearer using one light that the caustic was not showing up opposite to where the light source was—turns out I was calculating distance incorrectly, d'oh!)
Sum up the photons' "flux" per ray intersection point, divide by their squared radius, and presto! We have caustics. Photon mapping also demonstrates a key aspect of careful program design: at each intersection point one has to find a number of the closest photons. The image at right shows 20 photons sampled at each intersection point from 2,000 initially shot out (fairly small numbers all told). With these numbers the image is rendered in about a minute. Increasing those numbers by an order of magnitude to 100 samples from 10,000 photons initially shot yields about a 9-minute render time. Meanwhile, increasing yet again to 500,000 photons and 500 samples takes...I don't yet know, still waiting...on the order of hours I expect. Ding! Just done "baking": 188.6 minutes, yup 3.14 (pi?) hours. The key aspect of program design is this search for closest photons—the program uses a kd-tree to find the k-closest photons in O(log n) time. It has to do this for every intersection point, of which there is a very large number. If no kd-tree was used, then the search would take O(n) every time, and I suspect it would have taken a lot longer to complete, perhaps days. So was all that extra number-crunching time worth it? Below are two images (10,000 photons on the left 500,000 photons on the right) that match the photon map above. See the difference? One could argue that the caustic boundaries and the caustic itself are a bit crisper in the image at right, but are they worth three hours?
Saturday, January 1, 2011
Happy New Year!
Saturday, December 25, 2010
Milford Sound
Sunday, December 19, 2010
Horsing Around Te Anau
Friday, December 10, 2010
Road to Te Anau
Thursday, November 25, 2010
Bluff
Saturday, November 20, 2010
Tautuku Bay
Road to Dunedin
Queenstown, NZ
Saturday, November 6, 2010
Flight to NZ
Thursday, October 28, 2010
Oct.22 Gig at Wingin' It
Wednesday, October 20, 2010
Dylan
Hounds at Friar's Tavern
Saturday, September 11, 2010
Luggage refit
Tuesday, August 3, 2010
Real-time heatmaps
|
|
Some of you already know what the above images are about, but I'm so happy about getting this to work, that I thought I'd post a blog about it. It happens to coincide with the end of this year's REU (Research Experience for Undergraduates) program during which I had 5 undergrads in the lab working on several eye tracking projects. This year it was all about video, which prompted me to develop the program responsible for drawing the above images. Collecting eye movement data (x,y,t) over video is what I worked on in Barcelona. It took me pretty much most of those 6 weeks to get enough C/C++ code together to be able to display video while recording gaze data. Once that was done, I handed the program over to the REUs who then ran four studies and who also extended the program to do various other things. Meanwhile, the whole effort motivated me to figure out how to display the captured data atop the video frames as a means to visualize the recorded gaze data. The algorithm for generating the above heatmaps is pretty straightforward and is well-known. Step 1 involves dropping a Gaussian point-spread function at each gaze location, growing the resultant heightfield with as many gaze points as collected per each video frame. Step 2 requires finding the maximum value in the heightmap. Sounds easy, but for an NxN image, it takes O(N^2) operations. Step 3 then requires normalization of the heightfield (division by the max value). Step 4 then recolors the height (luminance) by mapping it to the rainbow color palette. The last two steps, which can be combined into one, together take another O(N^2) steps. The image above at left was created this way for a data set of 24 scanpaths (sequence of gaze points) on the CPU. Looks good but it's slow (took about a minute). The image at right took only a fraction of a second and looks almost identical. The trick here is to use the GPU to reduce the number of operations form order O(N^2) to O(log(N)) for the max value localization and O(1) for the recoloring. On one particular workstation with a decent graphics card I observed a 700-fold speedup due to these reductions. That just blew me away, which is why I'm so excited about this development. I recently moved that bit of GPU code onto my video playing code and sure enough, even for a fairly large data set (oh, about 8 people or so), the code appears to play the video at real-time (30 Hz) rates. I suppose I should take timings of this just to confirm how long it takes...this could make a nice little paper someplace. Other eye tracking types might like to know how the whole thing is put together...
Monday, July 12, 2010
Reedy River Gig
The pic is back from our gig on July 7th. Right in the middle of a heat wave, when it went up to 98F. If I look like I'm trying to concentrate, I was. I don't know whether it was the heat, the Gretsch drums, or something else or a combination of factors, but I was not having a good first set. I think it played ok, but I know I made a couple of flubs here and there. I pulled out my old Gretsch drums but I haven't played on them in a very long time. Lately I've been playing on the Tama rockstar kit I traded for my old Pintech electronic set. I like the Tama's larger toms and I think its compactness—one less floor tom. The Gretsch kit has two floor toms and maybe because of that seems more spread out. I remember missing the right crash symbol because it was out of my immediate reach (had to stretch for it). So after the gig I transferred the bass drum's resonant head (with the band name on it) onto the Tama kit and bagged the Tama kit. I don't think I'll be using the Gretsch kit any more, so it may be time to start looking for a new owner for that kit. Right during setup I busted a resonant head on the small 10" tom...it sounded kinda crappy the rest of the night, another reason for a lackluster first set...once I got into the habit of going for the second tom, and the temperature went down, the second set was much better.
Tuesday, July 6, 2010
Greenville Gig at Reedy River
Tomorrow the Hoodoo Hounds play at the Reedy River Nighttime Concert Series. Just ahead of this gig we got a story on us printed in the Greenville News, our local city paper, as you see above. The full story can be found here.
Monday, July 5, 2010
4th of July
As soon as I got back from Barcelona, it was straight back to work. I was already a week behind on my meetings with this year's REU students, so it's been pretty hectic. Today is the last day of the 4th of July long weekend, and since I'm stuck at home on the couch, I thought I'd update the blog. Somehow I managed to pull my left pec muscle a couple of days ago, which is why I'm sitting here coding and not out on the boat. I guess it must have been lugging the new sailboat battery that did it, but I can't be sure. All I know is my left pec is so painful that it's difficult to breathe. I wanted to get out on the sailboat, give it a nice cleaning, and putt around on it, but I'm having trouble moving around much. It's nice to have caught up to some badly needed coding, but it's really nice outside, too... Hopefully this goes away by tomorrow, because that's when I need to load up the truck with my drum gear for Wednesday's Greenville gig. Tonight is band practice, when I'll see how I can play in this condition. Major annoyance. Anyway, above is a short video of the fireworks that the city of Clemson puts on every year at the YMCA beach. We get out there on the motorboat and sit and watch (a major reason for getting the powerboat back in '03 I think it was—the idea was to have it on the water by July 4th—I think we got it in the water just in time). This is the first video upload I've done on the blog, hopefully it turns out ok. I shot the vid on my iPhone, so it may be a little blurry, although I think it managed to focus itself fairly well.











