Ask Your Question

Revision history [back]

Stitching panorama images of blank walls

Hi everyone!

Im currently working on a stitching project for Unity. My code works fine for stitching images as of the moment except when I'm trying to stitch photos with large blank walls. It's because of the lack of the features to detect. I tried looking up possible solutions for this but I am currently empty handed. This is my current code:

save_path = Application.persistentDataPath + "/";
first_mat = Highgui.imread(save_path + "1.jpg", Highgui.IMREAD_COLOR);
second_mat = Highgui.imread(save_path + "2.jpg",Highgui.IMREAD_COLOR);

pr2 = Stitching(second_mat, first_mat);

Imgproc.cvtColor(pr2, pr2, Imgproc.COLOR_BGR2RGB);

//Preview Image     
_Texture1 = new Texture2D (pr2.cols (), pr2.rows (), TextureFormat.RGBA32, false);
Utils.matToTexture2D (pr2, _Texture1);
ImagePreview.texture = _Texture1;

This is my stitching class:

Mat Stitching (Mat first_mat, Mat second_mat) 
    {
        FeatureDetector detector = FeatureDetector.create (FeatureDetector.ORB);
        DescriptorExtractor extractor = DescriptorExtractor.create (DescriptorExtractor.ORB);

    MatOfKeyPoint keypointsSrc = new MatOfKeyPoint ();
    Mat descriptorsSrc = new Mat ();

    detector.detect (first_mat, keypointsSrc);
    extractor.compute (first_mat, keypointsSrc, descriptorsSrc);

    MatOfKeyPoint keypointsScene = new MatOfKeyPoint ();
    Mat descriptorsScene = new Mat ();

    detector.detect (second_mat, keypointsScene);
    extractor.compute (second_mat, keypointsScene, descriptorsScene);

    DescriptorMatcher matcher = DescriptorMatcher.create (DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);
    MatOfDMatch matches = new MatOfDMatch ();

    matcher.match (descriptorsSrc, descriptorsScene, matches);

    //////////////////////////////////////////////////////////////////////////////////////////////////

    List<DMatch> matchesList = matches.toList ();

    double max_dist = 0;
    double min_dist = 100;
    for (int i = 0; i < descriptorsSrc.rows (); i++) {

        double dist = (double)matchesList [i].distance;
        if (dist < min_dist)
            min_dist = dist;
        if (dist > max_dist)
            max_dist = dist;
    }

    List<DMatch> good_matches = new List<DMatch> ();
    for (int i = 0; i < descriptorsSrc.rows (); i++) {
        if (matchesList [i].distance < 4*min_dist) {
            good_matches.Add (matchesList [i]);
        }
    }
    MatOfDMatch gm = new MatOfDMatch ();
    gm.fromList (good_matches);

    List<Point> objList = new List<Point> ();
    List<Point> sceneList = new List<Point> ();

    List<KeyPoint> keypoints_objectList = keypointsSrc.toList ();
    List<KeyPoint> keypoints_sceneList = keypointsScene.toList ();

    for (int i = 0; i < good_matches.Count; i++) {
        objList.Add (keypoints_objectList [good_matches [i].queryIdx].pt);
        sceneList.Add (keypoints_sceneList [good_matches [i].trainIdx].pt);
    }

    MatOfPoint2f obj = new MatOfPoint2f ();
    MatOfPoint2f scene = new MatOfPoint2f ();

    obj.fromList (objList);
    scene.fromList (sceneList);

    Mat H = Calib3d.findHomography(obj, scene, Calib3d.RANSAC, 18);

    //////////////////////////////////////////////////////////////////////////////////////////////////

    Mat warp_mat = first_mat.clone();
    OpenCVForUnity.Size ims = new OpenCVForUnity.Size(first_mat.cols() + second_mat.cols(),first_mat.rows());
    Imgproc.warpPerspective(first_mat, warp_mat, H, ims);

    OpenCVForUnity.Rect _rect = new OpenCVForUnity.Rect(0,0,second_mat.cols(),second_mat.rows());
    Mat half = new Mat (warp_mat, _rect);
    second_mat.copyTo(half);
    second_mat = warp_mat;

    return warp_mat;


}