0

我尝试使用适用于我的一个测试用例的 OpenCV for android 实现图像对齐,但它无法在另一个测试用例上运行。

测试用例 #1 - 我的代码适用于:

给定两个图像,例如Scene ImageObject Image

我希望输出对象图像与场景图像对齐。查看最终输出

测试用例 #2 - 我的代码不起作用:

给定图像、场景图像对象图像

我得到了这个特征匹配结果,并将作为warpPerspective的输出。

我的问题是,谁能告诉我为什么我无法在第二个测试用例中对齐图像。

Mat mObjectMat = new Mat();
    Mat mSceneMat = new Mat();
    Mat img3 = mSceneMat.clone();

    //Bitmap to Mat
    Utils.bitmapToMat(inputImage2, mObjectMat);
    Utils.bitmapToMat(inputImage1, mSceneMat);

    //rgb to gray
    Imgproc.cvtColor(mObjectMat, mObjectMat, Imgproc.COLOR_RGBA2GRAY);
    Imgproc.cvtColor(mSceneMat, mSceneMat, Imgproc.COLOR_RGBA2GRAY);

    //find interest points/keypoints in an image
    MatOfKeyPoint keypoints_object = new MatOfKeyPoint();
    MatOfKeyPoint keypoints_scene = new MatOfKeyPoint();
    FeatureDetector fd = FeatureDetector.create(FeatureDetector.ORB);
    fd.detect(mObjectMat, keypoints_object);
    fd.detect(mSceneMat, keypoints_scene);

    //extract descriptor
    Mat descriptors_object = new Mat();
    Mat descriptors_scene = new Mat();
    DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.ORB);
    extractor.compute(mObjectMat, keypoints_object, descriptors_object);
    extractor.compute(mSceneMat, keypoints_scene, descriptors_scene);

    //match keypoint descriptors
    MatOfDMatch matches = new MatOfDMatch();
    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
    matcher.match( descriptors_object, descriptors_scene, matches);
    List<DMatch> matchesList = matches.toList();

    //Calculate max and min distances between keypoints
    matchesList = matches.toList();
    Double maxDistance = 0.0;
    Double minDistance = 100.0;
    for( int i = 0; i < descriptors_object.rows(); i++ )
    {
        Double dist = (double) matchesList.get(i).distance;
        if( dist < minDistance ) minDistance = dist;
        if( dist > maxDistance ) maxDistance = dist;
    }

    //display
    Toast.makeText(getApplicationContext(), "[ Max dist : " + maxDistance + " ] [ Min dist : " + minDistance + " ]", Toast.LENGTH_LONG).show();

    //find good matches
    LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
    MatOfDMatch gm = new MatOfDMatch();
    //Draw only good matches
    for(int i = 0; i < descriptors_object.rows(); i++){
        if(matchesList.get(i).distance < 3*minDistance){
            good_matches.addLast(matchesList.get(i));
        }
    }
    gm.fromList(good_matches);

    //display matches on imageView
    Mat opt = new Mat();
    Scalar RED = new Scalar(255,0,0);
    Scalar GREEN = new Scalar(0,255,0);
    MatOfByte drawnMatches = new MatOfByte();
    Features2d.drawMatches(mObjectMat,keypoints_object,mSceneMat,keypoints_scene,gm,opt,GREEN, RED,  drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);

    List<KeyPoint> keypoints_objectList = keypoints_object.toList();
    List<KeyPoint> keypoints_sceneList = keypoints_scene.toList();
    LinkedList<Point> objList = new LinkedList<Point>();
    LinkedList<Point> sceneList = new LinkedList<Point>();
    MatOfPoint2f obj = new MatOfPoint2f();
    MatOfPoint2f scene = new MatOfPoint2f();

    //Localize the object & find the keypoints from the good matches
    //separate corresponding points for both images
    for(int i = 0; i<good_matches.size(); i++){
        objList.addLast(keypoints_objectList.get(good_matches.get(i).queryIdx).pt);
        sceneList.addLast(keypoints_sceneList.get(good_matches.get(i).trainIdx).pt);
    }
    obj.fromList(objList);
    scene.fromList(sceneList);

    //Find homography - perspective transformation between two planes
    Mat H = Calib3d.findHomography(obj, scene, Calib3d.RANSAC);

    //perform perspective warp
    Mat imgWarped = new Mat();
    Imgproc.warpPerspective(mObjectMat, imgWarped, H, mSceneMat.size());

    //warp and scene images
    Mat finalImage = new Mat();
    Core.add(mSceneMat, imgWarped,finalImage);

    //add image to imageView
    Bitmap imageMatched = Bitmap.createBitmap(finalImage.cols(), finalImage.rows(), Bitmap.Config.RGB_565);//need to save bitmap
    Utils.matToBitmap(finalImage, imageMatched);
    imageView1.setImageBitmap(imageMatched);
4

0 回答 0