Войны сшивки изображений

Пытаюсь сшить два изображения. технический стек - это opecv c ++ по сравнению с 2017 годом.

Я рассмотрел следующие изображения:

изображение1 кода:

а также

изображение2 кода:

Я нашел матрицу гомоографии, используя этот код. Я рассмотрел image1 и image2, как указано выше.

    int minHessian = 400;
    Ptr<SURF> detector = SURF::create(minHessian);
    vector< KeyPoint > keypoints_object, keypoints_scene;
    detector->detect(gray_image1, keypoints_object);
    detector->detect(gray_image2, keypoints_scene);

    
    Mat img_keypoints;
    drawKeypoints(gray_image1, keypoints_object, img_keypoints);
    imshow("SURF Keypoints", img_keypoints);

    Mat img_keypoints1;
    drawKeypoints(gray_image2, keypoints_scene, img_keypoints1);
    imshow("SURF Keypoints1", img_keypoints1);
    //-- Step 2: Calculate descriptors (feature vectors)
    Mat descriptors_object, descriptors_scene;
    detector->compute(gray_image1, keypoints_object, descriptors_object);
    detector->compute(gray_image2, keypoints_scene, descriptors_scene);

    //-- Step 3: Matching descriptor vectors using FLANN matcher

    Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::FLANNBASED);
    vector< DMatch > matches;
    matcher->match(descriptors_object, descriptors_scene, matches);


    double max_dist = 0; double min_dist = 100;

    //-- Quick calculation of max and min distances between keypoints 
    for (int i = 0; i < descriptors_object.rows; i++)
    {
        double dist = matches[i].distance;
        if (dist < min_dist) min_dist = dist;
        if (dist > max_dist) max_dist = dist;
    }

    printf("-- Max dist: %f \n", max_dist);
    printf("-- Min dist: %f \n", min_dist);


    //-- Use only "good" matches (i.e. whose distance is less than 3*min_dist )
    vector< DMatch > good_matches;
    Mat result, H;
    for (int i = 0; i < descriptors_object.rows; i++)
    {
        if (matches[i].distance < 3 * min_dist)
        {
            good_matches.push_back(matches[i]);
        }
    }
    Mat img_matches;
    drawMatches(gray_image1, keypoints_object, gray_image2, keypoints_scene, good_matches, img_matches, Scalar::all(-1),
        Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
    imshow("Good Matches", img_matches);
    std::vector< Point2f > obj;
    std::vector< Point2f > scene;
    cout << "Good Matches detected" << good_matches.size() << endl;
    for (int i = 0; i < good_matches.size(); i++)
    {
        //-- Get the keypoints from the good matches
        obj.push_back(keypoints_object[good_matches[i].queryIdx].pt);
        scene.push_back(keypoints_scene[good_matches[i].trainIdx].pt);
    }


    // Find the Homography Matrix for img 1 and img2
    H = findHomography(obj, scene, RANSAC);

Следующим шагом будет их деформация. Я использовал функцию перспективного преобразования, чтобы найти угол image1 на сшитом изображении. Я считал это количеством столбцов, которые будут использоваться в Mat result. Это код, который я написал - ›

    vector<Point2f> imageCorners(4);
    imageCorners[0] = Point(0, 0);
    imageCorners[1] = Point(image1.cols, 0);
    imageCorners[2] = Point(image1.cols, image1.rows);
    imageCorners[3] = Point(0, image1.rows);
    vector<Point2f> projectedCorners(4);
    perspectiveTransform(imageCorners, projectedCorners, H);
    Mat result;
    warpPerspective(image1, result, H, Size(projectedCorners[2].x, image1.rows));
    Mat half(result, Rect(0, 0, image2.cols, image2.rows));
    image2.copyTo(half);
    imshow("result", result);

Я получаю сшитый вывод этих изображений. Но проблема в размере изображения. Я проводил сравнение, вручную комбинируя два исходных изображения с результатом приведенного выше кода. Размер результата из кода больше. Что мне делать, чтобы он был идеального размера? Идеальный размер должен быть image1.cols + image2.cols - overlapping length.


person Adi shukla    schedule 16.06.2021    source источник


Ответы (1)


warpPerspective(image1, result, H, Size(projectedCorners[2].x, image1.rows));

Эта строка кажется проблемной. Вам следует выбрать точки экстремума по размеру.

Rect rec = boundingRect(projectedCorners);
warpPerspective(image1, result, H, rec.size());

Но вы потеряете детали, если rec.tl() упадет на отрицательные оси, поэтому вам следует сместить матрицу гомографии, чтобы она попала в первый квадрант. См. Раздел Деформация в перспективу моего ответа на вопрос Быстрый и надежный алгоритм сшивания изображений для многих изображений в Python.

person Burak    schedule 16.06.2021