9

Я пытался смешивать два изображения. Текущий подход, который я принимаю, я получаю координаты перекрывающейся области двух изображений, и только для перекрывающихся областей, я смешиваю с жестко кодированной альфой 0,5, прежде чем добавлять ее. SO, в основном, я беру половину значения каждого пикселя из перекрывающихся областей обоих изображений и добавляю их. Это не дает мне идеальной смеси, потому что альфа-значение жестко закодировано до 0,5. Вот результат смешивания 3 изображений:Как получить правильное значение альфа, чтобы идеально сочетать два изображения?

Как вы можете видеть, переход от одного изображения к другому все еще виден. Как получить идеальную альфа-ценность, которая устранит этот видимый переход? Или нет такой вещи, и я ошибаюсь?

Вот как я сейчас делаю смешивание:

for i in range(3): 
      base_img_warp[overlap_coords[0], overlap_coords[1], i] = base_img_warp[overlap_coords[0], overlap_coords[1],i]*0.5 
      next_img_warp[overlap_coords[0], overlap_coords[1], i] = next_img_warp[overlap_coords[0], overlap_coords[1],i]*0.5 
final_img = cv2.add(base_img_warp, next_img_warp) 

Если кто-то хотел бы дать ему шанс, вот две деформированные изображения и маску их перекрытия: http://imgur.com/a/9pOsQ

+0

Источник изображения, кажется, предварительно умноженное с фоном. Не могли бы вы показать формулу, которую вы используете до сих пор? – K3N

+0

@ K3N, я отредактировал и добавил код. Дайте мне знать, если это поможет. – Metal

+2

Не могли бы вы предоставить 3 отдельных искаженных изображения, а также перекрывающиеся координаты? Это позволит людям проверять различные подходы. – Miki

ответ

8

Вот как я хотел бы сделать это в целом:

int main(int argc, char* argv[]) 
{ 
    cv::Mat input1 = cv::imread("C:/StackOverflow/Input/pano1.jpg"); 
    cv::Mat input2 = cv::imread("C:/StackOverflow/Input/pano2.jpg"); 

    // compute the vignetting masks. This is much easier before warping, but I will try... 
    // it can be precomputed, if the size and position of your ROI in the image doesnt change and can be precomputed and aligned, if you can determine the ROI for every image 
    // the compression artifacts make it a little bit worse here, I try to extract all the non-black regions in the images. 
    cv::Mat mask1; 
    cv::inRange(input1, cv::Vec3b(10, 10, 10), cv::Vec3b(255, 255, 255), mask1); 
    cv::Mat mask2; 
    cv::inRange(input2, cv::Vec3b(10, 10, 10), cv::Vec3b(255, 255, 255), mask2); 


    // now compute the distance from the ROI border: 
    cv::Mat dt1; 
    cv::distanceTransform(mask1, dt1, CV_DIST_L1, 3); 
    cv::Mat dt2; 
    cv::distanceTransform(mask2, dt2, CV_DIST_L1, 3); 

    // now you can use the distance values for blending directly. If the distance value is smaller this means that the value is worse (your vignetting becomes worse at the image border) 
    cv::Mat mosaic = cv::Mat(input1.size(), input1.type(), cv::Scalar(0, 0, 0)); 
    for (int j = 0; j < mosaic.rows; ++j) 
    for (int i = 0; i < mosaic.cols; ++i) 
    { 
     float a = dt1.at<float>(j, i); 
     float b = dt2.at<float>(j, i); 

     float alpha = a/(a + b); // distances are not between 0 and 1 but this value is. The "better" a is, compared to b, the higher is alpha. 
     // actual blending: alpha*A + beta*B 
     mosaic.at<cv::Vec3b>(j, i) = alpha*input1.at<cv::Vec3b>(j, i) + (1 - alpha)* input2.at<cv::Vec3b>(j, i); 
    } 

    cv::imshow("mosaic", mosaic); 

    cv::waitKey(0); 
    return 0; 
} 

в принципе вы вычислить расстояние от границы ROI до центра ваших объектов и вычислить ALP га из обоих значений смешивания маски. Поэтому, если одно изображение находится на большом расстоянии от границы, а другое - на небольшом расстоянии от границы, вы предпочитаете пиксель, который ближе к центру изображения. Было бы лучше нормализовать эти значения для случаев, когда искаженные изображения не имеют одинакового размера. Но еще лучше и эффективнее предкоммутировать маски наложения и деформировать их. Лучше всего было бы узнать виньетирование вашей оптической системы и выбрать и идентичную маску смешивания (как правило, более низкие значения границы).

Из предыдущего кода вы получите эти результаты: ROI маски:

enter image description here

enter image description here

Blending маски (так же, как впечатление, должно быть поплавок матрицы вместо):

enter image description here

enter image description here

мозаичное изображение:

enter image description here

+0

Эй, как вы получили маски. 'cv2.distanceTransform (img_1_mask, cv2.DIST_L1, 3)' просто возвращает исходную маску в python. – Metal

+0

перед отображением вам нужно их масштабировать, потому что значения float> = 1 отображаются белым цветом. Попробуйте 'imshow (windowname, dt1/255)' или sth. вроде этого (не знаю синтаксис numpy/python, извините) – Micka

+0

Это 'cv2.imshow (windowname, img/255)', спасибо! Также, задаваясь вопросом, есть ли более быстрый способ манипулировать всеми пикселями, а не повторять их все. Есть идеи? – Metal

4

Есть 2 очевидные проблемы с изображениями:

  1. Пограничный район искаженные условия освещения

    То есть, скорее всего, вызванные оптикой, используемой для получения изображений. Поэтому, чтобы исправить это, вы должны использовать только внутреннюю часть изображений (отрезать несколько пикселей от границы.

    Так что, когда отрезал 20 пикселей от границы и смешивание для общего освещения я получил это:

    border cut off

    Как вы можете видеть уродливые границы шов прочь теперь только проблемы освещения будет повторяться (см пули # 2).

  2. Изображения принимаются в различных условиях освещения

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

    bump

    Так остальная часть линии должна быть умножена на постоянной i0/i1. Эти типы, если удары могут возникать только по краям между значениями перекрытия, чтобы вы могли либо сканировать их, либо использовать эти позиции напрямую ... Чтобы распознать действительный бамп, у него должны быть соседки рядом в предыдущей и следующей строках вдоль всей высоты изображения.

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