2

2つの画像間で適切な一致features2d(すべての一致ではない)を描画するために使用したいので、次のコードスニペットを使用しました:

Mat gray1 = //image1 converted to gray
Mat gray2 = //image2 converted to gray

MatOfDMatch matches = new MatOfDMatch();
MatOfDMatch gm = new MatOfDMatch();

LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
MatOfKeyPoint keypoints_object = new MatOfKeyPoint();
MatOfKeyPoint keypoints_scene = new MatOfKeyPoint();
Mat descriptors_object = new Mat();
Mat descriptors_scene = new Mat();
FeatureDetector fd = FeatureDetector.create(FeatureDetector.ORB);

fd.detect(gray1, keypoints_object);
fd.detect(gray2, keypoints_scene);
// – Step 2: Calculate descriptors (feature vectors)
DescriptorExtractor extractor = DescriptorExtractor
.create(DescriptorExtractor.ORB);

extractor.compute(gray1, keypoints_object, descriptors_object);
extractor.compute(gray2, keypoints_scene, descriptors_scene);
DescriptorMatcher matcher = DescriptorMatcher
.create(DescriptorMatcher.BRUTEFORCE_HAMMING);

matcher.match(descriptors_object, descriptors_scene, matches);

double max_dist = 0;
double min_dist = 100;
List<DMatch> matchesList = matches.toList();

// – Quick calculation of max and min distances between keypoints
for (int i = 0; i < descriptors_object.rows(); i++) {
    Double dist = (double) matchesList.get(i).distance;
    if (dist < min_dist)
    min_dist = dist;
    if (dist > max_dist)
    max_dist = dist;
}

for (int i = 0; i < descriptors_object.rows(); i++) {
    if (matchesList.get(i).distance <= 3 * min_dist) {
        good_matches.addLast(matchesList.get(i));
    }
}

gm.fromList(good_matches);

List<KeyPoint> keypoints_objectList = keypoints_object.toList();
List<KeyPoint> keypoints_sceneList = keypoints_scene.toList();

MatOfKeyPoint matOfObjectGoodKeyPoints = new MatOfKeyPoint();
MatOfKeyPoint matOfSceneGoodKeyPoints = new MatOfKeyPoint();
LinkedList<KeyPoint> listOfObjectGoodKeyPoints = new LinkedList<KeyPoint>();
LinkedList<KeyPoint> listOfSceneGoodKeyPoints = new LinkedList<KeyPoint>();
for (int i = 0; i < good_matches.size(); i++) {
    listOfObjectGoodKeyPoints.addLast(keypoints_objectList
    .get(good_matches.get(i).queryIdx));
    listOfSceneGoodKeyPoints.addLast(keypoints_sceneList
    .get(good_matches.get(i).trainIdx));
}
matOfObjectGoodKeyPoints.fromList(listOfObjectGoodKeyPoints);
matOfSceneGoodKeyPoints.fromList(listOfSceneGoodKeyPoints);

// feature and connection colors
Scalar RED = new Scalar(255, 0, 0);
// output image
Mat outputImg = new Mat();
MatOfByte drawnMatches = new MatOfByte();
// this would draw good matches,but not works fine:
Features2d.drawMatches(gray1, matOfObjectGoodKeyPoints, gray2,
matOfSceneGoodKeyPoints, gm, outputImg, Scalar.all(-1), RED,
drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);

しかし、実行時に、このエラーが発生します:

CvException ... features2d/src/draw.cpp:208: エラー: (-215) i2 >= 0 && i2 < static_cast(keypoints2.size())

コードの問題は何ですか?

4

1 に答える 1

2

問題は、フィルタリングされたリスト (つまりmatOfSceneGoodKeyPoints) を に与えることですdrawMatches()。ただし、適切な一致リストgmには、元のリストに基づくインデックスが含まれています。だからに変更

Features2d.drawMatches(gray1, keypoints_object, gray2,
keypoints_scene, gm, outputImg, Scalar.all(-1), RED,
drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);

そしてあなたはあなたが欲しかったものを持っています。引き分けられた一致は、中のもののみが使用されるため、依然として最良のものに制限さgmれます。

于 2015-03-06T14:31:26.017 に答える