findHomography返回负值

时间:2014-04-15 22:21:13

标签: java opencv computer-vision homography

为了找到2张图片之间的单应性,我使用的是OpenCV 2.4.8,java版本却出现了以下问题:

我可以找到超过2千个匹配但findHomography函数返回一些负值。单应性的声明如下:

Mat homography = Calib3d.findHomography(goodReferencePoints, goodScenePoints);

正如你在我的终端中看到的那样,单应性会返回这些负值:

  

H = [0.0728467050846091,-1.778341899752422,523.4269328629535;   0.05293440263461851,-1.283649810597391,377.7784434651413;   0.0001384401936905583,-0.003397194330027168,1]

最后的1对我来说似乎是正确的,但这些是这些矩阵中唯一正确的值:/

知道为什么吗?我怎样才能获得更好的Matrix?

提前谢谢

我的代码:

    private void findCorners() {

    Mat img_matches = new Mat();

    List<DMatch> matchesList = matches.toList();
    if (matchesList.size() < 4) {
        // There are too few matches to find the homography.
        System.err.println("There are too few matches to find the homography.");
        return;
    }

    List<KeyPoint> object_keypoints_list = object_keypoints.toList();
    List<KeyPoint> scene_keypoints_list = scene_keypoints.toList();
    this.object_good_keypoints = new ArrayList<KeyPoint>();
    this.scene_good_keypoints = new ArrayList<KeyPoint>();

    // Calculate the max and min distances between keypoints.
    double maxDist = 0.0;
    double minDist = Double.MAX_VALUE;
    for(DMatch match : matchesList) {
        double dist = match.distance;
        if (dist < minDist) {
            minDist = dist;
        }
        if (dist > maxDist) {
            maxDist = dist;
        }
    }

    // The thresholds for minDist are chosen subjectively
    // based on testing. The unit is not related to pixel
    // distances; it is related to the number of failed tests
    // for similarity between the matched descriptors.
    if (minDist > 50.0) {
        // The target is completely lost.
        // Discard any previously found corners.
        scene_corners.create(0, 0, scene_corners.type());
        return;
    } else if (minDist > 20.0) {
        // The target is lost but maybe it is still close.
        // Keep any previously found corners.
        System.err.println("The target is lost but maybe it is still close. Keep any previously found corners.");
        return;
    }


    // Identify "good" keypoints based on match distance.
    ArrayList<Point> goodReferencePointsList = new ArrayList<Point>();
    ArrayList<Point> goodScenePointsList = new ArrayList<Point>();

    double maxGoodMatchDist = 1.75 * minDist;
    for(DMatch match : matchesList) {
        if (match.distance < maxGoodMatchDist) {
           goodReferencePointsList.add(
                   object_keypoints_list.get(match.queryIdx).pt);
           goodScenePointsList.add(
                   scene_keypoints_list.get(match.trainIdx).pt);
           this.object_good_keypoints.add(object_keypoints_list.get(match.queryIdx));
           this.scene_good_keypoints.add(scene_keypoints_list.get(match.trainIdx));
        }
    }

    if (goodReferencePointsList.size() < 4 ||
            goodScenePointsList.size() < 4) {
        // There are too few good points to find the homography.
        System.err.println("There are too few good points to find the homography.");
        return;
    }

    System.out.println("Match found");

    MatOfPoint2f goodReferencePoints = new MatOfPoint2f();
    goodReferencePoints.fromList(goodReferencePointsList);

    MatOfPoint2f goodScenePoints = new MatOfPoint2f();
    goodScenePoints.fromList(goodScenePointsList);

    System.out.println("goodReferencePoints size ="+goodReferencePoints.size());
    System.out.println("goodScenePoints size ="+goodScenePoints.size());

    Mat homography = Calib3d.findHomography(goodReferencePoints, goodScenePoints);

    System.out.println("homography = "+homography.dump());

    object_corners = new Mat(4, 1, CvType.CV_32FC2);
    scene_corners = new Mat(4, 1, CvType.CV_32FC2);

    object_corners.put(0, 0, new double[] { 0, 0 });
    object_corners.put(1, 0, new double[] { object_image.cols(), 0 });
    object_corners.put(2, 0, new double[] { object_image.cols(), object_image.rows() });
    object_corners.put(3, 0, new double[] { 0, object_image.rows() });

    Core.perspectiveTransform(object_corners, scene_corners, homography);

    print_corners();

    Point p0 = new Point(scene_corners.get(0, 0));
    Point p1 = new Point(scene_corners.get(1, 0));
    Point p2 = new Point(scene_corners.get(2, 0));
    Point p3 = new Point(scene_corners.get(3, 0));
    int offset = (int) new Point(object_corners.get(1, 0)).x;

    System.out.println("Matches size = "+matches.size());

    MatOfKeyPoint object_good_kp = new MatOfKeyPoint();
    object_good_kp.fromList(this.object_good_keypoints);
    MatOfKeyPoint scene_good_kp = new MatOfKeyPoint();
    scene_good_kp.fromList(this.scene_good_keypoints);

    System.out.println("object kps = "+this.object_keypoints.size());
    System.out.println("object good kps = "+this.object_good_keypoints.size());
    System.out.println("scene kps = "+this.scene_keypoints.size());
    System.out.println("scene good kps = "+this.scene_good_keypoints.size());

    Features2d.drawMatches(object_image, object_keypoints, scene_image, scene_keypoints, matches, img_matches, new Scalar(255, 0, 0),
            new Scalar(0, 0, 255), new MatOfByte(), 2);

    Core.line(img_matches, new Point(p0.x+offset, p0.y), new Point(p1.x+offset, p1.y), COLOR_GREEN, 4);
    Core.line(img_matches, new Point(p1.x+offset, p1.y), new Point(p2.x+offset, p2.y), COLOR_GREEN, 4);
    Core.line(img_matches, new Point(p2.x+offset, p2.y), new Point(p3.x+offset, p3.y), COLOR_GREEN, 4);
    Core.line(img_matches, new Point(p3.x+offset, p3.y), new Point(p0.x+offset, p0.y), COLOR_GREEN, 4);

    System.out.println(String.format("-- Writing result Mat in %s", pathResult));
    Highgui.imwrite(pathResult, img_matches);

}

这里是终端输出,我们可以看到单应矩阵有一些负值:

Match found
goodReferencePoints size =1x10
goodScenePoints size =1x10
homography = [0.0728467050846091, -1.778341899752422, 523.4269328629535;
  0.05293440263461851, -1.283649810597391, 377.7784434651413;
  0.0001384401936905583, -0.003397194330027168, 1]
-- Object-Point 0 [0,0]
-- Object-Point 1 [259,0]
-- Object-Point 2 [259,878]
-- Object-Point 3 [0,878]
-- Scene-Point 0 [523.43,377.78]
-- Scene-Point 1 [523.52,377.94]
-- Scene-Point 2 [523.45,377.81]
-- Scene-Point 3 [523.5,377.89]
Matches size = 1x2341
object kps = 1x2341
object good kps = 10
scene kps = 1x2576
scene good kps = 10

在图片上我们可以看到匹配被绘制但只有一个绿点。它应该是绿色的轮廓,而不仅仅是一个点。 和图片: On the picture we can see the matches and just one green point which should be the 4 corners...

0 个答案:

没有答案