Project 3: Robust 2D Image Warper


Overview:

In this project, you will apply what you learned about estimation in Chapter 3 to greatly improve Project 2's 4-point-correspondence code.  All these estimation ideas apply equally well to 3D projective space, but are much more tedious to implement.

The overall problem is the same as Project 2: we have photographs of a tabletop taken by an unknown camera from unknown positions.  This time we have only point positions (no lines) measured from the tabletop and the photographs,  and we have many more point pairs to use--many more than just 4.  However, this time we are more realistic: there are slight Gaussian-distributed random errors in all the position measurements, both on the tabletop and on the photos.  Your mission is to write a program to use these multiple measurements, direct linear transformation (DLT), and the Sampson Error measure to compensate for these errors and get an accurate estimate of the H matrix despite these measurement errors.

Assignment:

Your program should do each one of these things:

    1) Read a text only 'hint' file (defined below) to get measurements and determine the task.  You will need to extend your reader from Project 2 to accept these new command lines, where <numPts> is a single number (a <FloatEntry>) that gives the number of  point pairs it will use.  After one of these command lines you will find a series of <numPairs> commands, each one holding one pair of corresponding points in a single 'group_point_3' command line.

            $do_ptDLTnorm_3  <numPairs> 
                                                -- or >4 point correspondence pairs Xi, do DLT using normalization to 
                                                    find 3x3 H matrix
            $do_ptSampsonOnce_3   <numPairs>  
                                                -- for >4 point correspondence pairs Xi do DLT to find 3x3 H matrix (once).
                                                    Then use this fixed H with the Sampson Error method once to find and print 
                                                    estimates X^_i.
             $do_ptSampson_3    <numPairs>
                                                -- Same as do_ptSampsonOnce_3, except the Sampson Error method is used
                                                    iteratively to improve the point pair estimates X^_i, running until each point pair
                                                    estimate X^_i changes by less than 1/4096 on each iteration. 
EXTRA CREDIT:
            $do_ptReproject_3  <numPairs>  
                                                -- for >4 point correspondences, perform do_ptSampson3 iteratively, adjusting
                                                    estimates of both H and Xi. Choose your own stopping criterion; show
                                                    convergence.

2) Implement the 'do_ptDLTnorm_3' command.   Start with a working copy of the naive 4-point-correspondence solver you wrote for Project 2, but then update it to:
        a) Accept more than 4 point pairs.  Remember, SVD works fine for a 'tall' A matrix.
        b) Read and use the x3 (e.g. the 'w') value of the points it reads,
        c) Solve Hx <cross> x'=0, instead of Hx - x'=0;  this means your solver will read and use the 3rd entry
             in a point_3 command; it will NOT assume that w and w' are always equal to 1.
        d) Normalize input values to negate the errors due to DLT's non-invariance (pg 92 in book).
        e) Copy the input hintfile to the output, and append the H matrix to the end, as in Project 2.

3) Next, implement the 'do_ptSampsonOnce_3' command.  
    a)  Begin by calling your improved DLT command to find a good initial estimate for H.  
            Remember that you will not change this H at all in part 3).
    b) using this H (which minimizes algebraic error only, not geometric error), use Sampson Error 
            measure to find an estimate for each point pair Xi.  Do not iterate: apply the Sampson error 
            estimate only once.
    c) Copy the input hintfile to the output , followed by the H matrix found (as in Project 2), and append 
            a text list of correction vectors <delta>_X, listed in the same order as the point pairs in the input 
            file.  Correction vectors hold 4  elements; print all 4 on one line using Matrx::prnt()  (there is a
            Matrx::transpose() function you can use to convert column vectors to row vectors).

4) Finally the 'do_ptSampson_3' command uses the Sampson method iterative.  
    a) Begin by calling 'do_ptSampsonOnce_3' to find a good initial estimate of the H matrix and point pair 
            estimates X^_i.  Remember that the Sampson method only finds a first-order approximation of the 
            nearest point on the variety v_h.  
    b) Apply the Sampson error method iteratively to improve all point-pair estimates X^_i.  On each iteration 
            for each point pair estimate X^_i,  add all or part of the computed error vector <delta_X> to X^_i.  
            Each estimate X^_i should rapidly converge to a point on the variety v_h, or in plain English, the point 
            pair will satisfy 
            (Hx <cross> x' = almost 0), or equivalently, ||Ah||^2= almost 0, or ||C_H(X_i)||^2=almost zero.  
            Stop when each the ||X^_i||^2 changes by less than 1/1024 per iteration.
    c) Copy the input hintfile to the output (as in Project 2), and print H & correction vectors as in part 3) above.

5) Extra Credit Only:  Extend your iterative method to adjust both H matrix and point estimates for minimum reprojection error.  Does your method converge with randomly generated noise?

Vital Details:

Though I encourage you to incorporate your work into the 3D viewer you made in Project 1, it is not required.  
You will not be penalized in any way if you choose instead to write a stand-alone, command-line driven program invoked by:

    proj3 infile.hint outfile.hint

If MFC is your friend, then you may prefer to incorporate a file reader and writer for these 'hint' files into your viewer so you can see their results on-screen.  Either way, don't let the vagaries of Windows MFC programming frustrate you or eat up too much of your time; it's the projective geometry that matters here.

The hint file format is the same one used in Project 2.  The only changes are the 3 additional commands listed above.

Also as in Project 2, you can easily make your own test data.  Please post them to the newsgroup if you wish to share them.  I suggest that you:
1) Construct a simple H matrix, perhaps containing integers.
2) Generate a sequence of random point_3 input points--(your code can now accept ANY x,y,w values).
3) Apply your H matrix to compute output points.
4) These point pairs correspond perfectly--they are all 'on the variety v_h'.  First make sure your code can handle these properly.
5) Next, try adding small random errors to these 'perfect' input and output points--try corrupting just one point pair at first, and see if your Sampson method can remove it and report the error to you.
6) Finally, add random errors to all the points, and see how well your estimator extracts H from the noise and undoes the corruptions you added.
______________________________________________________________