cv::detail::MultiBandBlender странные белые полосы в конце фото

Я работаю с OpenCV 3.4.8 с С++ 11 и пытаюсь смешивать изображения вместе. В этом примере у меня есть 2 изображения (маска Тьера показана на экране ниже). У меня есть географическая привязка, поэтому я могу легко вычислить углы этих изображений в финальном изображении. Данные за пределами масок окрашены в черный цвет.

Маски изображений перед смешиванием

Мой код выглядит примерно так:

std::vector<cv::UMat> inputImages;
std::vector<cv::UMat> masks;
std::vector<cv::Point> corners;
std::vector<cv::Size> imgSizes;

/*
here is code where I load images, create thier masks 
(like in the screen above) and calculate corners.
*/

cv::Ptr<cv::detail::SeamFinder> seamFinder = new cv::detail::DpSeamFinder();
seamFinder->find(inputImages, corners, masks);

cv::Ptr<cv::detail::Blender> blender = new cv::detail:: MultiBandBlender(false);
blender->prepare(corners, imgSizes);
for(size_t i = 0; i < inputImages.size(); i++)
{
    blender->feed(inputImages[i], masks[i], corners[i]);
}

cv::UMat blendedImg, outMask;
blender->blend(blendedImg, outMask);

Линия стыка изображений

SeamFinder дает мне результат, как на экране выше. Найденные линии швов выглядят хорошо, и я ими очень довольна. Но другая проблема возникает на следующем шаге. MultiBandBlender создает странные белые полосы, когда линия стыка проходит в конце данных. Вот пример:

Изображения после смешивания

Когда я не использую блендер, а просто использую маски для вырезания исходных изображений и просто добавляю (cv::add()) изображения вместе с дополнительным альфа-каналом (сделанным из масок), я получаю очень хорошие результаты без каких-либо дыр и странных цветов, но мне нужно иметь более сглаженный переход :/

Может кто-нибудь помочь мне? Когда я создаю MultiBand Blender с меньшим num_bands, белые полосы становятся меньше, а с num_bands = 0 результаты выглядят так же, как и при добавлении изображений. Я посмотрел методы feed() и blend() в MultiBandBlender и думаю, что это связано с пирамидой Гаусса или Лапласа и окончательным восстановлением изображений из пирамиды Лапласа в методе blend().

РЕДАКТИРОВАТЬ 1: когда создаются пирамиды Гаусса и Лапласа, copyMakeBorder() не позволяет MultiBandBlender создавать эти белые полосы, когда изображения полностью заполнены данными. Поэтому в моем случае я думаю, что мне нужно создать свой блендер почти так же, как MultiBandBlender, но метод copyMakeBorder() в методе feed() изменить на что-то, что будет «расширять» мое изображение внутри маски, как предложил @AlexanderKondratskiy. Теперь я не знаю, как добиться правильного «расширения», похожего на BORDER_REFLECT или BORDER_REFLECT_101.


person Raffallo    schedule 09.01.2020    source источник
comment
Что эти изображения содержат в пикселях вне масок? На смешивание гауссовой/лапласианской пирамиды будут влиять пиксели за пределами маски.   -  person Alexander Kondratskiy    schedule 09.01.2020
comment
@AlexanderKondratskiy ой извините, я забыл сказать, что данные вне этих масок черные (добавил в основной пост)   -  person Raffallo    schedule 09.01.2020


Ответы (1)


Я подозреваю, что ваши входные изображения содержат белые пиксели за пределами этих масок. Белая полоса возникает вокруг областей, где шов точно следует за маской. Например, для лапласиана пиксели за пределами маски влияют на конечный результат, поскольку каждый слой пирамиды, по сути, является ядром размытия на изображении.

Если у вас есть какие-то хорошие данные за пределами маски, сохраните их. Если вы этого не сделаете, я предлагаю «расширить» ваше изображение за пределы маски, чтобы сохранить плавный переход.

Редактировать:

Вот две вещи, которые вы можете попробовать, если только не появится кто-то с большим опытом работы с OpenCV.

  1. Чтобы подтвердить/опровергнуть мою гипотезу, залейте черную область только средним или медианным цветом в пределах маски. Это должно сделать переход к внешней области менее резким и, надеюсь, уменьшить количество артефактов. Если этого не произойдет, мой ответ неверен.

  2. С точки зрения того, что, вероятно, является хорошим обобщением «BORDER_REFLECT», когда край произвольный, вы можете попробовать что-то вроде этого:

    • Find the centroid c of the mask polygon
    • Для каждого пикселя p за пределами маски подумайте о линии между ним и c.
    • Вычислите точку p' вдоль этой линии, которая находится на том же расстоянии внутри области маски, что и p от края маски. (т.е. вы отражаете вдоль края маски)
    • Линейно интерполируйте цвет от соседей p' (поскольку его положение может не попадать точно в середину пикселя). Это цвет пикселя p
person Alexander Kondratskiy    schedule 09.01.2020
comment
ой извините, я забыл сказать, что данные вне этих масок черные (я добавил это в основной пост). Вот почему я немного смущаюсь, когда у меня появляются белые полосы. У вас есть идея, как расширить данные из масок, чтобы не потерять качество в стыках с переходом и не размыть расширенные данные черными пикселями? - person Raffallo; 09.01.2020
comment
Я не могу быстро придумать что-либо в своей голове (на самом деле я не слишком хорошо знаком с OpenCV, просто имел дело с пирамидами Лапласа). Я отредактирую свой ответ с предложениями - person Alexander Kondratskiy; 10.01.2020