2012-05-20 3 views
4

Как наложить два изображения? По сути, у меня есть фон без альфа-канала и одно или несколько изображений, которые имеют альфа-канал, которые должны быть наложены друг на друга.Как накладывать изображения с помощью OpenCv?

Я попытался следующий код, но результат наложения ужасна:

// create our out image 
Mat merged (info.width, info.height, CV_8UC4); 

// get layers 
Mat layer1Image = imread(layer1Path); 
Mat layer2Image = imread(layer2Path); 

addWeighted(layer1Image, 0.5, layer2Image, 0.5, 0.0, merged); 

Я также попытался с помощью слияния, но я где-то читал, что он не поддерживает альфа-канал?

ответ

5

Я не знаю о функции OpenCV, которая делает это. Но вы могли бы просто реализовать его сами. Он похож на функцию addWeighted. Но вместо фиксированного веса 0.5 весы вычисляются из альфа-канала наложенного изображения.

Mat img = imread("bg.bmp"); 
    Mat dst(img); 
    Mat ov = imread("ov.tiff", -1); 


    for(int y=0;y<img.rows;y++) 
    for(int x=0;x<img.cols;x++) 
    { 
      //int alpha = ov.at<Vec4b>(y,x)[3]; 
      int alpha = 256 * (x+y)/(img.rows+img.cols); 
      dst.at<Vec3b>(y,x)[0] = (1-alpha/256.0) * img.at<Vec3b>(y,x)[0] + (alpha * ov.at<Vec3b>(y,x)[0]/256); 
      dst.at<Vec3b>(y,x)[1] = (1-alpha/256.0) * img.at<Vec3b>(y,x)[1] + (alpha * ov.at<Vec3b>(y,x)[1]/256); 
      dst.at<Vec3b>(y,x)[2] = (1-alpha/256.0) * img.at<Vec3b>(y,x)[2] + (alpha * ov.at<Vec3b>(y,x)[2]/256); 
    } 

    imwrite("bg_ov.bmp",dst); 

Обратите внимание, что я не смог прочитать файл с альфа-каналом, потому что, по-видимому, OpenCV не поддерживает это. Вот почему я вычислил альфа-значение из координат, чтобы получить какой-то градиент.

+0

А! Совершенно! Я действительно смог использовать ваш код и модифицировал его, чтобы поддерживать 4 канала Vect4b и не понравился вашей первой альфа-линии. Perfect работает очень хорошо! :) – Jona

+1

Это, кажется, не очень эффективно. –

+0

Этот код работает хорошо, но слишком много времени для изображений большого размера, например, для изображения 6.4MP с водяным знаком 500 КБ, он занимает 45 секунд. –

0

Скорее всего, количество подключенных каналов отличается от входов. Вы можете заменить

Mat merged (info.width, info.height, CV_8UC4); 

с этим:

Mat merged; 

Таким образом, вы будете пусть метод addWeighted создать матрицу назначения с правильными параметрами.

+0

Спасибо за быстрый ответ. Проблема с сбоем, которую я просто понимаю, объясняется тем, что layer2 не соответствует размеру layer1. :(Я попытался объединить изображения, но они выглядят неплохо. Я пробовал играть с альфой и бета-версией, но я не могу получить нетронутый образ, чтобы просто наложить на него. – Jona

Смежные вопросы