001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package org.openimaj.image.feature.local.interest.experiment;
031
032import gnu.trove.list.array.TDoubleArrayList;
033
034import java.io.BufferedReader;
035import java.io.File;
036import java.io.FileInputStream;
037import java.io.IOException;
038import java.io.InputStream;
039import java.io.InputStreamReader;
040import java.util.ArrayList;
041import java.util.HashSet;
042import java.util.List;
043import java.util.PriorityQueue;
044import java.util.Set;
045
046import org.apache.log4j.BasicConfigurator;
047import org.apache.log4j.Level;
048import org.apache.log4j.Logger;
049import org.openimaj.feature.local.ScaleSpaceLocation;
050import org.openimaj.image.DisplayUtilities;
051import org.openimaj.image.Image;
052import org.openimaj.image.ImageUtilities;
053import org.openimaj.image.MBFImage;
054import org.openimaj.image.colour.ColourSpace;
055import org.openimaj.image.colour.RGBColour;
056import org.openimaj.image.colour.Transforms;
057import org.openimaj.image.feature.local.interest.EllipticInterestPointData;
058import org.openimaj.image.feature.local.interest.InterestPointData;
059import org.openimaj.image.feature.local.interest.InterestPointDetector;
060import org.openimaj.image.feature.local.interest.InterestPointVisualiser;
061import org.openimaj.knn.CoordinateKDTree;
062import org.openimaj.math.geometry.line.Line2d;
063import org.openimaj.math.geometry.point.PayloadCoordinate;
064import org.openimaj.math.geometry.point.Point2d;
065import org.openimaj.math.geometry.point.Point2dImpl;
066import org.openimaj.math.geometry.shape.Ellipse;
067import org.openimaj.math.geometry.shape.EllipseUtilities;
068import org.openimaj.math.geometry.shape.Rectangle;
069import org.openimaj.math.geometry.transforms.TransformUtilities;
070import org.openimaj.util.pair.IndependentPair;
071import org.openimaj.util.pair.Pair;
072
073import Jama.Matrix;
074
075/**
076 * An interest point repeatability as originally implemented <a
077 * href="http://www.robots.ox.ac.uk/~vgg/research/affine/evaluation.html"
078 * >here</a>.
079 * <p>
080 * We find some interest points in two images, and the known homography to go
081 * from image 1 to image 2
082 * <p>
083 * We apply this exhaustively to a pairwise matching of each feature to each
084 * other feature and compare the distances of the transformed features from the
085 * second image to the features in the first image. If the pair distance is
086 * below a give threshold they are placed on top of each other and their overlap
087 * measured.
088 * <p>
089 * Repeatability is measured at a given overlap threshold, if two feature point
090 * ellipses overlap over a certain percentage of their overall size then those
091 * features are counted as repeatable. The repeatability of a given IPD for a
092 * given pair of images is the proportion of repeatable features for a given
093 * maximum distance and a given overlap percentage.
094 * 
095 * @author Sina Samangooei (ss@ecs.soton.ac.uk)
096 * 
097 * @param <T>
098 *            The type of {@link InterestPointData}
099 */
100public class IPDRepeatability<T extends InterestPointData> {
101
102        static Logger logger = Logger.getLogger(IPDRepeatability.class);
103        static {
104                BasicConfigurator.configure();
105                logger.setLevel(Level.INFO);
106        }
107
108        /**
109         * A pair of matching features with a score
110         * 
111         * @author Sina Samangooei (ss@ecs.soton.ac.uk)
112         * 
113         * @param <B>
114         * @param <T>
115         */
116        public static class ScoredPair<B extends Comparable<B>, T extends Pair<B>>
117                        implements Comparable<ScoredPair<B, T>>
118        {
119                private T pair;
120                private double score;
121
122                ScoredPair(T pair, double score) {
123                        this.pair = pair;
124                        this.score = score;
125                }
126
127                @Override
128                public int compareTo(ScoredPair<B, T> that) {
129                        int diff = Double.compare(this.score, that.score);
130                        if (diff != 0)
131                                return -diff;
132                        else {
133                                diff = this.pair.firstObject().compareTo(
134                                                that.pair.firstObject());
135                                if (diff == 0) {
136                                        return this.pair.secondObject().compareTo(
137                                                        that.pair.secondObject());
138                                }
139                                return diff;
140                        }
141                }
142        }
143
144        private Matrix homography;
145        private List<Ellipse> validImage2Points;
146        private List<Ellipse> validImage1Points;
147        private List<ScoredPair<Integer, Pair<Integer>>> prunedOverlapping;
148        private double maximumDistanceMultiple = 4;
149        private int imageWidth;
150        private int imageHeight;
151
152        public IPDRepeatability() {
153        }
154
155        /**
156         * Check the repeatability against two imags, two sets of points and a
157         * homography between the two images.
158         * 
159         * @param image1
160         * @param image2
161         * @param image1Points
162         * @param image2Points
163         * @param homography
164         */
165        public IPDRepeatability(Image<?, ?> image1, Image<?, ?> image2,
166                        List<Ellipse> image1Points, List<Ellipse> image2Points,
167                        Matrix homography)
168        {
169                setup(image1, image2, image1Points, image2Points, homography);
170        }
171
172        /**
173         * Check the repeatability between two images from files, an interest point
174         * detector used to find the feature points in the images and a homography
175         * from a file. The homography file has the format:
176         * 
177         * number number number number number number number number number
178         * 
179         * @param image1f
180         * @param image2f
181         * @param ipd
182         * @param homographyf
183         * @throws IOException
184         */
185        public IPDRepeatability(File image1f, File image2f,
186                        InterestPointDetector<T> ipd, File homographyf) throws IOException
187        {
188                final MBFImage image1 = ImageUtilities.readMBF(image1f);
189                final MBFImage image2 = ImageUtilities.readMBF(image2f);
190
191                ipd.findInterestPoints(Transforms.calculateIntensityNTSC(image1));
192                final List<T> image1Points = ipd.getInterestPoints(20);
193                ipd.findInterestPoints(Transforms.calculateIntensityNTSC(image2));
194                final List<T> image2Points = ipd.getInterestPoints(20);
195
196                final List<Ellipse> image1Ellipse = new ArrayList<Ellipse>();
197                final List<Ellipse> image2Ellipse = new ArrayList<Ellipse>();
198                for (final InterestPointData d : image1Points)
199                        image1Ellipse.add(d.getEllipse());
200                for (final InterestPointData d : image2Points)
201                        image2Ellipse.add(d.getEllipse());
202
203                final Matrix homography = readHomography(homographyf);
204                setup(image1, image2, image1Ellipse, image2Ellipse, homography);
205        }
206
207        /**
208         * Two images, features extracted using ipd, homography found in stream. See
209         * {@link IPDRepeatability}
210         * 
211         * @param image1
212         * @param image2
213         * @param ipd
214         * @param homographyf
215         * @throws IOException
216         */
217        public IPDRepeatability(MBFImage image1, MBFImage image2,
218                        InterestPointDetector<T> ipd, InputStream homographyf)
219                        throws IOException
220        {
221
222                ipd.findInterestPoints(Transforms.calculateIntensityNTSC(image1));
223                final List<T> image1Points = ipd.getInterestPoints(20);
224                ipd.findInterestPoints(Transforms.calculateIntensityNTSC(image2));
225                final List<T> image2Points = ipd.getInterestPoints(20);
226
227                final List<Ellipse> image1Ellipse = new ArrayList<Ellipse>();
228                final List<Ellipse> image2Ellipse = new ArrayList<Ellipse>();
229                for (final InterestPointData d : image1Points)
230                        image1Ellipse.add(d.getEllipse());
231                for (final InterestPointData d : image2Points)
232                        image2Ellipse.add(d.getEllipse());
233
234                final Matrix homography = readHomography(homographyf);
235                setup(image1, image2, image1Ellipse, image2Ellipse, homography);
236        }
237
238        /**
239         * Two images, features extracted using ipd, homography matrix between the
240         * two images
241         * 
242         * @param image1
243         * @param image2
244         * @param ipd
245         * @param homography
246         * @throws IOException
247         */
248        public IPDRepeatability(MBFImage image1, MBFImage image2,
249                        InterestPointDetector<T> ipd, Matrix homography) throws IOException
250        {
251
252                ipd.findInterestPoints(Transforms.calculateIntensityNTSC(image1));
253                final List<T> image1Points = ipd.getInterestPoints(20);
254                ipd.findInterestPoints(Transforms.calculateIntensityNTSC(image2));
255                final List<T> image2Points = ipd.getInterestPoints(20);
256
257                final List<Ellipse> image1Ellipse = new ArrayList<Ellipse>();
258                final List<Ellipse> image2Ellipse = new ArrayList<Ellipse>();
259                for (final InterestPointData d : image1Points)
260                        image1Ellipse.add(d.getEllipse());
261                for (final InterestPointData d : image2Points)
262                        image2Ellipse.add(d.getEllipse());
263
264                setup(image1, image2, image1Ellipse, image2Ellipse, homography);
265        }
266
267        public IPDRepeatability(List<Ellipse> firstImagePoints,
268                        List<Ellipse> secondImagePoints, Matrix transform)
269        {
270                this.validImage1Points = firstImagePoints;
271                this.validImage2Points = secondImagePoints;
272                this.homography = transform;
273        }
274
275        private void setup(Image<?, ?> image1, Image<?, ?> image2,
276                        List<Ellipse> image1Points, List<Ellipse> image2Points,
277                        Matrix homography)
278        {
279                this.homography = homography;
280
281                this.validImage2Points = IPDRepeatability.validPoints(image2Points,
282                                image1, homography);
283                this.validImage1Points = IPDRepeatability.validPoints(image1Points,
284                                image2, homography.inverse());
285                this.imageWidth = image1.getWidth();
286                this.imageHeight = image1.getHeight();
287                if (logger.getLevel() == Level.DEBUG) {
288                        final MBFImage combined = new MBFImage(image1.getWidth()
289                                        + image2.getWidth(), Math.max(image1.getHeight(),
290                                        image2.getHeight()), ColourSpace.RGB);
291
292                        final InterestPointVisualiser<Float[], MBFImage> ipdv1 = new InterestPointVisualiser<Float[], MBFImage>(
293                                        (MBFImage) image1, this.validImage1Points);
294                        combined.drawImage(
295                                        ipdv1.drawPatches(RGBColour.RED, RGBColour.BLUE), 0, 0);
296                        final InterestPointVisualiser<Float[], MBFImage> ipdv2 = new InterestPointVisualiser<Float[], MBFImage>(
297                                        (MBFImage) image2, this.validImage2Points);
298                        combined.drawImage(
299                                        ipdv2.drawPatches(RGBColour.RED, RGBColour.BLUE),
300                                        image1.getWidth(), 0);
301
302                        // DisplayUtilities.displayName(combined, "valid points");
303
304                }
305        }
306
307        /**
308         * The percentage of valid points found to be repeatable. Repeatability of a
309         * given ellipse is defined by what percentage overlap there is between it
310         * and a nearby detected ellipse (after an affine transform). The
311         * repeatability of all the points in an image is defined by the proprotion
312         * of points which could catch and did match with their ellipses overlapping
313         * by more than or equal to the percentageOverlap (1 == complete overlap, 0
314         * == no overlap)
315         * 
316         * @param percentageOverlap
317         *            the percentage overlap two ellipses must be over to be
318         *            considered a "repeatable" point
319         * @return the percentage of ellipses which are repeatable
320         */
321        public double repeatability(double percentageOverlap) {
322                prepare();
323                final double potentialMatches = Math.min(this.validImage2Points.size(),
324                                this.validImage1Points.size());
325                if (potentialMatches == 0) {
326                        return 0;
327                }
328                double countMatches = 0;
329
330                for (final ScoredPair<Integer, Pair<Integer>> d : this.prunedOverlapping) {
331                        if (d.score >= percentageOverlap)
332                                countMatches++;
333                }
334                return countMatches / potentialMatches;
335        }
336
337        /**
338         * Find pairs of interest points whose ellipses overlap sufficiently and
339         * calculate how much they overlap. This function must be told what maximum
340         * distance factor is which two interest points are considered to match and
341         * therefore their overlap measured.
342         * 
343         * @return map of an interest point pair to a percentage overlap (0 >
344         *         overlap =<1.0
345         */
346        public List<ScoredPair<Integer, Pair<Integer>>> calculateOverlappingEllipses() {
347                final int smallerSetSize = Math.min(this.validImage1Points.size(),
348                                this.validImage2Points.size());
349                final PriorityQueue<ScoredPair<Integer, Pair<Integer>>> overlapping = new PriorityQueue<ScoredPair<Integer, Pair<Integer>>>(
350                                this.validImage1Points.size() * this.validImage2Points.size());
351                int oldQueueSize = 0;
352                // Map<Integer,Matrix> matrixHash1 = new HashMap<Integer,Matrix>();
353                // Map<Integer,Matrix> matrixHash2 = new HashMap<Integer,Matrix>();
354
355                final CoordinateKDTree<PayloadCoordinate<ScaleSpaceLocation, IndependentPair<Integer, Ellipse>>> tree = new CoordinateKDTree<PayloadCoordinate<ScaleSpaceLocation, IndependentPair<Integer, Ellipse>>>();
356
357                int j = 0;
358                for (Ellipse ellipse2 : this.validImage2Points) {
359                        ellipse2 = ellipse2.transformAffine(this.homography.inverse());
360                        final ScaleSpaceLocation ep = new ScaleSpaceLocation(ellipse2.calculateCentroid()
361                                        .getX(), ellipse2.calculateCentroid().getY(), (float) getRadius(
362                                        ellipse2, this.maximumDistanceMultiple));
363                        tree.insert(PayloadCoordinate.payload(ep,
364                                        new IndependentPair<Integer, Ellipse>(j, ellipse2)));
365                        j++;
366                }
367
368                int i = 0;
369                logger.debug("Checking all ellipses against each other");
370                for (final Ellipse ellipse1 : this.validImage1Points) {
371
372                        final float radius = (float) getRadius(ellipse1,
373                                        this.maximumDistanceMultiple);
374
375                        final List<PayloadCoordinate<ScaleSpaceLocation, IndependentPair<Integer, Ellipse>>> possible = new ArrayList<PayloadCoordinate<ScaleSpaceLocation, IndependentPair<Integer, Ellipse>>>();
376                        final Point2d left = ellipse1.calculateCentroid();
377                        left.translate(-radius, -radius);
378                        final Point2d right = ellipse1.calculateCentroid();
379                        right.translate(radius, radius);
380
381                        final float scaleRadius = (float) (radius * 0.5);
382
383                        tree.rangeSearch(possible,
384                                        new ScaleSpaceLocation(left.getX(), left.getY(), radius
385                                                        - scaleRadius), new ScaleSpaceLocation(
386                                                        right.getX(), right.getY(), radius + scaleRadius));
387                        // logger.debug("Checking ellipse: " + i + " found: " +
388                        // possible.size() + " nearby ellipses");
389
390                        for (final PayloadCoordinate<ScaleSpaceLocation, IndependentPair<Integer, Ellipse>> payloadCoordinate : possible)
391                        {
392                                final IndependentPair<Integer, Ellipse> pl = payloadCoordinate
393                                                .getPayload();
394                                j = pl.firstObject();
395                                final Ellipse ellipse2 = pl.secondObject();
396                                final Matrix e1Mat = EllipseUtilities.ellipseToCovariance(ellipse1)
397                                                .inverse();
398                                final Matrix e2Mat = EllipseUtilities.ellipseToCovariance(ellipse2)
399                                                .inverse();
400                                final double overlap = calculateOverlapPercentageOxford(e1Mat, e2Mat,
401                                                ellipse1, ellipse2, maximumDistanceMultiple);
402                                // double overlap =
403                                // calculateOverlapPercentage(ellipse1,ellipse2,this.maximumDistanceMultiple);
404                                // if(logger.getLevel() == Level.DEBUG){
405                                // double oxfordOverlap =
406                                // calculateOverlapPercentageOxford(e1Mat, e2Mat, ellipse1,
407                                // ellipse2, maximumDistanceMultiple);
408                                // // displayEllipsesFull(ellipse1,ellipse2);
409                                // // displayEllipsesZoomed(ellipse1,ellipse2);
410                                //
411                                // logger.debug("different in overlap: " + Math.abs(overlap -
412                                // oxfordOverlap));
413                                //
414                                //
415                                // }
416                                // final float e1x = ellipse1.getCOG().getX();
417                                // final float e1y = ellipse1.getCOG().getY();
418                                // final float e2x = ellipse2.getCOG().getX();
419                                // final float e2y = ellipse2.getCOG().getY();
420                                // 130.78,y=31.68
421                                // if(e2x > 130 && e2x < 131 && e2y > 31 && e2y < 32 &&
422                                // e1x > 100 && e1x < 101 && e1y > 60 && e1y < 61){
423                                // System.out.println("FOUND IT!!");
424                                // }
425                                if (overlap >= 0) {
426                                        // System.out.println(overlap + " Adding: " +
427                                        // ellipse1.getCOG() + " -> " + ellipse2.getCOG() +
428                                        // " with score: " + overlap);
429                                        overlapping.add(new ScoredPair<Integer, Pair<Integer>>(
430                                                        new Pair<Integer>(i, j), overlap));
431                                        if (oldQueueSize == overlapping.size()) {
432                                                System.err.println("The queue didn't change in size!!");
433                                        }
434                                        oldQueueSize = overlapping.size();
435                                }
436                        }
437                        // for(Ellipse ellipse2: this.validImage2Points)
438                        // {
439
440                        // ellipse2 = ellipse2.transformAffine(this.homography.inverse());
441                        //
442                        // double overlap =
443                        // calculateOverlapPercentage(ellipse1,ellipse2,this.maximumDistanceMultiple);
444                        // if(overlap > 0){
445                        // // System.out.println(overlap + " Adding: " + ellipse1.getCOG() +
446                        // " -> " + ellipse2.getCOG() + " with score: " + overlap);
447                        // overlapping.add(new ScoredPair<Integer,Pair<Integer>>(new
448                        // Pair<Integer>(i,j), overlap));
449                        // if(oldQueueSize == overlapping.size()){
450                        // System.err.println("The queue didn't change in size!!");
451                        // }
452                        // oldQueueSize = overlapping.size();
453                        // }
454
455                        // }
456                        i++;
457                }
458                logger.debug("pruning overlapping ellipses, finding best case for each ellipse");
459                final List<ScoredPair<Integer, Pair<Integer>>> prunedOverlapping = pruneOverlapping(
460                                overlapping, smallerSetSize);
461                return prunedOverlapping;
462        }
463
464        @SuppressWarnings("unused")
465        private static void displayEllipsesZoomed(Ellipse ellipse1, Ellipse ellipse2) {
466                final int zoomHeight = 400;
467                final int zoomWidth = 400;
468
469                final int midzoomx = zoomWidth / 2;
470                final int midzoomy = zoomHeight / 2;
471
472                final double e1Radius = getRadius(ellipse1, 1);
473
474                final double scale = (zoomWidth * 0.50) / e1Radius;
475                final Matrix scaleMatrix = TransformUtilities.scaleMatrixAboutPoint(
476                                1 / scale, 1 / scale, 0, 0);
477                final MBFImage zoomed = new MBFImage(zoomWidth, zoomHeight, ColourSpace.RGB);
478                Matrix translateE1 = Matrix.identity(3, 3);
479                translateE1 = translateE1.times(TransformUtilities
480                                .translateToPointMatrix(new Point2dImpl(0, 0), new Point2dImpl(
481                                                midzoomx, midzoomy)));
482                translateE1 = translateE1.times(scaleMatrix);
483                translateE1 = translateE1.times(TransformUtilities
484                                .translateToPointMatrix(ellipse1.calculateCentroid(),
485                                                new Point2dImpl(0, 0)));
486
487                final Ellipse expandedTranslated1 = ellipse1.transformAffine(translateE1);
488                final Ellipse expandedTranslated2 = ellipse2.transformAffine(translateE1);
489                zoomed.drawShape(expandedTranslated1, RGBColour.RED);
490                zoomed.drawShape(expandedTranslated2, RGBColour.BLUE);
491
492                DisplayUtilities.displayName(zoomed, "zoomed image");
493                System.out.println();
494        }
495
496        @SuppressWarnings("unused")
497        private void displayEllipsesFull(Ellipse ellipse1, Ellipse ellipse2) {
498                final MBFImage debugDisplay = new MBFImage(this.imageWidth, this.imageHeight,
499                                ColourSpace.RGB);
500                debugDisplay.drawShape(ellipse1, RGBColour.RED);
501                debugDisplay.drawShape(ellipse2, RGBColour.BLUE);
502                debugDisplay
503                                .drawShape(
504                                                ellipse2.calculateRegularBoundingBox().union(
505                                                                ellipse1.calculateRegularBoundingBox()),
506                                                RGBColour.BLUE);
507                DisplayUtilities.displayName(debugDisplay, "debug display full");
508        }
509
510        private static double getRadius(Ellipse ellipse,
511                        double maximumDistanceFactor)
512        {
513                double maxDistance = Math
514                                .sqrt((ellipse.getMajor() * ellipse.getMinor()));
515                maxDistance *= maximumDistanceFactor;
516                return maxDistance;
517        }
518
519        private List<ScoredPair<Integer, Pair<Integer>>> pruneOverlapping(
520                        PriorityQueue<ScoredPair<Integer, Pair<Integer>>> overlapping,
521                        int smallerSetSize)
522        {
523                // Use the priority queue to perform a greedy optimisation.
524                // Once you see a pair don't allow any other pair involving either
525                // element
526                final Set<Integer> seenE1 = new HashSet<Integer>();
527                final Set<Integer> seenE2 = new HashSet<Integer>();
528                final List<ScoredPair<Integer, Pair<Integer>>> prunedOverlapping = new ArrayList<ScoredPair<Integer, Pair<Integer>>>();
529                while (overlapping.size() > 0 && seenE1.size() < smallerSetSize) {
530                        final ScoredPair<Integer, Pair<Integer>> scoredPair = overlapping.poll();
531                        if (!(seenE1.contains(scoredPair.pair.firstObject()) || seenE2
532                                        .contains(scoredPair.pair.secondObject())))
533                        {
534                                prunedOverlapping.add(scoredPair);
535                                seenE1.add(scoredPair.pair.firstObject());
536                                seenE2.add(scoredPair.pair.secondObject());
537                        } else {
538                        }
539                }
540                return prunedOverlapping;
541        }
542
543        /**
544         * Generates and initialises a new Repeatability instance. The percentage of
545         * valid points found to be repeatable. Repeatability of a given ellipse is
546         * defined by what percentage overlap there is between it and a nearby
547         * detected ellipse (after an affine transform). The repeatability of all
548         * the points in an image is defined by the proprotion of points which could
549         * catch and did match with their ellipses overlapping by more than or equal
550         * to the percentageOverlap (1 == complete overlap, 0 == no overlap)
551         * 
552         * @param img1
553         * @param img2
554         * @param e1
555         * @param e2
556         * @param transform
557         * 
558         * @param maximumDistanceMultiple
559         *            The distance multiple at which point two interest points are
560         *            considered to be "close"
561         * @return the percentage of ellipses which are repeatable
562         */
563        public static IPDRepeatability<EllipticInterestPointData> repeatability(
564                        Image<?, ?> img1, Image<?, ?> img2, List<Ellipse> e1,
565                        List<Ellipse> e2, Matrix transform, double maximumDistanceMultiple)
566        {
567                final IPDRepeatability<EllipticInterestPointData> rep = new IPDRepeatability<EllipticInterestPointData>(
568                                img1, img2, e1, e2, transform);
569                rep.maximumDistanceMultiple = maximumDistanceMultiple;
570                rep.prepare();
571                return rep;
572        }
573
574        public static <T extends InterestPointData> IPDRepeatability<T> repeatability(
575                        MBFImage image1, MBFImage image2, List<T> interestPoints1,
576                        List<T> interestPoints2, Matrix transform,
577                        int maximumDistanceMultiple2)
578        {
579                final List<Ellipse> image1Ellipse = new ArrayList<Ellipse>();
580                final List<Ellipse> image2Ellipse = new ArrayList<Ellipse>();
581                for (final InterestPointData d : interestPoints1)
582                        image1Ellipse.add(d.getEllipse());
583                for (final InterestPointData d : interestPoints2)
584                        image2Ellipse.add(d.getEllipse());
585
586                logger.debug("Comparing: " + image1Ellipse.size() + " to "
587                                + image2Ellipse.size() + " ellipses");
588
589                final IPDRepeatability<T> rep = new IPDRepeatability<T>(image1, image2,
590                                image1Ellipse, image2Ellipse, transform);
591                rep.maximumDistanceMultiple = 4;
592                rep.prepare();
593                return rep;
594        }
595
596        private void prepare() {
597                if (this.prunedOverlapping == null)
598                        this.prunedOverlapping = calculateOverlappingEllipses();
599        }
600
601        /**
602         * Use the transform to call find the location sourceImage.getBounds() in
603         * another image. Drop points from allPoints which are not within the
604         * transformed bounds
605         * 
606         * @param allPoints
607         * @param sourceImage
608         * @param transform
609         * @return ellipses
610         */
611        public static List<Ellipse> validPoints(List<Ellipse> allPoints,
612                        Image<?, ?> sourceImage, Matrix transform)
613        {
614                final List<Ellipse> valid = new ArrayList<Ellipse>();
615                final Rectangle validArea = sourceImage.getBounds();
616                for (final Ellipse data : allPoints) {
617                        if (data.calculateCentroid().getX() == 294.079f
618                                        && data.calculateCentroid().getY() == 563.356f)
619                        {
620                                System.out.println();
621                        }
622                        // data.getCOG().transform(transform.inverse())
623                        ;
624                        if (validArea.isInside(data.transformAffine(transform.inverse())
625                                        .calculateRegularBoundingBox()))
626                        {
627                                valid.add(data);
628                        } else {
629                        }
630                }
631                return valid;
632        }
633
634        public static List<ScoredPair<Integer, Pair<Integer>>> calculateOverlappingEllipses(
635                        List<Ellipse> firstImagePoints, List<Ellipse> secondImagePoints,
636                        Matrix transform, double maximumDistanceMultiple)
637        {
638                final IPDRepeatability<EllipticInterestPointData> rep = new IPDRepeatability<EllipticInterestPointData>(
639                                firstImagePoints, secondImagePoints, transform);
640                rep.maximumDistanceMultiple = maximumDistanceMultiple;
641                return rep.calculateOverlappingEllipses();
642        }
643
644        public static Matrix readHomography(File homographyf) throws IOException {
645                return readHomography(new FileInputStream(homographyf));
646        }
647
648        public static Matrix readHomography(InputStream homographyf)
649                        throws IOException
650        {
651                final BufferedReader reader = new BufferedReader(new InputStreamReader(
652                                homographyf));
653                final List<TDoubleArrayList> doubleListList = new ArrayList<TDoubleArrayList>();
654                String line = null;
655                int nCols = -1;
656                int nRows = 0;
657                while ((line = reader.readLine()) != null) {
658                        boolean anyAdded = false;
659                        final String[] parts = line.split(" ");
660                        final TDoubleArrayList doubleList = new TDoubleArrayList();
661                        int currCols = 0;
662                        for (final String part : parts) {
663                                if (part.length() != 0) {
664                                        anyAdded = true;
665                                        doubleList.add(Double.parseDouble(part));
666                                        currCols++;
667                                }
668                        }
669                        if (nCols == -1)
670                                nCols = currCols;
671                        if (currCols != nCols)
672                                throw new IOException("Could not read matrix file");
673                        if (anyAdded) {
674                                doubleListList.add(doubleList);
675                                nRows++;
676                        }
677                }
678                final Matrix ret = new Matrix(nRows, nCols);
679                int rowNumber = 0;
680                for (final TDoubleArrayList doubleList : doubleListList) {
681                        doubleList.toArray(ret.getArray()[rowNumber++], 0, nCols);
682                }
683                return ret;
684        }
685
686        /**
687         * The overlap of a pair of ellipses (doesn't give the same results as the
688         * oxford implementation below, TODO: FIXME :)
689         * 
690         * @param e1
691         * @param e2
692         * @param maximumDistanceFactor
693         * @return the percentage overlap with a maximum distance scaled by
694         *         maximumDistanceFactor * ellipse scale
695         */
696        public double calculateOverlapPercentage(Ellipse e1, Ellipse e2,
697                        double maximumDistanceFactor)
698        {
699                final double maxDistance = getRadius(e1, maximumDistanceFactor);
700                // This is a scaling of the two ellipses such that they fit in a
701                // normalised space
702                final double scaleFactor = getScaleFactor(e1);
703                // System.out.println("Maximum distance was: " + maxDistance);
704                if (new Line2d(e1.calculateCentroid(), e2.calculateCentroid()).calculateLength() >= maxDistance)
705                        return 0;
706                final Matrix scaleMatrix1 = TransformUtilities.scaleMatrixAboutPoint(
707                                scaleFactor, scaleFactor, e1.calculateCentroid());
708                final Matrix scaleMatrix2 = TransformUtilities.scaleMatrixAboutPoint(
709                                scaleFactor, scaleFactor, e2.calculateCentroid());
710                // Matrix scaleMatrix = TransformUtilities.scaleMatrix(1.0f, 1.0f);
711
712                // Matrix e1Trans =
713                // TransformUtilities.translateToPointMatrix(e1.getCOG(),new
714                // Point2dImpl(0,0));
715                // Matrix e2Trans =
716                // TransformUtilities.translateToPointMatrix(e2.getCOG(),new
717                // Point2dImpl(0,0));
718                final Ellipse e1Corrected = e1.transformAffine(scaleMatrix1);
719                final Ellipse e2Corrected = e2.transformAffine(scaleMatrix2);
720
721                // displayEllipsesFull(e1Corrected,e2Corrected);
722
723                final double intersection = e1Corrected.intersectionArea(e2Corrected, 50);
724                // return intersection;
725
726                final double e1Area = e1Corrected.calculateArea();
727                final double e2Area = e2Corrected.calculateArea();
728
729                return intersection
730                                / ((e1Area - intersection) + (e2Area - intersection) + intersection);
731        }
732
733        /**
734         * This is how the original matlab found the difference between two
735         * ellipses. Basically, if ellipse 1 and 2 were within a certain distance
736         * the ellipses were placed on top of each other (i.e. same centroid) and
737         * the difference between them calculated. This is simulated in a much saner
738         * way in calculateOverlapPercentage
739         * 
740         * @param e1Mat
741         * @param e2Mat
742         * @param e1
743         * @param e2
744         * @param multiplier
745         * @return the overlap percentage as calculated the matlab way (uses the
746         *         covariance matricies of the ellipses)
747         */
748        public double calculateOverlapPercentageOxford(Matrix e1Mat, Matrix e2Mat,
749                        Ellipse e1, Ellipse e2, double multiplier)
750        {
751                double maxDistance = Math.sqrt((e1.getMajor() * e1.getMinor()));
752
753                // This is a scaling of the two ellipses such that they fit in a
754                // normalised space
755                double scaleFactor = 30 / maxDistance;
756                scaleFactor = 1 / (scaleFactor * scaleFactor);
757                maxDistance *= multiplier;
758                if (new Line2d(e1.calculateCentroid(), e2.calculateCentroid()).calculateLength() >= maxDistance)
759                        return -1;
760                // System.out.println(maxDistance);
761                final float dx = e2.calculateCentroid().getX() - e1.calculateCentroid().getX();
762                final float dy = e2.calculateCentroid().getY() - e1.calculateCentroid().getY();
763
764                final double yy1 = e1Mat.get(1, 1) * scaleFactor;
765                final double xx1 = e1Mat.get(0, 0) * scaleFactor;
766                final double xy1 = e1Mat.get(0, 1) * scaleFactor;
767
768                final double yy2 = e2Mat.get(1, 1) * scaleFactor;
769                final double xx2 = e2Mat.get(0, 0) * scaleFactor;
770                final double xy2 = e2Mat.get(0, 1) * scaleFactor;
771
772                // Ellipse e1Corrected =
773                // EllipseUtilities.ellipseFromCovariance(e1.getCOG().getX(),
774                // e1.getCOG().getY(), new Matrix(new
775                // double[][]{{xx1,xy1},{xy1,yy1}}).inverse(), 1.0f);
776                // Ellipse e2Corrected =
777                // EllipseUtilities.ellipseFromCovariance(e2.getCOG().getX(),
778                // e2.getCOG().getY(), new Matrix(new
779                // double[][]{{xx2,xy2},{xy2,yy2}}).inverse(), 1.0f);
780                // displayEllipsesFull(e1Corrected,e2Corrected);
781
782                final double e1Width = Math.sqrt(yy1 / (xx1 * yy1 - xy1 * xy1));
783                final double e1Height = Math.sqrt(xx1 / (xx1 * yy1 - xy1 * xy1));
784
785                final double e2Width = Math.sqrt(yy2 / (xx2 * yy2 - xy2 * xy2));
786                final double e2Height = Math.sqrt(xx2 / (xx2 * yy2 - xy2 * xy2));
787                final float maxx = (float) Math.ceil((e1Width > (dx + e2Width)) ? e1Width
788                                : (dx + e2Width));
789                final float minx = (float) Math
790                                .floor((-e1Width < (dx - e2Width)) ? (-e1Width)
791                                                : (dx - e2Width));
792                final float maxy = (float) Math.ceil((e1Height > (dy + e2Height)) ? e1Height
793                                : (dy + e2Height));
794                final float miny = (float) Math
795                                .floor((-e1Height < (dy - e2Height)) ? (-e1Height)
796                                                : (dy - e2Height));
797
798                final float mina = (maxx - minx) < (maxy - miny) ? (maxx - minx)
799                                : (maxy - miny);
800                final float dr = (float) (mina / 50.0);
801
802                int bua = 0;
803                int bna = 0;
804                // int t1 = 0;
805
806                // Rectangle r = new Rectangle(minx,miny,maxx - minx,maxy-miny);
807                // System.out.println("Oxford rectangle: " + r);
808                // System.out.println("Oxford step: " + dr);
809                // compute the area
810                for (float rx = minx; rx <= maxx; rx += dr) {
811                        final float rx2 = rx - dx;
812                        // t1++;
813                        for (float ry = miny; ry <= maxy; ry += dr) {
814                                final float ry2 = ry - dy;
815                                // compute the distance from the ellipse center
816                                final float a = (float) (xx1 * rx * rx + 2 * xy1 * rx * ry + yy1 * ry
817                                                * ry);
818                                final float b = (float) (xx2 * rx2 * rx2 + 2 * xy2 * rx2 * ry2 + yy2
819                                                * ry2 * ry2);
820                                // compute the area
821                                if (a < 1 && b < 1)
822                                        bna++;
823                                if (a < 1 || b < 1)
824                                        bua++;
825                        }
826                }
827                return (double) bna / (double) bua;
828        }
829
830        private static double getScaleFactor(Ellipse ellipse) {
831                final double maxDistance = Math
832                                .sqrt((ellipse.getMajor() * ellipse.getMinor()));
833                // This is a scaling of the two ellipses such that they fit in a
834                // normalised space
835                final double scaleFactor = 30 / maxDistance;
836                // scaleFactor = (scaleFactor);
837
838                return scaleFactor;
839        }
840
841        /**
842         * Read an ellipses from the matlab interest point files
843         * 
844         * @param inputStream
845         * @return list of ellipses
846         * @throws IOException
847         */
848        public static List<Ellipse> readMatlabInterestPoints(InputStream inputStream)
849                        throws IOException
850        {
851                final BufferedReader reader = new BufferedReader(new InputStreamReader(
852                                inputStream));
853                reader.readLine(); // 1.0
854                reader.readLine(); // nPoints
855
856                String line = "";
857                final List<Ellipse> ret = new ArrayList<Ellipse>();
858                while ((line = reader.readLine()) != null) {
859                        final String[] parts = line.split(" ");
860
861                        final float x = Float.parseFloat(parts[0]);
862                        final float y = Float.parseFloat(parts[1]);
863                        final float xx = Float.parseFloat(parts[2]);
864                        final float xy = Float.parseFloat(parts[3]);
865                        final float yy = Float.parseFloat(parts[4]);
866
867                        final Ellipse e = EllipseUtilities.ellipseFromCovariance(x, y,
868                                        new Matrix(new double[][] { { xx, xy }, { xy, yy } })
869                                                        .inverse(), 1.0f);
870                        ret.add(e);
871                }
872                return ret;
873        }
874
875        public static void main(String args[]) throws IOException {
876                testSingleEllipseFromMatlab();
877        }
878
879        /**
880         * Check the overlap of a single ellipse using covariance numbrers loaded
881         * from matlab
882         * 
883         * @throws IOException
884         */
885        public static void testSingleEllipseFromMatlab() throws IOException {
886                final Matrix secondMoments1_220_0 = new Matrix(new double[][] {
887                                { 0.002523f, -0.000888f }, { -0.000888f, 0.000802f } });
888                final Matrix secondMoments2_220_0 = new Matrix(new double[][] {
889                                { 0.000788f, -0.000406f }, { -0.000406f, 0.000668f } });
890                final Ellipse e1_220_0 = EllipseUtilities.ellipseFromCovariance(185.130000f,
891                                139.150000f, secondMoments1_220_0.inverse(), 1.0f);
892                final Ellipse e2_220_0 = EllipseUtilities.ellipseFromCovariance(185.287320f,
893                                137.549020f, secondMoments2_220_0.inverse(), 1.0f);
894                doTest(secondMoments1_220_0, secondMoments2_220_0, e1_220_0, e2_220_0,
895                                0.533756f);
896                final Matrix secondMoments1_265_0 = new Matrix(new double[][] {
897                                { 0.002523f, -0.000888f }, { -0.000888f, 0.000802f } });
898                final Matrix secondMoments2_265_0 = new Matrix(new double[][] {
899                                { 0.000424f, -0.000377f }, { -0.000377f, 0.000993f } });
900                final Ellipse e1_265_0 = EllipseUtilities.ellipseFromCovariance(185.130000f,
901                                139.150000f, secondMoments1_265_0.inverse(), 1.0f);
902                final Ellipse e2_265_0 = EllipseUtilities.ellipseFromCovariance(178.697624f,
903                                134.167477f, secondMoments2_265_0.inverse(), 1.0f);
904                doTest(secondMoments1_265_0, secondMoments2_265_0, e1_265_0, e2_265_0,
905                                0.391304f);
906                final Matrix secondMoments1_424_0 = new Matrix(new double[][] {
907                                { 0.002523f, -0.000888f }, { -0.000888f, 0.000802f } });
908                final Matrix secondMoments2_424_0 = new Matrix(new double[][] {
909                                { 0.000315f, -0.000280f }, { -0.000280f, 0.000851f } });
910                final Ellipse e1_424_0 = EllipseUtilities.ellipseFromCovariance(185.130000f,
911                                139.150000f, secondMoments1_424_0.inverse(), 1.0f);
912                final Ellipse e2_424_0 = EllipseUtilities.ellipseFromCovariance(177.858951f,
913                                134.845534f, secondMoments2_424_0.inverse(), 1.0f);
914                doTest(secondMoments1_424_0, secondMoments2_424_0, e1_424_0, e2_424_0,
915                                0.345265f);
916                final Matrix secondMoments1_548_0 = new Matrix(new double[][] {
917                                { 0.002523f, -0.000888f }, { -0.000888f, 0.000802f } });
918                final Matrix secondMoments2_548_0 = new Matrix(new double[][] {
919                                { 0.000364f, -0.000245f }, { -0.000245f, 0.000488f } });
920                final Ellipse e1_548_0 = EllipseUtilities.ellipseFromCovariance(185.130000f,
921                                139.150000f, secondMoments1_548_0.inverse(), 1.0f);
922                final Ellipse e2_548_0 = EllipseUtilities.ellipseFromCovariance(183.986308f,
923                                136.929409f, secondMoments2_548_0.inverse(), 1.0f);
924                doTest(secondMoments1_548_0, secondMoments2_548_0, e1_548_0, e2_548_0,
925                                0.309550f);
926                final Matrix secondMoments1_664_0 = new Matrix(new double[][] {
927                                { 0.002523f, -0.000888f }, { -0.000888f, 0.000802f } });
928                final Matrix secondMoments2_664_0 = new Matrix(new double[][] {
929                                { 0.000205f, -0.000190f }, { -0.000190f, 0.000621f } });
930                final Ellipse e1_664_0 = EllipseUtilities.ellipseFromCovariance(185.130000f,
931                                139.150000f, secondMoments1_664_0.inverse(), 1.0f);
932                final Ellipse e2_664_0 = EllipseUtilities.ellipseFromCovariance(177.752180f,
933                                135.828765f, secondMoments2_664_0.inverse(), 1.0f);
934                doTest(secondMoments1_664_0, secondMoments2_664_0, e1_664_0, e2_664_0,
935                                0.269426f);
936                final Matrix secondMoments1_772_0 = new Matrix(new double[][] {
937                                { 0.002523f, -0.000888f }, { -0.000888f, 0.000802f } });
938                final Matrix secondMoments2_772_0 = new Matrix(new double[][] {
939                                { 0.000148f, -0.000150f }, { -0.000150f, 0.000561f } });
940                final Ellipse e1_772_0 = EllipseUtilities.ellipseFromCovariance(185.130000f,
941                                139.150000f, secondMoments1_772_0.inverse(), 1.0f);
942                final Ellipse e2_772_0 = EllipseUtilities.ellipseFromCovariance(176.399164f,
943                                135.967058f, secondMoments2_772_0.inverse(), 1.0f);
944                doTest(secondMoments1_772_0, secondMoments2_772_0, e1_772_0, e2_772_0,
945                                0.220970f);
946                final Matrix secondMoments1_944_0 = new Matrix(new double[][] {
947                                { 0.002523f, -0.000888f }, { -0.000888f, 0.000802f } });
948                final Matrix secondMoments2_944_0 = new Matrix(new double[][] {
949                                { 0.000099f, -0.000059f }, { -0.000059f, 0.000309f } });
950                final Ellipse e1_944_0 = EllipseUtilities.ellipseFromCovariance(185.130000f,
951                                139.150000f, secondMoments1_944_0.inverse(), 1.0f);
952                final Ellipse e2_944_0 = EllipseUtilities.ellipseFromCovariance(176.545412f,
953                                138.198624f, secondMoments2_944_0.inverse(), 1.0f);
954                doTest(secondMoments1_944_0, secondMoments2_944_0, e1_944_0, e2_944_0,
955                                0.146820f);
956                final Matrix secondMoments1_1199_0 = new Matrix(new double[][] {
957                                { 0.002523f, -0.000888f }, { -0.000888f, 0.000802f } });
958                final Matrix secondMoments2_1199_0 = new Matrix(new double[][] {
959                                { 0.000071f, 0.000024f }, { 0.000024f, 0.000094f } });
960                final Ellipse e1_1199_0 = EllipseUtilities.ellipseFromCovariance(185.130000f,
961                                139.150000f, secondMoments1_1199_0.inverse(), 1.0f);
962                final Ellipse e2_1199_0 = EllipseUtilities.ellipseFromCovariance(175.623656f,
963                                142.291151f, secondMoments2_1199_0.inverse(), 1.0f);
964                doTest(secondMoments1_1199_0, secondMoments2_1199_0, e1_1199_0,
965                                e2_1199_0, 0.069626f);
966                final Matrix secondMoments1_1269_0 = new Matrix(new double[][] {
967                                { 0.002523f, -0.000888f }, { -0.000888f, 0.000802f } });
968                final Matrix secondMoments2_1269_0 = new Matrix(new double[][] {
969                                { 0.000070f, 0.000034f }, { 0.000034f, 0.000058f } });
970                final Ellipse e1_1269_0 = EllipseUtilities.ellipseFromCovariance(185.130000f,
971                                139.150000f, secondMoments1_1269_0.inverse(), 1.0f);
972                final Ellipse e2_1269_0 = EllipseUtilities.ellipseFromCovariance(171.919962f,
973                                142.703652f, secondMoments2_1269_0.inverse(), 1.0f);
974                doTest(secondMoments1_1269_0, secondMoments2_1269_0, e1_1269_0,
975                                e2_1269_0, 0.048306f);
976                final Matrix secondMoments1_3_1 = new Matrix(new double[][] {
977                                { 0.001639f, 0.000229f }, { 0.000229f, 0.000785f } });
978                final Matrix secondMoments2_3_1 = new Matrix(new double[][] {
979                                { 0.000724f, 0.000618f }, { 0.000618f, 0.001520f } });
980                final Ellipse e1_3_1 = EllipseUtilities.ellipseFromCovariance(273.460000f,
981                                145.200000f, secondMoments1_3_1.inverse(), 1.0f);
982                final Ellipse e2_3_1 = EllipseUtilities.ellipseFromCovariance(280.304662f,
983                                140.134832f, secondMoments2_3_1.inverse(), 1.0f);
984                doTest(secondMoments1_3_1, secondMoments2_3_1, e1_3_1, e2_3_1,
985                                0.523566f);
986                final Matrix secondMoments1_4_1 = new Matrix(new double[][] {
987                                { 0.001639f, 0.000229f }, { 0.000229f, 0.000785f } });
988                final Matrix secondMoments2_4_1 = new Matrix(new double[][] {
989                                { 0.001578f, 0.000486f }, { 0.000486f, 0.000631f } });
990                final Ellipse e1_4_1 = EllipseUtilities.ellipseFromCovariance(273.460000f,
991                                145.200000f, secondMoments1_4_1.inverse(), 1.0f);
992                final Ellipse e2_4_1 = EllipseUtilities.ellipseFromCovariance(272.361295f,
993                                144.968486f, secondMoments2_4_1.inverse(), 1.0f);
994                doTest(secondMoments1_4_1, secondMoments2_4_1, e1_4_1, e2_4_1,
995                                0.751560f);
996                final Matrix secondMoments1_154_1 = new Matrix(new double[][] {
997                                { 0.001639f, 0.000229f }, { 0.000229f, 0.000785f } });
998                final Matrix secondMoments2_154_1 = new Matrix(new double[][] {
999                                { 0.000593f, 0.000661f }, { 0.000661f, 0.001310f } });
1000                final Ellipse e1_154_1 = EllipseUtilities.ellipseFromCovariance(273.460000f,
1001                                145.200000f, secondMoments1_154_1.inverse(), 1.0f);
1002                final Ellipse e2_154_1 = EllipseUtilities.ellipseFromCovariance(280.763026f,
1003                                139.853156f, secondMoments2_154_1.inverse(), 1.0f);
1004                doTest(secondMoments1_154_1, secondMoments2_154_1, e1_154_1, e2_154_1,
1005                                0.417829f);
1006                final Matrix secondMoments1_156_1 = new Matrix(new double[][] {
1007                                { 0.001639f, 0.000229f }, { 0.000229f, 0.000785f } });
1008                final Matrix secondMoments2_156_1 = new Matrix(new double[][] {
1009                                { 0.000644f, 0.000344f }, { 0.000344f, 0.000676f } });
1010                final Ellipse e1_156_1 = EllipseUtilities.ellipseFromCovariance(273.460000f,
1011                                145.200000f, secondMoments1_156_1.inverse(), 1.0f);
1012                final Ellipse e2_156_1 = EllipseUtilities.ellipseFromCovariance(275.113701f,
1013                                140.124526f, secondMoments2_156_1.inverse(), 1.0f);
1014                doTest(secondMoments1_156_1, secondMoments2_156_1, e1_156_1, e2_156_1,
1015                                0.502418f);
1016                final Matrix secondMoments1_157_1 = new Matrix(new double[][] {
1017                                { 0.001639f, 0.000229f }, { 0.000229f, 0.000785f } });
1018                final Matrix secondMoments2_157_1 = new Matrix(new double[][] {
1019                                { 0.001396f, 0.000382f }, { 0.000382f, 0.000352f } });
1020                final Ellipse e1_157_1 = EllipseUtilities.ellipseFromCovariance(273.460000f,
1021                                145.200000f, secondMoments1_157_1.inverse(), 1.0f);
1022                final Ellipse e2_157_1 = EllipseUtilities.ellipseFromCovariance(271.708659f,
1023                                149.102793f, secondMoments2_157_1.inverse(), 1.0f);
1024                doTest(secondMoments1_157_1, secondMoments2_157_1, e1_157_1, e2_157_1,
1025                                0.530884f);
1026                final Matrix secondMoments1_261_1 = new Matrix(new double[][] {
1027                                { 0.001639f, 0.000229f }, { 0.000229f, 0.000785f } });
1028                final Matrix secondMoments2_261_1 = new Matrix(new double[][] {
1029                                { 0.000609f, 0.000352f }, { 0.000352f, 0.000554f } });
1030                final Ellipse e1_261_1 = EllipseUtilities.ellipseFromCovariance(273.460000f,
1031                                145.200000f, secondMoments1_261_1.inverse(), 1.0f);
1032                final Ellipse e2_261_1 = EllipseUtilities.ellipseFromCovariance(275.617119f,
1033                                141.717819f, secondMoments2_261_1.inverse(), 1.0f);
1034                doTest(secondMoments1_261_1, secondMoments2_261_1, e1_261_1, e2_261_1,
1035                                0.416771f);
1036                final Matrix secondMoments1_513_1 = new Matrix(new double[][] {
1037                                { 0.001639f, 0.000229f }, { 0.000229f, 0.000785f } });
1038                final Matrix secondMoments2_513_1 = new Matrix(new double[][] {
1039                                { 0.000741f, 0.000225f }, { 0.000225f, 0.000221f } });
1040                final Ellipse e1_513_1 = EllipseUtilities.ellipseFromCovariance(273.460000f,
1041                                145.200000f, secondMoments1_513_1.inverse(), 1.0f);
1042                final Ellipse e2_513_1 = EllipseUtilities.ellipseFromCovariance(272.495410f,
1043                                149.946936f, secondMoments2_513_1.inverse(), 1.0f);
1044                doTest(secondMoments1_513_1, secondMoments2_513_1, e1_513_1, e2_513_1,
1045                                0.302778f);
1046                final Matrix secondMoments1_545_1 = new Matrix(new double[][] {
1047                                { 0.001639f, 0.000229f }, { 0.000229f, 0.000785f } });
1048                final Matrix secondMoments2_545_1 = new Matrix(new double[][] {
1049                                { 0.000629f, 0.000270f }, { 0.000270f, 0.000285f } });
1050                final Ellipse e1_545_1 = EllipseUtilities.ellipseFromCovariance(273.460000f,
1051                                145.200000f, secondMoments1_545_1.inverse(), 1.0f);
1052                final Ellipse e2_545_1 = EllipseUtilities.ellipseFromCovariance(273.264727f,
1053                                150.116431f, secondMoments2_545_1.inverse(), 1.0f);
1054                doTest(secondMoments1_545_1, secondMoments2_545_1, e1_545_1, e2_545_1,
1055                                0.295045f);
1056                final Matrix secondMoments1_769_1 = new Matrix(new double[][] {
1057                                { 0.001639f, 0.000229f }, { 0.000229f, 0.000785f } });
1058                final Matrix secondMoments2_769_1 = new Matrix(new double[][] {
1059                                { 0.000386f, 0.000222f }, { 0.000222f, 0.000248f } });
1060                final Ellipse e1_769_1 = EllipseUtilities.ellipseFromCovariance(273.460000f,
1061                                145.200000f, secondMoments1_769_1.inverse(), 1.0f);
1062                final Ellipse e2_769_1 = EllipseUtilities.ellipseFromCovariance(275.391351f,
1063                                152.353229f, secondMoments2_769_1.inverse(), 1.0f);
1064                doTest(secondMoments1_769_1, secondMoments2_769_1, e1_769_1, e2_769_1,
1065                                0.194111f);
1066                final Matrix secondMoments1_995_1 = new Matrix(new double[][] {
1067                                { 0.001639f, 0.000229f }, { 0.000229f, 0.000785f } });
1068                final Matrix secondMoments2_995_1 = new Matrix(new double[][] {
1069                                { 0.000217f, 0.000108f }, { 0.000108f, 0.000131f } });
1070                final Ellipse e1_995_1 = EllipseUtilities.ellipseFromCovariance(273.460000f,
1071                                145.200000f, secondMoments1_995_1.inverse(), 1.0f);
1072                final Ellipse e2_995_1 = EllipseUtilities.ellipseFromCovariance(284.495607f,
1073                                151.936791f, secondMoments2_995_1.inverse(), 1.0f);
1074                doTest(secondMoments1_995_1, secondMoments2_995_1, e1_995_1, e2_995_1,
1075                                0.114420f);
1076                final Matrix secondMoments1_1015_2 = new Matrix(new double[][] {
1077                                { 0.001145f, -0.000044f }, { -0.000044f, 0.001080f } });
1078                final Matrix secondMoments2_1015_2 = new Matrix(new double[][] {
1079                                { 0.000157f, 0.000009f }, { 0.000009f, 0.000102f } });
1080                final Ellipse e1_1015_2 = EllipseUtilities.ellipseFromCovariance(332.750000f,
1081                                191.180000f, secondMoments1_1015_2.inverse(), 1.0f);
1082                final Ellipse e2_1015_2 = EllipseUtilities.ellipseFromCovariance(334.840142f,
1083                                197.358808f, secondMoments2_1015_2.inverse(), 1.0f);
1084                doTest(secondMoments1_1015_2, secondMoments2_1015_2, e1_1015_2,
1085                                e2_1015_2, 0.113011f);
1086                final Matrix secondMoments1_1125_2 = new Matrix(new double[][] {
1087                                { 0.001145f, -0.000044f }, { -0.000044f, 0.001080f } });
1088                final Matrix secondMoments2_1125_2 = new Matrix(new double[][] {
1089                                { 0.000117f, -0.000017f }, { -0.000017f, 0.000065f } });
1090                final Ellipse e1_1125_2 = EllipseUtilities.ellipseFromCovariance(332.750000f,
1091                                191.180000f, secondMoments1_1125_2.inverse(), 1.0f);
1092                final Ellipse e2_1125_2 = EllipseUtilities.ellipseFromCovariance(336.496971f,
1093                                184.812171f, secondMoments2_1125_2.inverse(), 1.0f);
1094                doTest(secondMoments1_1125_2, secondMoments2_1125_2, e1_1125_2,
1095                                e2_1125_2, 0.076743f);
1096                final Matrix secondMoments1_1200_2 = new Matrix(new double[][] {
1097                                { 0.001145f, -0.000044f }, { -0.000044f, 0.001080f } });
1098                final Matrix secondMoments2_1200_2 = new Matrix(new double[][] {
1099                                { 0.000090f, -0.000005f }, { -0.000005f, 0.000053f } });
1100                final Ellipse e1_1200_2 = EllipseUtilities.ellipseFromCovariance(332.750000f,
1101                                191.180000f, secondMoments1_1200_2.inverse(), 1.0f);
1102                final Ellipse e2_1200_2 = EllipseUtilities.ellipseFromCovariance(336.907334f,
1103                                186.759097f, secondMoments2_1200_2.inverse(), 1.0f);
1104                doTest(secondMoments1_1200_2, secondMoments2_1200_2, e1_1200_2,
1105                                e2_1200_2, 0.061274f);
1106                final Matrix secondMoments1_1227_2 = new Matrix(new double[][] {
1107                                { 0.001145f, -0.000044f }, { -0.000044f, 0.001080f } });
1108                final Matrix secondMoments2_1227_2 = new Matrix(new double[][] {
1109                                { 0.000069f, -0.000007f }, { -0.000007f, 0.000045f } });
1110                final Ellipse e1_1227_2 = EllipseUtilities.ellipseFromCovariance(332.750000f,
1111                                191.180000f, secondMoments1_1227_2.inverse(), 1.0f);
1112                final Ellipse e2_1227_2 = EllipseUtilities.ellipseFromCovariance(334.020375f,
1113                                183.709935f, secondMoments2_1227_2.inverse(), 1.0f);
1114                doTest(secondMoments1_1227_2, secondMoments2_1227_2, e1_1227_2,
1115                                e2_1227_2, 0.048780f);
1116                final Matrix secondMoments1_56_3 = new Matrix(new double[][] {
1117                                { 0.002428f, 0.000424f }, { 0.000424f, 0.000583f } });
1118                final Matrix secondMoments2_56_3 = new Matrix(new double[][] {
1119                                { 0.001432f, 0.000331f }, { 0.000331f, 0.000360f } });
1120                final Ellipse e1_56_3 = EllipseUtilities.ellipseFromCovariance(435.600000f,
1121                                191.180000f, secondMoments1_56_3.inverse(), 1.0f);
1122                final Ellipse e2_56_3 = EllipseUtilities.ellipseFromCovariance(435.054090f,
1123                                192.225532f, secondMoments2_56_3.inverse(), 1.0f);
1124                doTest(secondMoments1_56_3, secondMoments2_56_3, e1_56_3, e2_56_3,
1125                                0.572848f);
1126                final Matrix secondMoments1_158_3 = new Matrix(new double[][] {
1127                                { 0.002428f, 0.000424f }, { 0.000424f, 0.000583f } });
1128                final Matrix secondMoments2_158_3 = new Matrix(new double[][] {
1129                                { 0.001311f, 0.000220f }, { 0.000220f, 0.000257f } });
1130                final Ellipse e1_158_3 = EllipseUtilities.ellipseFromCovariance(435.600000f,
1131                                191.180000f, secondMoments1_158_3.inverse(), 1.0f);
1132                final Ellipse e2_158_3 = EllipseUtilities.ellipseFromCovariance(435.869415f,
1133                                192.424474f, secondMoments2_158_3.inverse(), 1.0f);
1134                doTest(secondMoments1_158_3, secondMoments2_158_3, e1_158_3, e2_158_3,
1135                                0.483477f);
1136                final Matrix secondMoments1_428_4 = new Matrix(new double[][] {
1137                                { 0.001743f, -0.000279f }, { -0.000279f, 0.000753f } });
1138                final Matrix secondMoments2_428_4 = new Matrix(new double[][] {
1139                                { 0.000641f, -0.000135f }, { -0.000135f, 0.000210f } });
1140                final Ellipse e1_428_4 = EllipseUtilities.ellipseFromCovariance(492.470000f,
1141                                228.690000f, secondMoments1_428_4.inverse(), 1.0f);
1142                final Ellipse e2_428_4 = EllipseUtilities.ellipseFromCovariance(491.933851f,
1143                                234.396223f, secondMoments2_428_4.inverse(), 1.0f);
1144                doTest(secondMoments1_428_4, secondMoments2_428_4, e1_428_4, e2_428_4,
1145                                0.305591f);
1146                final Matrix secondMoments1_516_4 = new Matrix(new double[][] {
1147                                { 0.001743f, -0.000279f }, { -0.000279f, 0.000753f } });
1148                final Matrix secondMoments2_516_4 = new Matrix(new double[][] {
1149                                { 0.000892f, 0.000166f }, { 0.000166f, 0.000125f } });
1150                final Ellipse e1_516_4 = EllipseUtilities.ellipseFromCovariance(492.470000f,
1151                                228.690000f, secondMoments1_516_4.inverse(), 1.0f);
1152                final Ellipse e2_516_4 = EllipseUtilities.ellipseFromCovariance(492.855834f,
1153                                226.034456f, secondMoments2_516_4.inverse(), 1.0f);
1154                doTest(secondMoments1_516_4, secondMoments2_516_4, e1_516_4, e2_516_4,
1155                                0.259701f);
1156                final Matrix secondMoments1_627_4 = new Matrix(new double[][] {
1157                                { 0.001743f, -0.000279f }, { -0.000279f, 0.000753f } });
1158                final Matrix secondMoments2_627_4 = new Matrix(new double[][] {
1159                                { 0.000634f, 0.000133f }, { 0.000133f, 0.000112f } });
1160                final Ellipse e1_627_4 = EllipseUtilities.ellipseFromCovariance(492.470000f,
1161                                228.690000f, secondMoments1_627_4.inverse(), 1.0f);
1162                final Ellipse e2_627_4 = EllipseUtilities.ellipseFromCovariance(491.876614f,
1163                                226.470534f, secondMoments2_627_4.inverse(), 1.0f);
1164                doTest(secondMoments1_627_4, secondMoments2_627_4, e1_627_4, e2_627_4,
1165                                0.207720f);
1166                final Matrix secondMoments1_669_4 = new Matrix(new double[][] {
1167                                { 0.001743f, -0.000279f }, { -0.000279f, 0.000753f } });
1168                final Matrix secondMoments2_669_4 = new Matrix(new double[][] {
1169                                { 0.000456f, -0.000060f }, { -0.000060f, 0.000131f } });
1170                final Ellipse e1_669_4 = EllipseUtilities.ellipseFromCovariance(492.470000f,
1171                                228.690000f, secondMoments1_669_4.inverse(), 1.0f);
1172                final Ellipse e2_669_4 = EllipseUtilities.ellipseFromCovariance(491.162552f,
1173                                235.045782f, secondMoments2_669_4.inverse(), 1.0f);
1174                doTest(secondMoments1_669_4, secondMoments2_669_4, e1_669_4, e2_669_4,
1175                                0.213105f);
1176                final Matrix secondMoments1_1149_4 = new Matrix(new double[][] {
1177                                { 0.001743f, -0.000279f }, { -0.000279f, 0.000753f } });
1178                final Matrix secondMoments2_1149_4 = new Matrix(new double[][] {
1179                                { 0.000116f, -0.000035f }, { -0.000035f, 0.000059f } });
1180                final Ellipse e1_1149_4 = EllipseUtilities.ellipseFromCovariance(492.470000f,
1181                                228.690000f, secondMoments1_1149_4.inverse(), 1.0f);
1182                final Ellipse e2_1149_4 = EllipseUtilities.ellipseFromCovariance(491.609239f,
1183                                242.634937f, secondMoments2_1149_4.inverse(), 1.0f);
1184                doTest(secondMoments1_1149_4, secondMoments2_1149_4, e1_1149_4,
1185                                e2_1149_4, 0.067179f);
1186                final Matrix secondMoments1_365_5 = new Matrix(new double[][] {
1187                                { 0.000958f, -0.000971f }, { -0.000971f, 0.002273f } });
1188                final Matrix secondMoments2_365_5 = new Matrix(new double[][] {
1189                                { 0.000309f, -0.000272f }, { -0.000272f, 0.000808f } });
1190                final Ellipse e1_365_5 = EllipseUtilities.ellipseFromCovariance(337.590000f,
1191                                240.790000f, secondMoments1_365_5.inverse(), 1.0f);
1192                final Ellipse e2_365_5 = EllipseUtilities.ellipseFromCovariance(336.633738f,
1193                                239.693549f, secondMoments2_365_5.inverse(), 1.0f);
1194                doTest(secondMoments1_365_5, secondMoments2_365_5, e1_365_5, e2_365_5,
1195                                0.379938f);
1196                final Matrix secondMoments1_638_5 = new Matrix(new double[][] {
1197                                { 0.000958f, -0.000971f }, { -0.000971f, 0.002273f } });
1198                final Matrix secondMoments2_638_5 = new Matrix(new double[][] {
1199                                { 0.000217f, -0.000227f }, { -0.000227f, 0.000618f } });
1200                final Ellipse e1_638_5 = EllipseUtilities.ellipseFromCovariance(337.590000f,
1201                                240.790000f, secondMoments1_638_5.inverse(), 1.0f);
1202                final Ellipse e2_638_5 = EllipseUtilities.ellipseFromCovariance(328.577191f,
1203                                245.186420f, secondMoments2_638_5.inverse(), 1.0f);
1204                doTest(secondMoments1_638_5, secondMoments2_638_5, e1_638_5, e2_638_5,
1205                                0.259821f);
1206                final Matrix secondMoments1_838_5 = new Matrix(new double[][] {
1207                                { 0.000958f, -0.000971f }, { -0.000971f, 0.002273f } });
1208                final Matrix secondMoments2_838_5 = new Matrix(new double[][] {
1209                                { 0.000129f, 0.000101f }, { 0.000101f, 0.000360f } });
1210                final Ellipse e1_838_5 = EllipseUtilities.ellipseFromCovariance(337.590000f,
1211                                240.790000f, secondMoments1_838_5.inverse(), 1.0f);
1212                final Ellipse e2_838_5 = EllipseUtilities.ellipseFromCovariance(326.461413f,
1213                                235.046223f, secondMoments2_838_5.inverse(), 1.0f);
1214                doTest(secondMoments1_838_5, secondMoments2_838_5, e1_838_5, e2_838_5,
1215                                0.171267f);
1216                final Matrix secondMoments1_996_5 = new Matrix(new double[][] {
1217                                { 0.000958f, -0.000971f }, { -0.000971f, 0.002273f } });
1218                final Matrix secondMoments2_996_5 = new Matrix(new double[][] {
1219                                { 0.000094f, 0.000074f }, { 0.000074f, 0.000242f } });
1220                final Ellipse e1_996_5 = EllipseUtilities.ellipseFromCovariance(337.590000f,
1221                                240.790000f, secondMoments1_996_5.inverse(), 1.0f);
1222                final Ellipse e2_996_5 = EllipseUtilities.ellipseFromCovariance(328.356298f,
1223                                234.286336f, secondMoments2_996_5.inverse(), 1.0f);
1224                doTest(secondMoments1_996_5, secondMoments2_996_5, e1_996_5, e2_996_5,
1225                                0.118915f);
1226                final Matrix secondMoments1_1060_5 = new Matrix(new double[][] {
1227                                { 0.000958f, -0.000971f }, { -0.000971f, 0.002273f } });
1228                final Matrix secondMoments2_1060_5 = new Matrix(new double[][] {
1229                                { 0.000105f, -0.000008f }, { -0.000008f, 0.000113f } });
1230                final Ellipse e1_1060_5 = EllipseUtilities.ellipseFromCovariance(337.590000f,
1231                                240.790000f, secondMoments1_1060_5.inverse(), 1.0f);
1232                final Ellipse e2_1060_5 = EllipseUtilities.ellipseFromCovariance(349.731703f,
1233                                234.442286f, secondMoments2_1060_5.inverse(), 1.0f);
1234                doTest(secondMoments1_1060_5, secondMoments2_1060_5, e1_1060_5,
1235                                e2_1060_5, 0.095904f);
1236                final Matrix secondMoments1_668_6 = new Matrix(new double[][] {
1237                                { 0.001354f, 0.000523f }, { 0.000523f, 0.001113f } });
1238                final Matrix secondMoments2_668_6 = new Matrix(new double[][] {
1239                                { 0.000387f, -0.000085f }, { -0.000085f, 0.000169f } });
1240                final Ellipse e1_668_6 = EllipseUtilities.ellipseFromCovariance(574.750000f,
1241                                249.260000f, secondMoments1_668_6.inverse(), 1.0f);
1242                final Ellipse e2_668_6 = EllipseUtilities.ellipseFromCovariance(565.259118f,
1243                                250.988953f, secondMoments2_668_6.inverse(), 1.0f);
1244                doTest(secondMoments1_668_6, secondMoments2_668_6, e1_668_6, e2_668_6,
1245                                0.218441f);
1246                final Matrix secondMoments1_777_6 = new Matrix(new double[][] {
1247                                { 0.001354f, 0.000523f }, { 0.000523f, 0.001113f } });
1248                final Matrix secondMoments2_777_6 = new Matrix(new double[][] {
1249                                { 0.000283f, -0.000032f }, { -0.000032f, 0.000145f } });
1250                final Ellipse e1_777_6 = EllipseUtilities.ellipseFromCovariance(574.750000f,
1251                                249.260000f, secondMoments1_777_6.inverse(), 1.0f);
1252                final Ellipse e2_777_6 = EllipseUtilities.ellipseFromCovariance(567.000420f,
1253                                251.169427f, secondMoments2_777_6.inverse(), 1.0f);
1254                doTest(secondMoments1_777_6, secondMoments2_777_6, e1_777_6, e2_777_6,
1255                                0.180799f);
1256                final Matrix secondMoments1_874_6 = new Matrix(new double[][] {
1257                                { 0.001354f, 0.000523f }, { 0.000523f, 0.001113f } });
1258                final Matrix secondMoments2_874_6 = new Matrix(new double[][] {
1259                                { 0.000309f, -0.000063f }, { -0.000063f, 0.000097f } });
1260                final Ellipse e1_874_6 = EllipseUtilities.ellipseFromCovariance(574.750000f,
1261                                249.260000f, secondMoments1_874_6.inverse(), 1.0f);
1262                final Ellipse e2_874_6 = EllipseUtilities.ellipseFromCovariance(566.196720f,
1263                                250.693547f, secondMoments2_874_6.inverse(), 1.0f);
1264                doTest(secondMoments1_874_6, secondMoments2_874_6, e1_874_6, e2_874_6,
1265                                0.146600f);
1266                final Matrix secondMoments1_947_6 = new Matrix(new double[][] {
1267                                { 0.001354f, 0.000523f }, { 0.000523f, 0.001113f } });
1268                final Matrix secondMoments2_947_6 = new Matrix(new double[][] {
1269                                { 0.000261f, -0.000054f }, { -0.000054f, 0.000075f } });
1270                final Ellipse e1_947_6 = EllipseUtilities.ellipseFromCovariance(574.750000f,
1271                                249.260000f, secondMoments1_947_6.inverse(), 1.0f);
1272                final Ellipse e2_947_6 = EllipseUtilities.ellipseFromCovariance(567.439385f,
1273                                247.649178f, secondMoments2_947_6.inverse(), 1.0f);
1274                doTest(secondMoments1_947_6, secondMoments2_947_6, e1_947_6, e2_947_6,
1275                                0.117028f);
1276                final Matrix secondMoments1_1311_6 = new Matrix(new double[][] {
1277                                { 0.001354f, 0.000523f }, { 0.000523f, 0.001113f } });
1278                final Matrix secondMoments2_1311_6 = new Matrix(new double[][] {
1279                                { 0.000058f, -0.000009f }, { -0.000009f, 0.000016f } });
1280                final Ellipse e1_1311_6 = EllipseUtilities.ellipseFromCovariance(574.750000f,
1281                                249.260000f, secondMoments1_1311_6.inverse(), 1.0f);
1282                final Ellipse e2_1311_6 = EllipseUtilities.ellipseFromCovariance(566.572361f,
1283                                256.816211f, secondMoments2_1311_6.inverse(), 1.0f);
1284                doTest(secondMoments1_1311_6, secondMoments2_1311_6, e1_1311_6,
1285                                e2_1311_6, 0.025298f);
1286                final Matrix secondMoments1_1315_6 = new Matrix(new double[][] {
1287                                { 0.001354f, 0.000523f }, { 0.000523f, 0.001113f } });
1288                final Matrix secondMoments2_1315_6 = new Matrix(new double[][] {
1289                                { 0.000047f, -0.000008f }, { -0.000008f, 0.000018f } });
1290                final Ellipse e1_1315_6 = EllipseUtilities.ellipseFromCovariance(574.750000f,
1291                                249.260000f, secondMoments1_1315_6.inverse(), 1.0f);
1292                final Ellipse e2_1315_6 = EllipseUtilities.ellipseFromCovariance(562.537774f,
1293                                255.107101f, secondMoments2_1315_6.inverse(), 1.0f);
1294                doTest(secondMoments1_1315_6, secondMoments2_1315_6, e1_1315_6,
1295                                e2_1315_6, 0.024782f);
1296                final Matrix secondMoments1_164_7 = new Matrix(new double[][] {
1297                                { 0.000573f, 0.000492f }, { 0.000492f, 0.002577f } });
1298                final Matrix secondMoments2_164_7 = new Matrix(new double[][] {
1299                                { 0.000386f, 0.000474f }, { 0.000474f, 0.001509f } });
1300                final Ellipse e1_164_7 = EllipseUtilities.ellipseFromCovariance(383.570000f,
1301                                254.100000f, secondMoments1_164_7.inverse(), 1.0f);
1302                final Ellipse e2_164_7 = EllipseUtilities.ellipseFromCovariance(384.642802f,
1303                                253.183299f, secondMoments2_164_7.inverse(), 1.0f);
1304                doTest(secondMoments1_164_7, secondMoments2_164_7, e1_164_7, e2_164_7,
1305                                0.539050f);
1306                final Matrix secondMoments1_9_8 = new Matrix(new double[][] {
1307                                { 0.001197f, 0.000842f }, { 0.000842f, 0.001625f } });
1308                final Matrix secondMoments2_9_8 = new Matrix(new double[][] {
1309                                { 0.001259f, 0.001575f }, { 0.001575f, 0.002509f } });
1310                final Ellipse e1_9_8 = EllipseUtilities.ellipseFromCovariance(400.510000f,
1311                                263.780000f, secondMoments1_9_8.inverse(), 1.0f);
1312                final Ellipse e2_9_8 = EllipseUtilities.ellipseFromCovariance(408.481337f,
1313                                259.534703f, secondMoments2_9_8.inverse(), 1.0f);
1314                doTest(secondMoments1_9_8, secondMoments2_9_8, e1_9_8, e2_9_8,
1315                                0.580043f);
1316                final Matrix secondMoments1_63_8 = new Matrix(new double[][] {
1317                                { 0.001197f, 0.000842f }, { 0.000842f, 0.001625f } });
1318                final Matrix secondMoments2_63_8 = new Matrix(new double[][] {
1319                                { 0.000968f, 0.001248f }, { 0.001248f, 0.002056f } });
1320                final Ellipse e1_63_8 = EllipseUtilities.ellipseFromCovariance(400.510000f,
1321                                263.780000f, secondMoments1_63_8.inverse(), 1.0f);
1322                final Ellipse e2_63_8 = EllipseUtilities.ellipseFromCovariance(408.233989f,
1323                                260.161238f, secondMoments2_63_8.inverse(), 1.0f);
1324                doTest(secondMoments1_63_8, secondMoments2_63_8, e1_63_8, e2_63_8,
1325                                0.536834f);
1326                final Matrix secondMoments1_65_8 = new Matrix(new double[][] {
1327                                { 0.001197f, 0.000842f }, { 0.000842f, 0.001625f } });
1328                final Matrix secondMoments2_65_8 = new Matrix(new double[][] {
1329                                { 0.000771f, 0.000945f }, { 0.000945f, 0.001809f } });
1330                final Ellipse e1_65_8 = EllipseUtilities.ellipseFromCovariance(400.510000f,
1331                                263.780000f, secondMoments1_65_8.inverse(), 1.0f);
1332                final Ellipse e2_65_8 = EllipseUtilities.ellipseFromCovariance(411.983753f,
1333                                264.164628f, secondMoments2_65_8.inverse(), 1.0f);
1334                doTest(secondMoments1_65_8, secondMoments2_65_8, e1_65_8, e2_65_8,
1335                                0.511713f);
1336                final Matrix secondMoments1_1365_9 = new Matrix(new double[][] {
1337                                { 0.001053f, 0.000882f }, { 0.000882f, 0.001912f } });
1338                final Matrix secondMoments2_1365_9 = new Matrix(new double[][] {
1339                                { 0.000013f, -0.000006f }, { -0.000006f, 0.000026f } });
1340                final Ellipse e1_1365_9 = EllipseUtilities.ellipseFromCovariance(393.250000f,
1341                                266.200000f, secondMoments1_1365_9.inverse(), 1.0f);
1342                final Ellipse e2_1365_9 = EllipseUtilities.ellipseFromCovariance(383.425219f,
1343                                274.208974f, secondMoments2_1365_9.inverse(), 1.0f);
1344                doTest(secondMoments1_1365_9, secondMoments2_1365_9, e1_1365_9,
1345                                e2_1365_9, 0.016473f);
1346                final Matrix secondMoments1_1388_9 = new Matrix(new double[][] {
1347                                { 0.001053f, 0.000882f }, { 0.000882f, 0.001912f } });
1348                final Matrix secondMoments2_1388_9 = new Matrix(new double[][] {
1349                                { 0.000011f, -0.000013f }, { -0.000013f, 0.000029f } });
1350                final Ellipse e1_1388_9 = EllipseUtilities.ellipseFromCovariance(393.250000f,
1351                                266.200000f, secondMoments1_1388_9.inverse(), 1.0f);
1352                final Ellipse e2_1388_9 = EllipseUtilities.ellipseFromCovariance(380.052283f,
1353                                270.743548f, secondMoments2_1388_9.inverse(), 1.0f);
1354                doTest(secondMoments1_1388_9, secondMoments2_1388_9, e1_1388_9,
1355                                e2_1388_9, 0.011116f);
1356                final Matrix secondMoments1_9_10 = new Matrix(new double[][] {
1357                                { 0.001525f, 0.001640f }, { 0.001640f, 0.002574f } });
1358                final Matrix secondMoments2_9_10 = new Matrix(new double[][] {
1359                                { 0.001211f, 0.001514f }, { 0.001514f, 0.002412f } });
1360                final Ellipse e1_9_10 = EllipseUtilities.ellipseFromCovariance(407.770000f,
1361                                266.200000f, secondMoments1_9_10.inverse(), 1.0f);
1362                final Ellipse e2_9_10 = EllipseUtilities.ellipseFromCovariance(408.481337f,
1363                                259.534703f, secondMoments2_9_10.inverse(), 1.0f);
1364                doTest(secondMoments1_9_10, secondMoments2_9_10, e1_9_10, e2_9_10,
1365                                0.577320f);
1366                final Matrix secondMoments1_63_10 = new Matrix(new double[][] {
1367                                { 0.001525f, 0.001640f }, { 0.001640f, 0.002574f } });
1368                final Matrix secondMoments2_63_10 = new Matrix(new double[][] {
1369                                { 0.000930f, 0.001200f }, { 0.001200f, 0.001976f } });
1370                final Ellipse e1_63_10 = EllipseUtilities.ellipseFromCovariance(407.770000f,
1371                                266.200000f, secondMoments1_63_10.inverse(), 1.0f);
1372                final Ellipse e2_63_10 = EllipseUtilities.ellipseFromCovariance(408.233989f,
1373                                260.161238f, secondMoments2_63_10.inverse(), 1.0f);
1374                doTest(secondMoments1_63_10, secondMoments2_63_10, e1_63_10, e2_63_10,
1375                                0.524812f);
1376                final Matrix secondMoments1_65_10 = new Matrix(new double[][] {
1377                                { 0.001525f, 0.001640f }, { 0.001640f, 0.002574f } });
1378                final Matrix secondMoments2_65_10 = new Matrix(new double[][] {
1379                                { 0.000741f, 0.000908f }, { 0.000908f, 0.001739f } });
1380                final Ellipse e1_65_10 = EllipseUtilities.ellipseFromCovariance(407.770000f,
1381                                266.200000f, secondMoments1_65_10.inverse(), 1.0f);
1382                final Ellipse e2_65_10 = EllipseUtilities.ellipseFromCovariance(411.983753f,
1383                                264.164628f, secondMoments2_65_10.inverse(), 1.0f);
1384                doTest(secondMoments1_65_10, secondMoments2_65_10, e1_65_10, e2_65_10,
1385                                0.615385f);
1386                final Matrix secondMoments1_563_11 = new Matrix(new double[][] {
1387                                { 0.001142f, 0.000197f }, { 0.000197f, 0.001115f } });
1388                final Matrix secondMoments2_563_11 = new Matrix(new double[][] {
1389                                { 0.000367f, 0.000160f }, { 0.000160f, 0.000364f } });
1390                final Ellipse e1_563_11 = EllipseUtilities.ellipseFromCovariance(451.330000f,
1391                                267.410000f, secondMoments1_563_11.inverse(), 1.0f);
1392                final Ellipse e2_563_11 = EllipseUtilities.ellipseFromCovariance(442.275933f,
1393                                258.456881f, secondMoments2_563_11.inverse(), 1.0f);
1394                doTest(secondMoments1_563_11, secondMoments2_563_11, e1_563_11,
1395                                e2_563_11, 0.292264f);
1396                final Matrix secondMoments1_637_11 = new Matrix(new double[][] {
1397                                { 0.001142f, 0.000197f }, { 0.000197f, 0.001115f } });
1398                final Matrix secondMoments2_637_11 = new Matrix(new double[][] {
1399                                { 0.000270f, 0.000128f }, { 0.000128f, 0.000327f } });
1400                final Ellipse e1_637_11 = EllipseUtilities.ellipseFromCovariance(451.330000f,
1401                                267.410000f, secondMoments1_637_11.inverse(), 1.0f);
1402                final Ellipse e2_637_11 = EllipseUtilities.ellipseFromCovariance(438.144245f,
1403                                264.255157f, secondMoments2_637_11.inverse(), 1.0f);
1404                doTest(secondMoments1_637_11, secondMoments2_637_11, e1_637_11,
1405                                e2_637_11, 0.241868f);
1406                final Matrix secondMoments1_739_11 = new Matrix(new double[][] {
1407                                { 0.001142f, 0.000197f }, { 0.000197f, 0.001115f } });
1408                final Matrix secondMoments2_739_11 = new Matrix(new double[][] {
1409                                { 0.000242f, 0.000099f }, { 0.000099f, 0.000220f } });
1410                final Ellipse e1_739_11 = EllipseUtilities.ellipseFromCovariance(451.330000f,
1411                                267.410000f, secondMoments1_739_11.inverse(), 1.0f);
1412                final Ellipse e2_739_11 = EllipseUtilities.ellipseFromCovariance(443.506090f,
1413                                258.974375f, secondMoments2_739_11.inverse(), 1.0f);
1414                doTest(secondMoments1_739_11, secondMoments2_739_11, e1_739_11,
1415                                e2_739_11, 0.187706f);
1416                final Matrix secondMoments1_782_11 = new Matrix(new double[][] {
1417                                { 0.001142f, 0.000197f }, { 0.000197f, 0.001115f } });
1418                final Matrix secondMoments2_782_11 = new Matrix(new double[][] {
1419                                { 0.000258f, 0.000104f }, { 0.000104f, 0.000229f } });
1420                final Ellipse e1_782_11 = EllipseUtilities.ellipseFromCovariance(451.330000f,
1421                                267.410000f, secondMoments1_782_11.inverse(), 1.0f);
1422                final Ellipse e2_782_11 = EllipseUtilities.ellipseFromCovariance(442.606689f,
1423                                260.868482f, secondMoments2_782_11.inverse(), 1.0f);
1424                doTest(secondMoments1_782_11, secondMoments2_782_11, e1_782_11,
1425                                e2_782_11, 0.198262f);
1426                final Matrix secondMoments1_9_12 = new Matrix(new double[][] {
1427                                { 0.001146f, 0.000803f }, { 0.000803f, 0.001640f } });
1428                final Matrix secondMoments2_9_12 = new Matrix(new double[][] {
1429                                { 0.001229f, 0.001538f }, { 0.001538f, 0.002449f } });
1430                final Ellipse e1_9_12 = EllipseUtilities.ellipseFromCovariance(400.510000f,
1431                                268.620000f, secondMoments1_9_12.inverse(), 1.0f);
1432                final Ellipse e2_9_12 = EllipseUtilities.ellipseFromCovariance(408.481337f,
1433                                259.534703f, secondMoments2_9_12.inverse(), 1.0f);
1434                doTest(secondMoments1_9_12, secondMoments2_9_12, e1_9_12, e2_9_12,
1435                                0.550890f);
1436                final Matrix secondMoments1_63_12 = new Matrix(new double[][] {
1437                                { 0.001146f, 0.000803f }, { 0.000803f, 0.001640f } });
1438                final Matrix secondMoments2_63_12 = new Matrix(new double[][] {
1439                                { 0.000945f, 0.001218f }, { 0.001218f, 0.002007f } });
1440                final Ellipse e1_63_12 = EllipseUtilities.ellipseFromCovariance(400.510000f,
1441                                268.620000f, secondMoments1_63_12.inverse(), 1.0f);
1442                final Ellipse e2_63_12 = EllipseUtilities.ellipseFromCovariance(408.233989f,
1443                                260.161238f, secondMoments2_63_12.inverse(), 1.0f);
1444                doTest(secondMoments1_63_12, secondMoments2_63_12, e1_63_12, e2_63_12,
1445                                0.504769f);
1446                final Matrix secondMoments1_65_12 = new Matrix(new double[][] {
1447                                { 0.001146f, 0.000803f }, { 0.000803f, 0.001640f } });
1448                final Matrix secondMoments2_65_12 = new Matrix(new double[][] {
1449                                { 0.000752f, 0.000922f }, { 0.000922f, 0.001766f } });
1450                final Ellipse e1_65_12 = EllipseUtilities.ellipseFromCovariance(400.510000f,
1451                                268.620000f, secondMoments1_65_12.inverse(), 1.0f);
1452                final Ellipse e2_65_12 = EllipseUtilities.ellipseFromCovariance(411.983753f,
1453                                264.164628f, secondMoments2_65_12.inverse(), 1.0f);
1454                doTest(secondMoments1_65_12, secondMoments2_65_12, e1_65_12, e2_65_12,
1455                                0.585214f);
1456                final Matrix secondMoments1_15_13 = new Matrix(new double[][] {
1457                                { 0.000660f, 0.000147f }, { 0.000147f, 0.001903f } });
1458                final Matrix secondMoments2_15_13 = new Matrix(new double[][] {
1459                                { 0.000512f, 0.000099f }, { 0.000099f, 0.001657f } });
1460                final Ellipse e1_15_13 = EllipseUtilities.ellipseFromCovariance(95.590000f,
1461                                274.670000f, secondMoments1_15_13.inverse(), 1.0f);
1462                final Ellipse e2_15_13 = EllipseUtilities.ellipseFromCovariance(96.256202f,
1463                                271.637173f, secondMoments2_15_13.inverse(), 1.0f);
1464                doTest(secondMoments1_15_13, secondMoments2_15_13, e1_15_13, e2_15_13,
1465                                0.793562f);
1466                final Matrix secondMoments1_81_13 = new Matrix(new double[][] {
1467                                { 0.000660f, 0.000147f }, { 0.000147f, 0.001903f } });
1468                final Matrix secondMoments2_81_13 = new Matrix(new double[][] {
1469                                { 0.000537f, 0.000107f }, { 0.000107f, 0.001190f } });
1470                final Ellipse e1_81_13 = EllipseUtilities.ellipseFromCovariance(95.590000f,
1471                                274.670000f, secondMoments1_81_13.inverse(), 1.0f);
1472                final Ellipse e2_81_13 = EllipseUtilities.ellipseFromCovariance(95.777830f,
1473                                271.375829f, secondMoments2_81_13.inverse(), 1.0f);
1474                doTest(secondMoments1_81_13, secondMoments2_81_13, e1_81_13, e2_81_13,
1475                                0.713031f);
1476                final Matrix secondMoments1_176_13 = new Matrix(new double[][] {
1477                                { 0.000660f, 0.000147f }, { 0.000147f, 0.001903f } });
1478                final Matrix secondMoments2_176_13 = new Matrix(new double[][] {
1479                                { 0.000372f, 0.000085f }, { 0.000085f, 0.001114f } });
1480                final Ellipse e1_176_13 = EllipseUtilities.ellipseFromCovariance(95.590000f,
1481                                274.670000f, secondMoments1_176_13.inverse(), 1.0f);
1482                final Ellipse e2_176_13 = EllipseUtilities.ellipseFromCovariance(96.782894f,
1483                                272.080449f, secondMoments2_176_13.inverse(), 1.0f);
1484                doTest(secondMoments1_176_13, secondMoments2_176_13, e1_176_13,
1485                                e2_176_13, 0.572466f);
1486                final Matrix secondMoments1_502_13 = new Matrix(new double[][] {
1487                                { 0.000660f, 0.000147f }, { 0.000147f, 0.001903f } });
1488                final Matrix secondMoments2_502_13 = new Matrix(new double[][] {
1489                                { 0.000576f, -0.000056f }, { -0.000056f, 0.000220f } });
1490                final Ellipse e1_502_13 = EllipseUtilities.ellipseFromCovariance(95.590000f,
1491                                274.670000f, secondMoments1_502_13.inverse(), 1.0f);
1492                final Ellipse e2_502_13 = EllipseUtilities.ellipseFromCovariance(91.532437f,
1493                                286.344582f, secondMoments2_502_13.inverse(), 1.0f);
1494                doTest(secondMoments1_502_13, secondMoments2_502_13, e1_502_13,
1495                                e2_502_13, 0.307848f);
1496                final Matrix secondMoments1_583_13 = new Matrix(new double[][] {
1497                                { 0.000660f, 0.000147f }, { 0.000147f, 0.001903f } });
1498                final Matrix secondMoments2_583_13 = new Matrix(new double[][] {
1499                                { 0.000097f, -0.000031f }, { -0.000031f, 0.001458f } });
1500                final Ellipse e1_583_13 = EllipseUtilities.ellipseFromCovariance(95.590000f,
1501                                274.670000f, secondMoments1_583_13.inverse(), 1.0f);
1502                final Ellipse e2_583_13 = EllipseUtilities.ellipseFromCovariance(94.860438f,
1503                                282.858744f, secondMoments2_583_13.inverse(), 1.0f);
1504                doTest(secondMoments1_583_13, secondMoments2_583_13, e1_583_13,
1505                                e2_583_13, 0.304291f);
1506                final Matrix secondMoments1_640_13 = new Matrix(new double[][] {
1507                                { 0.000660f, 0.000147f }, { 0.000147f, 0.001903f } });
1508                final Matrix secondMoments2_640_13 = new Matrix(new double[][] {
1509                                { 0.000138f, -0.000002f }, { -0.000002f, 0.000620f } });
1510                final Ellipse e1_640_13 = EllipseUtilities.ellipseFromCovariance(95.590000f,
1511                                274.670000f, secondMoments1_640_13.inverse(), 1.0f);
1512                final Ellipse e2_640_13 = EllipseUtilities.ellipseFromCovariance(95.102784f,
1513                                281.836333f, secondMoments2_640_13.inverse(), 1.0f);
1514                doTest(secondMoments1_640_13, secondMoments2_640_13, e1_640_13,
1515                                e2_640_13, 0.263184f);
1516                final Matrix secondMoments1_846_13 = new Matrix(new double[][] {
1517                                { 0.000660f, 0.000147f }, { 0.000147f, 0.001903f } });
1518                final Matrix secondMoments2_846_13 = new Matrix(new double[][] {
1519                                { 0.000100f, -0.000003f }, { -0.000003f, 0.000445f } });
1520                final Ellipse e1_846_13 = EllipseUtilities.ellipseFromCovariance(95.590000f,
1521                                274.670000f, secondMoments1_846_13.inverse(), 1.0f);
1522                final Ellipse e2_846_13 = EllipseUtilities.ellipseFromCovariance(92.764510f,
1523                                288.550082f, secondMoments2_846_13.inverse(), 1.0f);
1524                doTest(secondMoments1_846_13, secondMoments2_846_13, e1_846_13,
1525                                e2_846_13, 0.189570f);
1526                final Matrix secondMoments1_883_13 = new Matrix(new double[][] {
1527                                { 0.000660f, 0.000147f }, { 0.000147f, 0.001903f } });
1528                final Matrix secondMoments2_883_13 = new Matrix(new double[][] {
1529                                { 0.000602f, -0.000000f }, { -0.000000f, 0.000063f } });
1530                final Ellipse e1_883_13 = EllipseUtilities.ellipseFromCovariance(95.590000f,
1531                                274.670000f, secondMoments1_883_13.inverse(), 1.0f);
1532                final Ellipse e2_883_13 = EllipseUtilities.ellipseFromCovariance(93.459892f,
1533                                267.111785f, secondMoments2_883_13.inverse(), 1.0f);
1534                doTest(secondMoments1_883_13, secondMoments2_883_13, e1_883_13,
1535                                e2_883_13, 0.176420f);
1536                final Matrix secondMoments1_1312_13 = new Matrix(new double[][] {
1537                                { 0.000660f, 0.000147f }, { 0.000147f, 0.001903f } });
1538                final Matrix secondMoments2_1312_13 = new Matrix(new double[][] {
1539                                { 0.000066f, -0.000000f }, { -0.000000f, 0.000021f } });
1540                final Ellipse e1_1312_13 = EllipseUtilities.ellipseFromCovariance(95.590000f,
1541                                274.670000f, secondMoments1_1312_13.inverse(), 1.0f);
1542                final Ellipse e2_1312_13 = EllipseUtilities.ellipseFromCovariance(97.906473f,
1543                                268.440672f, secondMoments2_1312_13.inverse(), 1.0f);
1544                doTest(secondMoments1_1312_13, secondMoments2_1312_13, e1_1312_13,
1545                                e2_1312_13, 0.033122f);
1546                final Matrix secondMoments1_7_14 = new Matrix(new double[][] {
1547                                { 0.000629f, 0.000651f }, { 0.000651f, 0.002635f } });
1548                final Matrix secondMoments2_7_14 = new Matrix(new double[][] {
1549                                { 0.000333f, 0.000425f }, { 0.000425f, 0.001766f } });
1550                final Ellipse e1_7_14 = EllipseUtilities.ellipseFromCovariance(735.680000f,
1551                                289.190000f, secondMoments1_7_14.inverse(), 1.0f);
1552                final Ellipse e2_7_14 = EllipseUtilities.ellipseFromCovariance(735.215675f,
1553                                289.470365f, secondMoments2_7_14.inverse(), 1.0f);
1554                doTest(secondMoments1_7_14, secondMoments2_7_14, e1_7_14, e2_7_14,
1555                                0.574898f);
1556                final Matrix secondMoments1_160_14 = new Matrix(new double[][] {
1557                                { 0.000629f, 0.000651f }, { 0.000651f, 0.002635f } });
1558                final Matrix secondMoments2_160_14 = new Matrix(new double[][] {
1559                                { 0.000240f, 0.000357f }, { 0.000357f, 0.001342f } });
1560                final Ellipse e1_160_14 = EllipseUtilities.ellipseFromCovariance(735.680000f,
1561                                289.190000f, secondMoments1_160_14.inverse(), 1.0f);
1562                final Ellipse e2_160_14 = EllipseUtilities.ellipseFromCovariance(737.219458f,
1563                                288.986366f, secondMoments2_160_14.inverse(), 1.0f);
1564                doTest(secondMoments1_160_14, secondMoments2_160_14, e1_160_14,
1565                                e2_160_14, 0.398695f);
1566                final Matrix secondMoments1_554_14 = new Matrix(new double[][] {
1567                                { 0.000629f, 0.000651f }, { 0.000651f, 0.002635f } });
1568                final Matrix secondMoments2_554_14 = new Matrix(new double[][] {
1569                                { 0.000145f, 0.000172f }, { 0.000172f, 0.000649f } });
1570                final Ellipse e1_554_14 = EllipseUtilities.ellipseFromCovariance(735.680000f,
1571                                289.190000f, secondMoments1_554_14.inverse(), 1.0f);
1572                final Ellipse e2_554_14 = EllipseUtilities.ellipseFromCovariance(737.726233f,
1573                                289.165221f, secondMoments2_554_14.inverse(), 1.0f);
1574                doTest(secondMoments1_554_14, secondMoments2_554_14, e1_554_14,
1575                                e2_554_14, 0.228170f);
1576                final Matrix secondMoments1_776_14 = new Matrix(new double[][] {
1577                                { 0.000629f, 0.000651f }, { 0.000651f, 0.002635f } });
1578                final Matrix secondMoments2_776_14 = new Matrix(new double[][] {
1579                                { 0.000121f, 0.000071f }, { 0.000071f, 0.000273f } });
1580                final Ellipse e1_776_14 = EllipseUtilities.ellipseFromCovariance(735.680000f,
1581                                289.190000f, secondMoments1_776_14.inverse(), 1.0f);
1582                final Ellipse e2_776_14 = EllipseUtilities.ellipseFromCovariance(737.146318f,
1583                                287.771841f, secondMoments2_776_14.inverse(), 1.0f);
1584                doTest(secondMoments1_776_14, secondMoments2_776_14, e1_776_14,
1585                                e2_776_14, 0.150452f);
1586                final Matrix secondMoments1_68_15 = new Matrix(new double[][] {
1587                                { 0.000621f, 0.000238f }, { 0.000238f, 0.002079f } });
1588                final Matrix secondMoments2_68_15 = new Matrix(new double[][] {
1589                                { 0.000271f, 0.000265f }, { 0.000265f, 0.001672f } });
1590                final Ellipse e1_68_15 = EllipseUtilities.ellipseFromCovariance(486.420000f,
1591                                306.130000f, secondMoments1_68_15.inverse(), 1.0f);
1592                final Ellipse e2_68_15 = EllipseUtilities.ellipseFromCovariance(485.435623f,
1593                                306.183645f, secondMoments2_68_15.inverse(), 1.0f);
1594                doTest(secondMoments1_68_15, secondMoments2_68_15, e1_68_15, e2_68_15,
1595                                0.555658f);
1596                final Matrix secondMoments1_167_15 = new Matrix(new double[][] {
1597                                { 0.000621f, 0.000238f }, { 0.000238f, 0.002079f } });
1598                final Matrix secondMoments2_167_15 = new Matrix(new double[][] {
1599                                { 0.000224f, 0.000211f }, { 0.000211f, 0.001501f } });
1600                final Ellipse e1_167_15 = EllipseUtilities.ellipseFromCovariance(486.420000f,
1601                                306.130000f, secondMoments1_167_15.inverse(), 1.0f);
1602                final Ellipse e2_167_15 = EllipseUtilities.ellipseFromCovariance(484.110847f,
1603                                305.836654f, secondMoments2_167_15.inverse(), 1.0f);
1604                doTest(secondMoments1_167_15, secondMoments2_167_15, e1_167_15,
1605                                e2_167_15, 0.486276f);
1606                final Matrix secondMoments1_281_15 = new Matrix(new double[][] {
1607                                { 0.000621f, 0.000238f }, { 0.000238f, 0.002079f } });
1608                final Matrix secondMoments2_281_15 = new Matrix(new double[][] {
1609                                { 0.000176f, 0.000168f }, { 0.000168f, 0.001212f } });
1610                final Ellipse e1_281_15 = EllipseUtilities.ellipseFromCovariance(486.420000f,
1611                                306.130000f, secondMoments1_281_15.inverse(), 1.0f);
1612                final Ellipse e2_281_15 = EllipseUtilities.ellipseFromCovariance(485.021331f,
1613                                306.075132f, secondMoments2_281_15.inverse(), 1.0f);
1614                doTest(secondMoments1_281_15, secondMoments2_281_15, e1_281_15,
1615                                e2_281_15, 0.387940f);
1616                final Matrix secondMoments1_284_15 = new Matrix(new double[][] {
1617                                { 0.000621f, 0.000238f }, { 0.000238f, 0.002079f } });
1618                final Matrix secondMoments2_284_15 = new Matrix(new double[][] {
1619                                { 0.000414f, -0.000290f }, { -0.000290f, 0.000689f } });
1620                final Ellipse e1_284_15 = EllipseUtilities.ellipseFromCovariance(486.420000f,
1621                                306.130000f, secondMoments1_284_15.inverse(), 1.0f);
1622                final Ellipse e2_284_15 = EllipseUtilities.ellipseFromCovariance(490.325903f,
1623                                314.914392f, secondMoments2_284_15.inverse(), 1.0f);
1624                doTest(secondMoments1_284_15, secondMoments2_284_15, e1_284_15,
1625                                e2_284_15, 0.391179f);
1626                final Matrix secondMoments1_437_15 = new Matrix(new double[][] {
1627                                { 0.000621f, 0.000238f }, { 0.000238f, 0.002079f } });
1628                final Matrix secondMoments2_437_15 = new Matrix(new double[][] {
1629                                { 0.000150f, 0.000150f }, { 0.000150f, 0.001084f } });
1630                final Ellipse e1_437_15 = EllipseUtilities.ellipseFromCovariance(486.420000f,
1631                                306.130000f, secondMoments1_437_15.inverse(), 1.0f);
1632                final Ellipse e2_437_15 = EllipseUtilities.ellipseFromCovariance(482.683481f,
1633                                305.834707f, secondMoments2_437_15.inverse(), 1.0f);
1634                doTest(secondMoments1_437_15, secondMoments2_437_15, e1_437_15,
1635                                e2_437_15, 0.337182f);
1636                final Matrix secondMoments1_570_15 = new Matrix(new double[][] {
1637                                { 0.000621f, 0.000238f }, { 0.000238f, 0.002079f } });
1638                final Matrix secondMoments2_570_15 = new Matrix(new double[][] {
1639                                { 0.000159f, 0.000021f }, { 0.000021f, 0.000537f } });
1640                final Ellipse e1_570_15 = EllipseUtilities.ellipseFromCovariance(486.420000f,
1641                                306.130000f, secondMoments1_570_15.inverse(), 1.0f);
1642                final Ellipse e2_570_15 = EllipseUtilities.ellipseFromCovariance(482.175137f,
1643                                304.678265f, secondMoments2_570_15.inverse(), 1.0f);
1644                doTest(secondMoments1_570_15, secondMoments2_570_15, e1_570_15,
1645                                e2_570_15, 0.262092f);
1646                final Matrix secondMoments1_10_16 = new Matrix(new double[][] {
1647                                { 0.001599f, 0.000493f }, { 0.000493f, 0.000924f } });
1648                final Matrix secondMoments2_10_16 = new Matrix(new double[][] {
1649                                { 0.000633f, 0.000295f }, { 0.000295f, 0.000950f } });
1650                final Ellipse e1_10_16 = EllipseUtilities.ellipseFromCovariance(464.640000f,
1651                                315.810000f, secondMoments1_10_16.inverse(), 1.0f);
1652                final Ellipse e2_10_16 = EllipseUtilities.ellipseFromCovariance(461.035908f,
1653                                312.042275f, secondMoments2_10_16.inverse(), 1.0f);
1654                doTest(secondMoments1_10_16, secondMoments2_10_16, e1_10_16, e2_10_16,
1655                                0.592315f);
1656                final Matrix secondMoments1_71_16 = new Matrix(new double[][] {
1657                                { 0.001599f, 0.000493f }, { 0.000493f, 0.000924f } });
1658                final Matrix secondMoments2_71_16 = new Matrix(new double[][] {
1659                                { 0.000646f, 0.000223f }, { 0.000223f, 0.000656f } });
1660                final Ellipse e1_71_16 = EllipseUtilities.ellipseFromCovariance(464.640000f,
1661                                315.810000f, secondMoments1_71_16.inverse(), 1.0f);
1662                final Ellipse e2_71_16 = EllipseUtilities.ellipseFromCovariance(466.645900f,
1663                                316.588559f, secondMoments2_71_16.inverse(), 1.0f);
1664                doTest(secondMoments1_71_16, secondMoments2_71_16, e1_71_16, e2_71_16,
1665                                0.550661f);
1666                final Matrix secondMoments1_73_16 = new Matrix(new double[][] {
1667                                { 0.001599f, 0.000493f }, { 0.000493f, 0.000924f } });
1668                final Matrix secondMoments2_73_16 = new Matrix(new double[][] {
1669                                { 0.001083f, -0.000252f }, { -0.000252f, 0.000435f } });
1670                final Ellipse e1_73_16 = EllipseUtilities.ellipseFromCovariance(464.640000f,
1671                                315.810000f, secondMoments1_73_16.inverse(), 1.0f);
1672                final Ellipse e2_73_16 = EllipseUtilities.ellipseFromCovariance(455.662170f,
1673                                321.327603f, secondMoments2_73_16.inverse(), 1.0f);
1674                doTest(secondMoments1_73_16, secondMoments2_73_16, e1_73_16, e2_73_16,
1675                                0.430947f);
1676                final Matrix secondMoments1_386_16 = new Matrix(new double[][] {
1677                                { 0.001599f, 0.000493f }, { 0.000493f, 0.000924f } });
1678                final Matrix secondMoments2_386_16 = new Matrix(new double[][] {
1679                                { 0.000263f, 0.000155f }, { 0.000155f, 0.000596f } });
1680                final Ellipse e1_386_16 = EllipseUtilities.ellipseFromCovariance(464.640000f,
1681                                315.810000f, secondMoments1_386_16.inverse(), 1.0f);
1682                final Ellipse e2_386_16 = EllipseUtilities.ellipseFromCovariance(462.827240f,
1683                                312.515353f, secondMoments2_386_16.inverse(), 1.0f);
1684                doTest(secondMoments1_386_16, secondMoments2_386_16, e1_386_16,
1685                                e2_386_16, 0.328313f);
1686                final Matrix secondMoments1_440_16 = new Matrix(new double[][] {
1687                                { 0.001599f, 0.000493f }, { 0.000493f, 0.000924f } });
1688                final Matrix secondMoments2_440_16 = new Matrix(new double[][] {
1689                                { 0.000720f, 0.000033f }, { 0.000033f, 0.000174f } });
1690                final Ellipse e1_440_16 = EllipseUtilities.ellipseFromCovariance(464.640000f,
1691                                315.810000f, secondMoments1_440_16.inverse(), 1.0f);
1692                final Ellipse e2_440_16 = EllipseUtilities.ellipseFromCovariance(456.316914f,
1693                                311.144240f, secondMoments2_440_16.inverse(), 1.0f);
1694                doTest(secondMoments1_440_16, secondMoments2_440_16, e1_440_16,
1695                                e2_440_16, 0.316909f);
1696                final Matrix secondMoments1_501_16 = new Matrix(new double[][] {
1697                                { 0.001599f, 0.000493f }, { 0.000493f, 0.000924f } });
1698                final Matrix secondMoments2_501_16 = new Matrix(new double[][] {
1699                                { 0.000710f, 0.000061f }, { 0.000061f, 0.000133f } });
1700                final Ellipse e1_501_16 = EllipseUtilities.ellipseFromCovariance(464.640000f,
1701                                315.810000f, secondMoments1_501_16.inverse(), 1.0f);
1702                final Ellipse e2_501_16 = EllipseUtilities.ellipseFromCovariance(456.266983f,
1703                                310.324293f, secondMoments2_501_16.inverse(), 1.0f);
1704                doTest(secondMoments1_501_16, secondMoments2_501_16, e1_501_16,
1705                                e2_501_16, 0.271487f);
1706                final Matrix secondMoments1_573_16 = new Matrix(new double[][] {
1707                                { 0.001599f, 0.000493f }, { 0.000493f, 0.000924f } });
1708                final Matrix secondMoments2_573_16 = new Matrix(new double[][] {
1709                                { 0.000592f, 0.000037f }, { 0.000037f, 0.000142f } });
1710                final Ellipse e1_573_16 = EllipseUtilities.ellipseFromCovariance(464.640000f,
1711                                315.810000f, secondMoments1_573_16.inverse(), 1.0f);
1712                final Ellipse e2_573_16 = EllipseUtilities.ellipseFromCovariance(456.400677f,
1713                                309.131000f, secondMoments2_573_16.inverse(), 1.0f);
1714                doTest(secondMoments1_573_16, secondMoments2_573_16, e1_573_16,
1715                                e2_573_16, 0.259374f);
1716                final Matrix secondMoments1_997_16 = new Matrix(new double[][] {
1717                                { 0.001599f, 0.000493f }, { 0.000493f, 0.000924f } });
1718                final Matrix secondMoments2_997_16 = new Matrix(new double[][] {
1719                                { 0.000183f, 0.000012f }, { 0.000012f, 0.000070f } });
1720                final Ellipse e1_997_16 = EllipseUtilities.ellipseFromCovariance(464.640000f,
1721                                315.810000f, secondMoments1_997_16.inverse(), 1.0f);
1722                final Ellipse e2_997_16 = EllipseUtilities.ellipseFromCovariance(458.808243f,
1723                                308.421958f, secondMoments2_997_16.inverse(), 1.0f);
1724                doTest(secondMoments1_997_16, secondMoments2_997_16, e1_997_16,
1725                                e2_997_16, 0.102489f);
1726                final Matrix secondMoments1_39_17 = new Matrix(new double[][] {
1727                                { 0.001362f, -0.000774f }, { -0.000774f, 0.001346f } });
1728                final Matrix secondMoments2_39_17 = new Matrix(new double[][] {
1729                                { 0.000746f, -0.000533f }, { -0.000533f, 0.001187f } });
1730                final Ellipse e1_39_17 = EllipseUtilities.ellipseFromCovariance(314.600000f,
1731                                318.230000f, secondMoments1_39_17.inverse(), 1.0f);
1732                final Ellipse e2_39_17 = EllipseUtilities.ellipseFromCovariance(313.953694f,
1733                                317.900074f, secondMoments2_39_17.inverse(), 1.0f);
1734                doTest(secondMoments1_39_17, secondMoments2_39_17, e1_39_17, e2_39_17,
1735                                0.697906f);
1736                final Matrix secondMoments1_173_17 = new Matrix(new double[][] {
1737                                { 0.001362f, -0.000774f }, { -0.000774f, 0.001346f } });
1738                final Matrix secondMoments2_173_17 = new Matrix(new double[][] {
1739                                { 0.000538f, -0.000403f }, { -0.000403f, 0.000919f } });
1740                final Ellipse e1_173_17 = EllipseUtilities.ellipseFromCovariance(314.600000f,
1741                                318.230000f, secondMoments1_173_17.inverse(), 1.0f);
1742                final Ellipse e2_173_17 = EllipseUtilities.ellipseFromCovariance(313.225518f,
1743                                318.446818f, secondMoments2_173_17.inverse(), 1.0f);
1744                doTest(secondMoments1_173_17, secondMoments2_173_17, e1_173_17,
1745                                e2_173_17, 0.519941f);
1746                final Matrix secondMoments1_293_17 = new Matrix(new double[][] {
1747                                { 0.001362f, -0.000774f }, { -0.000774f, 0.001346f } });
1748                final Matrix secondMoments2_293_17 = new Matrix(new double[][] {
1749                                { 0.000436f, -0.000319f }, { -0.000319f, 0.000764f } });
1750                final Ellipse e1_293_17 = EllipseUtilities.ellipseFromCovariance(314.600000f,
1751                                318.230000f, secondMoments1_293_17.inverse(), 1.0f);
1752                final Ellipse e2_293_17 = EllipseUtilities.ellipseFromCovariance(312.596572f,
1753                                318.602102f, secondMoments2_293_17.inverse(), 1.0f);
1754                doTest(secondMoments1_293_17, secondMoments2_293_17, e1_293_17,
1755                                e2_293_17, 0.431624f);
1756                final Matrix secondMoments1_295_17 = new Matrix(new double[][] {
1757                                { 0.001362f, -0.000774f }, { -0.000774f, 0.001346f } });
1758                final Matrix secondMoments2_295_17 = new Matrix(new double[][] {
1759                                { 0.000331f, 0.000212f }, { 0.000212f, 0.000842f } });
1760                final Ellipse e1_295_17 = EllipseUtilities.ellipseFromCovariance(314.600000f,
1761                                318.230000f, secondMoments1_295_17.inverse(), 1.0f);
1762                final Ellipse e2_295_17 = EllipseUtilities.ellipseFromCovariance(301.943402f,
1763                                319.295289f, secondMoments2_295_17.inverse(), 1.0f);
1764                doTest(secondMoments1_295_17, secondMoments2_295_17, e1_295_17,
1765                                e2_295_17, 0.373724f);
1766                final Matrix secondMoments1_580_17 = new Matrix(new double[][] {
1767                                { 0.001362f, -0.000774f }, { -0.000774f, 0.001346f } });
1768                final Matrix secondMoments2_580_17 = new Matrix(new double[][] {
1769                                { 0.000206f, 0.000105f }, { 0.000105f, 0.000543f } });
1770                final Ellipse e1_580_17 = EllipseUtilities.ellipseFromCovariance(314.600000f,
1771                                318.230000f, secondMoments1_580_17.inverse(), 1.0f);
1772                final Ellipse e2_580_17 = EllipseUtilities.ellipseFromCovariance(302.970663f,
1773                                318.730723f, secondMoments2_580_17.inverse(), 1.0f);
1774                doTest(secondMoments1_580_17, secondMoments2_580_17, e1_580_17,
1775                                e2_580_17, 0.283702f);
1776                final Matrix secondMoments1_682_17 = new Matrix(new double[][] {
1777                                { 0.001362f, -0.000774f }, { -0.000774f, 0.001346f } });
1778                final Matrix secondMoments2_682_17 = new Matrix(new double[][] {
1779                                { 0.000189f, -0.000086f }, { -0.000086f, 0.000376f } });
1780                final Ellipse e1_682_17 = EllipseUtilities.ellipseFromCovariance(314.600000f,
1781                                318.230000f, secondMoments1_682_17.inverse(), 1.0f);
1782                final Ellipse e2_682_17 = EllipseUtilities.ellipseFromCovariance(309.486674f,
1783                                319.420383f, secondMoments2_682_17.inverse(), 1.0f);
1784                doTest(secondMoments1_682_17, secondMoments2_682_17, e1_682_17,
1785                                e2_682_17, 0.228460f);
1786                final Matrix secondMoments1_789_17 = new Matrix(new double[][] {
1787                                { 0.001362f, -0.000774f }, { -0.000774f, 0.001346f } });
1788                final Matrix secondMoments2_789_17 = new Matrix(new double[][] {
1789                                { 0.000149f, -0.000033f }, { -0.000033f, 0.000329f } });
1790                final Ellipse e1_789_17 = EllipseUtilities.ellipseFromCovariance(314.600000f,
1791                                318.230000f, secondMoments1_789_17.inverse(), 1.0f);
1792                final Ellipse e2_789_17 = EllipseUtilities.ellipseFromCovariance(307.819206f,
1793                                318.726516f, secondMoments2_789_17.inverse(), 1.0f);
1794                doTest(secondMoments1_789_17, secondMoments2_789_17, e1_789_17,
1795                                e2_789_17, 0.196657f);
1796                final Matrix secondMoments1_1030_17 = new Matrix(new double[][] {
1797                                { 0.001362f, -0.000774f }, { -0.000774f, 0.001346f } });
1798                final Matrix secondMoments2_1030_17 = new Matrix(new double[][] {
1799                                { 0.000092f, -0.000018f }, { -0.000018f, 0.000159f } });
1800                final Ellipse e1_1030_17 = EllipseUtilities.ellipseFromCovariance(
1801                                314.600000f, 318.230000f, secondMoments1_1030_17.inverse(),
1802                                1.0f);
1803                final Ellipse e2_1030_17 = EllipseUtilities.ellipseFromCovariance(
1804                                307.429140f, 320.516190f, secondMoments2_1030_17.inverse(),
1805                                1.0f);
1806                doTest(secondMoments1_1030_17, secondMoments2_1030_17, e1_1030_17,
1807                                e2_1030_17, 0.109040f);
1808                final Matrix secondMoments1_1156_17 = new Matrix(new double[][] {
1809                                { 0.001362f, -0.000774f }, { -0.000774f, 0.001346f } });
1810                final Matrix secondMoments2_1156_17 = new Matrix(new double[][] {
1811                                { 0.000078f, -0.000019f }, { -0.000019f, 0.000097f } });
1812                final Ellipse e1_1156_17 = EllipseUtilities.ellipseFromCovariance(
1813                                314.600000f, 318.230000f, secondMoments1_1156_17.inverse(),
1814                                1.0f);
1815                final Ellipse e2_1156_17 = EllipseUtilities.ellipseFromCovariance(
1816                                307.771879f, 324.116857f, secondMoments2_1156_17.inverse(),
1817                                1.0f);
1818                doTest(secondMoments1_1156_17, secondMoments2_1156_17, e1_1156_17,
1819                                e2_1156_17, 0.077324f);
1820                final Matrix secondMoments1_1207_17 = new Matrix(new double[][] {
1821                                { 0.001362f, -0.000774f }, { -0.000774f, 0.001346f } });
1822                final Matrix secondMoments2_1207_17 = new Matrix(new double[][] {
1823                                { 0.000069f, -0.000007f }, { -0.000007f, 0.000070f } });
1824                final Ellipse e1_1207_17 = EllipseUtilities.ellipseFromCovariance(
1825                                314.600000f, 318.230000f, secondMoments1_1207_17.inverse(),
1826                                1.0f);
1827                final Ellipse e2_1207_17 = EllipseUtilities.ellipseFromCovariance(
1828                                305.410180f, 323.894917f, secondMoments2_1207_17.inverse(),
1829                                1.0f);
1830                doTest(secondMoments1_1207_17, secondMoments2_1207_17, e1_1207_17,
1831                                e2_1207_17, 0.060606f);
1832                final Matrix secondMoments1_89_18 = new Matrix(new double[][] {
1833                                { 0.001609f, -0.000768f }, { -0.000768f, 0.001134f } });
1834                final Matrix secondMoments2_89_18 = new Matrix(new double[][] {
1835                                { 0.000844f, -0.000444f }, { -0.000444f, 0.000933f } });
1836                final Ellipse e1_89_18 = EllipseUtilities.ellipseFromCovariance(122.210000f,
1837                                323.070000f, secondMoments1_89_18.inverse(), 1.0f);
1838                final Ellipse e2_89_18 = EllipseUtilities.ellipseFromCovariance(121.248810f,
1839                                322.865319f, secondMoments2_89_18.inverse(), 1.0f);
1840                doTest(secondMoments1_89_18, secondMoments2_89_18, e1_89_18, e2_89_18,
1841                                0.691817f);
1842                final Matrix secondMoments1_90_18 = new Matrix(new double[][] {
1843                                { 0.001609f, -0.000768f }, { -0.000768f, 0.001134f } });
1844                final Matrix secondMoments2_90_18 = new Matrix(new double[][] {
1845                                { 0.000938f, 0.000083f }, { 0.000083f, 0.000707f } });
1846                final Ellipse e1_90_18 = EllipseUtilities.ellipseFromCovariance(122.210000f,
1847                                323.070000f, secondMoments1_90_18.inverse(), 1.0f);
1848                final Ellipse e2_90_18 = EllipseUtilities.ellipseFromCovariance(125.111521f,
1849                                334.004283f, secondMoments2_90_18.inverse(), 1.0f);
1850                doTest(secondMoments1_90_18, secondMoments2_90_18, e1_90_18, e2_90_18,
1851                                0.528642f);
1852                final Matrix secondMoments1_180_18 = new Matrix(new double[][] {
1853                                { 0.001609f, -0.000768f }, { -0.000768f, 0.001134f } });
1854                final Matrix secondMoments2_180_18 = new Matrix(new double[][] {
1855                                { 0.000814f, -0.000393f }, { -0.000393f, 0.000748f } });
1856                final Ellipse e1_180_18 = EllipseUtilities.ellipseFromCovariance(122.210000f,
1857                                323.070000f, secondMoments1_180_18.inverse(), 1.0f);
1858                final Ellipse e2_180_18 = EllipseUtilities.ellipseFromCovariance(121.634598f,
1859                                323.117841f, secondMoments2_180_18.inverse(), 1.0f);
1860                doTest(secondMoments1_180_18, secondMoments2_180_18, e1_180_18,
1861                                e2_180_18, 0.605201f);
1862                final Matrix secondMoments1_181_18 = new Matrix(new double[][] {
1863                                { 0.001609f, -0.000768f }, { -0.000768f, 0.001134f } });
1864                final Matrix secondMoments2_181_18 = new Matrix(new double[][] {
1865                                { 0.000579f, 0.000129f }, { 0.000129f, 0.000783f } });
1866                final Ellipse e1_181_18 = EllipseUtilities.ellipseFromCovariance(122.210000f,
1867                                323.070000f, secondMoments1_181_18.inverse(), 1.0f);
1868                final Ellipse e2_181_18 = EllipseUtilities.ellipseFromCovariance(124.290424f,
1869                                334.918246f, secondMoments2_181_18.inverse(), 1.0f);
1870                doTest(secondMoments1_181_18, secondMoments2_181_18, e1_181_18,
1871                                e2_181_18, 0.439394f);
1872                final Matrix secondMoments1_451_18 = new Matrix(new double[][] {
1873                                { 0.001609f, -0.000768f }, { -0.000768f, 0.001134f } });
1874                final Matrix secondMoments2_451_18 = new Matrix(new double[][] {
1875                                { 0.000434f, -0.000197f }, { -0.000197f, 0.000569f } });
1876                final Ellipse e1_451_18 = EllipseUtilities.ellipseFromCovariance(122.210000f,
1877                                323.070000f, secondMoments1_451_18.inverse(), 1.0f);
1878                final Ellipse e2_451_18 = EllipseUtilities.ellipseFromCovariance(120.562590f,
1879                                323.776546f, secondMoments2_451_18.inverse(), 1.0f);
1880                doTest(secondMoments1_451_18, secondMoments2_451_18, e1_451_18,
1881                                e2_451_18, 0.411040f);
1882                final Matrix secondMoments1_452_18 = new Matrix(new double[][] {
1883                                { 0.001609f, -0.000768f }, { -0.000768f, 0.001134f } });
1884                final Matrix secondMoments2_452_18 = new Matrix(new double[][] {
1885                                { 0.000400f, 0.000070f }, { 0.000070f, 0.000535f } });
1886                final Ellipse e1_452_18 = EllipseUtilities.ellipseFromCovariance(122.210000f,
1887                                323.070000f, secondMoments1_452_18.inverse(), 1.0f);
1888                final Ellipse e2_452_18 = EllipseUtilities.ellipseFromCovariance(123.132287f,
1889                                334.051363f, secondMoments2_452_18.inverse(), 1.0f);
1890                doTest(secondMoments1_452_18, secondMoments2_452_18, e1_452_18,
1891                                e2_452_18, 0.370512f);
1892                final Matrix secondMoments1_689_18 = new Matrix(new double[][] {
1893                                { 0.001609f, -0.000768f }, { -0.000768f, 0.001134f } });
1894                final Matrix secondMoments2_689_18 = new Matrix(new double[][] {
1895                                { 0.000281f, 0.000029f }, { 0.000029f, 0.000357f } });
1896                final Ellipse e1_689_18 = EllipseUtilities.ellipseFromCovariance(122.210000f,
1897                                323.070000f, secondMoments1_689_18.inverse(), 1.0f);
1898                final Ellipse e2_689_18 = EllipseUtilities.ellipseFromCovariance(122.579885f,
1899                                333.188132f, secondMoments2_689_18.inverse(), 1.0f);
1900                doTest(secondMoments1_689_18, secondMoments2_689_18, e1_689_18,
1901                                e2_689_18, 0.282375f);
1902
1903        }
1904
1905        private static void doTest(Matrix secondMoments1, Matrix secondMoments2,
1906                        Ellipse e1, Ellipse e2, float f)
1907        {
1908                System.out.println(e1 + " vs " + e2);
1909                final IPDRepeatability<EllipticInterestPointData> dummy = new IPDRepeatability<EllipticInterestPointData>();
1910                final double overlap = dummy.calculateOverlapPercentageOxford(secondMoments1,
1911                                secondMoments2, e1, e2, 4.0f);
1912                System.out
1913                                .format("\tGot overlap: %4.2f, expecting %4.2f\n", overlap, f);
1914                if (Math.abs(f - overlap) > 0.02) {
1915                        System.err.println("THERE WAS AN ERROR WITH THE ABOVE ELLIPSE!!");
1916                }
1917        }
1918}