2013-03-21 27 views
9

我的代碼運行良好,但是當它提取關鍵點時,它與兩個圖像匹配不佳。 在這裏你可以找到我的代碼,但我不知道如何繪製JAVA Android在Android中與ORB匹配的錯誤

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); 
+1

你能否修復代碼的縮進? – 2013-03-21 09:57:18

+0

此代碼用於使用ORB提取兩個圖像的關鍵點,目標是我想提取良好的匹配並繪製它 只是全部 – Mirlo 2013-03-21 10:38:10

回答

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); 

最終你可以實現良好火柴。我希望this thread會有所幫助。

+1

嗨,謝謝你的迴應,現在我想找到一個很好的條件,找到一個很好的相似性,但這種情況不是有效的,爲什麼? if(row_count> 490 && good_matches.size()<60 && min_dist <12)logo_detected = true; else logo_detected = false; – Mirlo 2013-04-20 15:44:58

+0

您的歡迎。我不想誤導,但我認爲這取決於您的工作。你必須爲你自己的項目計算。 – COvayurt 2013-04-21 10:08:56

+0

我已經使用了你的代碼,並用10-12張圖片進行了測試,但是它並沒有給出完美的匹配,我只是想找到完全匹配位置的座標,但是它不能給我完美的結果。如果可能的話,給我的方式,我可以增加匹配的準確性 – 2014-01-03 11:13:46

5

良好匹配方法基礎上,從您的MatOfDMatch matches = new MatOfDMatch();列表中刪除與之匹配的是有不同的描述或空間位置點。我的建議做的是循環在比賽名單並投入是滿足條件一樣的新的列表匹配:

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); 

你可以用匹配點做同樣的事情座標。 Here是有用的鏈接。

+0

我無法將匹配轉換爲列表!因爲Feature2d.drawMatches() 需要MatOfDmatch而不是列表 MatOfDMatch **匹配**,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) //將前進添加到**匹配** Features2d.drawMatches(img1,keypoints,mGraySubmat,mKeyPoints,** matches **,mIntermediateMat2); – Mirlo 2013-03-21 13:14:59

+0

你可以用'MatOfDMatch matches = new MatOfDMatch(); \t \t \t matches.fromList(matches_final);'。這不是很有效,但我沒有看到另一種方式在java中做好匹配。 – andriy 2013-03-21 14:22:33

+0

是的thnx我解釋了爲什麼? 如果我們調用函數C++ jni? 你有沒有另一種解決方案 – Mirlo 2013-03-21 14:45:12