Подтвердить что ты не робот

Как выровнять 2 изображения на основе их содержимого с помощью OpenCV

Я абсолютно новичок в OpenCV, и я начал погружаться в него. Но мне нужна небольшая помощь.

Итак, я хочу объединить эти 2 изображения:

введите описание изображения здесь

Я хотел бы, чтобы 2 изображения соответствовали их ребрам (игнорируя сейчас очень правую часть изображения)

Может ли кто-нибудь указать мне правильное направление? Я попытался использовать функцию findTransformECC. Здесь моя реализация:

cv::Mat im1 = [imageArray[1] CVMat3];
cv::Mat im2 = [imageArray[0] CVMat3];

// Convert images to gray scale;
cv::Mat im1_gray, im2_gray;
cvtColor(im1, im1_gray, CV_BGR2GRAY);
cvtColor(im2, im2_gray, CV_BGR2GRAY);

// Define the motion model
const int warp_mode = cv::MOTION_AFFINE;

// Set a 2x3 or 3x3 warp matrix depending on the motion model.
cv::Mat warp_matrix;

// Initialize the matrix to identity
if ( warp_mode == cv::MOTION_HOMOGRAPHY )
    warp_matrix = cv::Mat::eye(3, 3, CV_32F);
else
    warp_matrix = cv::Mat::eye(2, 3, CV_32F);

// Specify the number of iterations.
int number_of_iterations = 50;

// Specify the threshold of the increment
// in the correlation coefficient between two iterations
double termination_eps = 1e-10;

// Define termination criteria
cv::TermCriteria criteria (cv::TermCriteria::COUNT+cv::TermCriteria::EPS,   number_of_iterations, termination_eps);

// Run the ECC algorithm. The results are stored in warp_matrix.
findTransformECC(
                 im1_gray,
                 im2_gray,
                 warp_matrix,
                 warp_mode,
                 criteria
                 );

// Storage for warped image.
cv::Mat im2_aligned;

if (warp_mode != cv::MOTION_HOMOGRAPHY)
    // Use warpAffine for Translation, Euclidean and Affine
    warpAffine(im2, im2_aligned, warp_matrix, im1.size(), cv::INTER_LINEAR + cv::WARP_INVERSE_MAP);
else
    // Use warpPerspective for Homography
    warpPerspective (im2, im2_aligned, warp_matrix, im1.size(),cv::INTER_LINEAR + cv::WARP_INVERSE_MAP);


UIImage* result =  [UIImage imageWithCVMat:im2_aligned];
return result;

Я пробовал играть с termination_eps и number_of_iterations и увеличил/уменьшил эти значения, но они действительно не имели большого значения.

Итак, вот результат:

введите описание изображения здесь

Что я могу сделать, чтобы улучшить свой результат?

EDIT: Я отметил проблематичные края красными кругами. Цель состоит в том, чтобы деформировать нижнее изображение и сделать его совпадающим с строками из изображения выше:

введите описание изображения здесь

Я немного научился, и я боюсь, что функция findTransformECC не даст мне результата, который я хотел бы иметь: - (

Что-то важное для добавления: У меня на самом деле есть массив этих "полосок" изображений, в этом случае они выглядят примерно так, как показано на рисунках, и все они должны быть обработаны в соответствии с линией. Я попытался экспериментировать с функцией stitch OpenCV, но результаты были ужасными.

EDIT:

Вот 3 исходных изображения:

1

2

3

Результат должен быть примерно таким:

result

Я преобразовал каждое изображение вдоль линий, которые должны совпадать. Линии, находящиеся слишком далеко друг от друга, можно игнорировать (тень и участок дороги на правой части изображения).

4b9b3361

Ответ 1

По вашим изображениям кажется, что они перекрываются. Поскольку вы сказали, что функция stitch не дает вам желаемых результатов, выполните свою собственную сшивку. Я тоже пытаюсь сделать что-то близкое. Вот учебник о том, как реализовать его в С++: https://ramsrigoutham.com/2012/11/22/panorama-image-stitching-in-opencv/

Ответ 2

Вы можете использовать алгоритм Hough с высоким порогом на двух изображениях, а затем сравнить вертикальные линии на обоих из них - большинство из них нужно немного сдвинуть, но удерживайте угол.

Вот что я получил от запуска этого алгоритма на одном из изображений:

Алгоритм Houghlines в первом примере

Фильтрация горизонтальных линий должна быть легкой (поскольку они представлены как Vec4i), а затем вы можете выровнять оставшиеся строки вместе.

Вот пример его использования в документации OpenCV.

ОБНОВЛЕНИЕ: еще одна мысль. Выравнивание линий вместе может быть выполнено с помощью концепции, аналогичной тому, как работает функция взаимной корреляции. Не имеет значения, имеет ли картинка 1 10 строк, а на картинке 2 - 100 строк, положение сдвига с большинством выровненных строк (что, в основном, максимум для CCF) должно быть довольно близко к ответу, хотя для этого может потребоваться некоторая настройка - например, давая вес каждой строке, основанной на ее длине, углу и т.д. Компьютерное зрение никогда не имеет прямого пути, да:)

ОБНОВЛЕНИЕ 2: Мне действительно интересно, если взять нижнюю линию пикселей верхнего изображения в виде массива 1 и верхнюю линию пикселей нижнего изображения в виде массива 2 и запустить общий CCF над ними, а затем использовать его максимум, поскольку сдвиг также может работать... Но я думаю, что это был бы известный метод, если бы он работал хорошо.