为了找到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
在图片上我们可以看到匹配被绘制但只有一个绿点。它应该是绿色的轮廓,而不仅仅是一个点。 和图片: