Sunday, April 24, 2011

Epilines are Co-linear

Just as the dataset up-ended some assumptions I made about automating single-camera calibration and made me have to rewrite some code, the same is true of stereo calibration.

Epipolar Lines and Corresponding Points


664.018066  1742.919556   Slope: 0.793310
524.132874  1583.951416   Slope: 0.779278
408.092316  1452.080811   Slope: 0.767639
290.211090  1318.118286   Slope: 0.755814
1.257200  989.745667   Slope: 0.726830
315.574677  1346.942017   Slope: 0.758358
144.123520  1152.101563   Slope: 0.741160
-164.351868  801.544434   Slope: 0.710218
-646.410828  253.723633   Slope: 0.661864

avg err = 2.38012 (in pixels)

The good news is that the epipolar lines are pretty close to colinear, which will make later calculations much easier.  

Saturday, April 23, 2011

Lucas Kanade isn't going so well.

This week I got a huge database of LUMIS images. Unfortunately, they don't work very well with Lucas Kanade. I think this has to do with the brightness consistency constraints (even after histogram matching). I think its related to finding large number of local minimum when the brightness constancy constraint is changed even a bit. 

Image Subtraction (ghostly parts and blurring are bad)

*The box is a subset of the image being used for matching. 

However, affine transformations do capture the transformation pretty well, even when we aren't taking images of a flat calibration grid:

Image Subtraction after histogram equalization and an affine transformation derived from hand chosen points


The sum of square differences increased 3 fold, but they're still acceptable. 

Thursday, April 21, 2011

Histogram matching

Histogram matching seems like a pretty good segmentation technique. The first row below is the left image, the right image, and the differences after an affine transformation. The second row is the same, but with histogram equalization. 

The average pixel difference dropped from 38 to 4, and I got it down to < 2 by cropping out the sections of the image that aren't visible in the other view.

It should be noted that there will still be some residual error from the affine transformation, so < 2 is pretty remarkable. I just hope this stands up to fluorescence!

Pure Translation isn't an Accurate Motion Model

I just figured I'd give it a try. This problem would have been very easy if was. In the following images, shadowy white parts are bad

Affine (the best so far) image subtraction


Pure Translation image subtraction


Sum of square differences increased 50%

Wednesday, April 20, 2011

Segmentation Hell: I'm in It

Recap from the weekend: I was reading papers related with Lucas-Kanade and collecting different implementations. I wanted to learn how some more advanced implementations work for my own sake.

Today I got down to comparing different implementations. In the name of K.I.S.S (Keep It Simple, Stupid), I started with OpenCV's pyramid-based Lucas Kanade, but it was totally failing because of my violations to constant brightness. My attempts at segmentation were not very good:

Basic LOG at different thresholds:



 Added a Histogram equalization stage. 

Friday, April 15, 2011

Affine or Projective?

Today I hand clicked some 'base truth' correspondences so I can use them as a metric for image registration later on and play around with transformations. I wanted to make sure the affine transformation was a good estimate.

Subtracting Upper Left Camera from Upper Right Camera



Affine Transformation + Image Subtraction: SoSD = 658.7664


Projective Transformation + Image Subtraction: SoSD = 911.9480

*SoSD = Sum of Square Differences

These images are a lot better than what I'm expecting, but still, it looks like an affine 'motion model' will do fine. 

EDIT: Below are the raw images. 



Thursday, April 14, 2011

First LUMIS2 Data: Calibration + Registration

Reflections on First LUMIS2 Image Set
Paul sent me calibration images today (pictured above) that were a little different from what I expected. Above are the images taken from the upper right camera. As a training set, it has some pretty radical changes in position (which is a good thing), but I did not count on some features like, I don't know, the big rock on the calibration pattern. Last week I wrote some OpenCV calibration code that is really difficult to modify to account for the fact that half the pattern is occluded, my world coordinate system's origin can't be in the extreme upper left of the pattern (because its missing in a lot of views), and I have 90 degree changes in angle. Bouguet's toolbox should handle it fine though. It was kind of silly for me to assume a perfect training set would be given to me when I have so much trouble collecting images from a compound camera system ABOVE water.

Recap: Last week I was writing calibration code in OpenCV C++ rather than just using Bouguet Matlab because I thought OpenCV's object-oriented code would be easier to modify to 'augment the distortion model.' It looks like I'm back to Matlab, though. At least for the time being. Coding the OpenCV calibration code was good practice and I might go back to it later.

Bouguet Calibration
Next up, I tested how well distortion models in the Bouguet toolbox accounted for radial distortion.

'Typical' consumer camera radial distortion













LUMIS2's radial distortion components


Yikes! But even with this extreme distortion I got pretty good reprojection error (measured in pixels):

Upper Left Camera
Before recomp corners + 2nd calib: [ 0.65965   0.88664 ]
After  recomp corners + 2nd calib:  [ 0.61634   0.83943 ]

Upper Right Camera
Before recomp corners + 2nd calib: [ 0.55489   0.85606 ]
After  recomp corners + 2nd calib:   [ 0.54128   0.70904 ]

Lower Left Camera

Before recomp corners + 2nd calib: [ 0.55489   0.85606 ]
After  recomp corners + 2nd calib:   [ 0.54128   0.70904 ]

As a frame of reference, I can usually get the FUJI 2-view camera to calibrate to around .2 pixel error, so these are pretty good results. Its small enough that we can work with it, but large enough that there's room for improvement and more investigation. 

Undistortion in OpenCV
A practical piece of software for the LUMIS2's GUI will be undistorting the images given these estimated parameters. I spent a good part of today getting Matlab to output OpenCV matrix files, and having OpenCV undistort based on them. (the documentation was awful)

Distorted Image


After Undistortion


Image Registration
There's a large class of image registration algorithms that assume that your two views have a small baseline. In CSE 252a we implemented one to do video stabilization. The gyst is that given two frames, you use Lucas Kanade to get the optical flow, you use the optical flow to define an affine transformation from one pose to the other, and you transform one image onto the other. The advantage of an algorithm like this is that you don't need to know any scene geometry, and its extremely well documented. I thought this would be out of the question given our wide baseline with respect to the image depth, but the disparity didn't seem too extreme. 

Left Camera Image Subtracted from Right


I remember from cse252a that a 'jump' between frames like this happen often and can be corrected, especially if you refine your algorithm with course-to-fine techniques. 

These algorithms are so common I knew there had to be some good starter code somewhere, and I hit pay-dirt here: http://www.codeproject.com/KB/recipes/ImgAlign.aspx

I fired up the algorithm and here are my results:

Cropped Portion of Right Cameras View


Left Camera View with Above Image Outlined in White


The algorithm was slow as dirt though, so there's definitely plenty of room for refinement. Initializing the affine transformation matrix to something like the extrinsic parameters from calibration should speed things up. Also, Serge turned me onto a paper that uses a similar algorithm that's catered specifically for multi-spectral images.  Additionally, this algorithm only works well when the cropped portion of one image is ENTIRELY contained in the other, and that's a weak point of the implementation.

Finally, stitching the images and presenting them is a whole science on its own.