Error matching with ORB in Android
android, opencv
Solution
Your code should be like this:
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);
Also if you want to display just features, you can add this code:
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);
Then you can show matched points like this:
Bitmap imageMatched = Bitmap.createBitmap(outputImg.cols(), outputImg.rows(), Bitmap.Config.RGB_565);//need to save bitmap
Utils.matToBitmap(outputImg, imageMatched);
ImageView.setImageBitmap(imageMatched);
Eventually you can implement good matches. I hope this thread will be helpful.
Problem
My code is working good but when it extracts keypoints, it matches poorly the two images. Here you can find my code, but I don't know how to draw good matched in `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); ``` any suggestion? EDIT : i can't convert matches to list ! because `Feature2d.drawMatches()` need a `MatOfDmatch` and not a `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); ```