9

私のコードはうまく機能していますが、キーポイントを抽出すると、2 つの画像がうまく一致しません。ここで私のコードを見つけることができますが、適切な一致を描画する方法がわかりませんJAVA Android

 descriptors = new Mat();
        keypoints = new MatOfKeyPoint();
        detector = FeatureDetector.create(FeatureDetector.ORB);
        detector.detect(img1, keypoints);
        descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);
        descriptor.compute(img1, keypoints, descriptors);
        matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
     ColorDetection.cvt_YUVtoRGBtoHSV(mYuv,mGraySubmat);
          MatOfKeyPoint mKeyPoints = new MatOfKeyPoint();
        MatOfDMatch  matches = new MatOfDMatch();

          detector.detect(mGraySubmat, mKeyPoints);
          descriptor.compute(mGraySubmat, mKeyPoints, mIntermediateMat);

        matcher.match(mIntermediateMat,descriptors,matches);
        mIntermediateMat2.create(resultSize, CvType.CV_8UC1);
        Features2d.drawMatches(img1, keypoints, mGraySubmat, mKeyPoints, matches, 
                mIntermediateMat2,GREEN, RED,  MATCH_MASK, Features2d.NOT_DRAW_SINGLE_POINTS);

          Imgproc.resize(mIntermediateMat2, mIntermediateMat2, mRgba.size());
          Imgproc.cvtColor(mIntermediateMat2, mRgba, Imgproc.COLOR_RGBA2BGRA, 4);
     Utils.matToBitmap(mRgba, bmp);

      DMatch dm[] = matches.toArray();
          List<Point> lp1 = new ArrayList<Point>(dm.length);
          List<Point> lp2 = new ArrayList<Point>(dm.length);
          KeyPoint tkp[] = keypoints.toArray();
          KeyPoint qkp[] = mKeyPoints.toArray();
          for (int i = 0; i < dm.length; i++) {
              DMatch dma = dm[i];
              lp1.add(tkp[dma.trainIdx].pt);
              lp2.add(qkp[dma.queryIdx].pt);
          }
          MatOfPoint2f pointsPrev = new MatOfPoint2f(lp1.toArray(new Point[0]));
          MatOfPoint2f pointsAct  = new MatOfPoint2f(lp2.toArray(new Point[0]));
        Log.i("pointsPrev", pointsPrev.size().toString());
        Log.i("pointsAct", pointsAct.size().toString());
          fundamental_matrix.create(resultSize, CvType.CV_8UC1);
        fundamental_matrix = Calib3d.findFundamentalMat(
                  pointsAct, pointsPrev, Calib3d.FM_RANSAC, 3, 0.99);

なにか提案を?

編集 :

マッチをリストに変換できません! がFeature2d.drawMatches() 必要であり、MatOfDmatchではないためList<Dmatch>

MatOfDMatch matches, matches12, matches21;
matcher.match( descriptors1, descriptors2, matches12 );
matcher.match( descriptors2, descriptors1, matches21 );

iterate matches12
    DMatch forward = matches12[i];  
    DMatch backward = matches21[forward.trainIdx]; 
    if( backward.trainIdx == forward.queryIdx ) 
 //add forward to matches 
Features2d.drawMatches(img1, keypoints, mGraySubmat, mKeyPoints, matches,mIntermediateMat2);
4

2 に答える 2

15

コードは次のようになります。

 FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
 DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);;
 DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);

 //first image
 Mat img1 = Highgui.imread("<image1 path>");
 Mat descriptors1 = new Mat();
 MatOfKeyPoint keypoints1 = new MatOfKeyPoint();

 detector.detect(img1, keypoints1);
 descriptor.compute(img1, keypoints1, descriptors1);

 //second image
 Mat img2 = Highgui.imread("<image2 path>");
 Mat descriptors2 = new Mat();
 MatOfKeyPoint keypoints2 = new MatOfKeyPoint();

 detector.detect(img2, keypoints2);
 descriptor.compute(img2, keypoints2, descriptors2);

 //matcher should include 2 different image's descriptors
 MatOfDMatch  matches = new MatOfDMatch();             
 matcher.match(descriptors1,descriptors2,matches);
 //feature and connection colors
 Scalar RED = new Scalar(255,0,0);
 Scalar GREEN = new Scalar(0,255,0);
 //output image
 Mat outputImg = new Mat();
 MatOfByte drawnMatches = new MatOfByte();
 //this will draw all matches, works fine
 Features2d.drawMatches(img1, keypoints1, img2, keypoints2, matches, 
 outputImg, GREEN, RED,  drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);

また、機能だけを表示したい場合は、次のコードを追加できます。

 Mat featuredImg = new Mat();
 Scalar kpColor = new Scalar(255,159,10);//this will be color of keypoints
 //featuredImg will be the output of first image
 Features2d.drawKeypoints(img1, keypoints1, featuredImg , kpColor, 0);
 //featuredImg will be the output of first image
 Features2d.drawKeypoints(img1, keypoints1, featuredImg , kpColor, 0);

次に、次のように一致したポイントを表示できます。

  Bitmap imageMatched = Bitmap.createBitmap(outputImg.cols(), outputImg.rows(), Bitmap.Config.RGB_565);//need to save bitmap
  Utils.matToBitmap(outputImg, imageMatched);
  ImageView.setImageBitmap(imageMatched);

最終的には、適切な一致を実装できます。このスレッドが役立つことを願っています。

于 2013-04-19T14:31:52.897 に答える
5

MatOfDMatch matches = new MatOfDMatch();Good Matches メソッドは、異なる記述子または空間的位置を持つ一致したポイントをリストから削除することに基づいています。私が提案するのは、一致リストをループして、次のような条件を満たす新しいリストの一致に入れることです。

int DIST_LIMIT = 80;
List<DMatch> matchesList = matches.toList();
List<DMatch> matches_final= new ArrayList<DMatch>();
for(int i=0; i<matchesList.size(); i++)
   if(matchesList .get(i).distance <= DIST_LIMIT){
       matches_final.add(matches.toList().get(i));
   }
}

MatOfDMatch matches_final_mat = new MatOfDMatch();
matches_final_mat.fromList(matches_final);

一致したポイントの座標でも同じことができます。 ここに便利なリンクがあります。

于 2013-03-21T11:41:10.667 に答える