Альфа-канал в OpenCV - PullRequest
       27

Альфа-канал в OpenCV

4 голосов
/ 20 сентября 2009

OpenCV поддерживает альфа-канал? Или есть ли способ работать с прозрачным png? Мне нужно объединить два изображения, где первое - это фон, а второе - изображение, которое было повернуто cvWarpAffine. Я могу сделать это, объединяя пиксели один за другим и пропуская пиксели с некоторым значением, которое я установил в cvScalar в cvWarpAffine. Однако я не думаю, что это намеренное решение. Спасибо за предложения

Ответы [ 3 ]

8 голосов
/ 21 января 2010

Обновленный ответ: Используйте флаг CV_LOAD_IMAGE_UNCHANGED для загрузки всех четырех каналов (включая альфа-канал) из изображения. Затем используйте mixChannels() и / или split(), чтобы отделить альфа-канал от других, и установите для него пороговое значение, как описано ниже.

Очень старый ответ:

OpenCV не поддерживает альфа-канал, только маскирование. Если вы хотите читать в формате PNG с альфа-каналом, сначала используйте imagemagick для извлечения альфа-канала:

convert input.png -channel Alpha -negate -separate input-mask.png

Тогда в OpenCV вы можете сделать следующее:

Mat_<float> mask = imread("input-mask.png", 0);
threshold(mask, mask, 254., 1., THRESH_BINARY);

... чтобы получить настоящую маску (может использоваться как матрица масок в операциях OpenCV). Или вы можете использовать его в своих собственных операциях без порога. Чтобы применить маску, было бы неплохо расширить ее до трех каналов:

std::vector<Mat> marr(3, mask);
Mat_<Vec<float, 3> > maskRGB;
merge(marr, maskRGB);

После этого вы можете проверить это так:

imshow("Target", target);
imshow("Mask", mask*255);
imshow("Applied", target.mul(maskRGB));
waitKey();

Примечание: Это код OpenCV 2.0.

2 голосов
/ 14 ноября 2010

Вот сценарий bash, который я создал вместе, который будет выполнять преобразование ImageMagick, предоставляемое ypnos для всех файлов png в каталоге. Вы можете сделать его рекурсивным, заменив * в третьей строке командой find.

#!/bin/bash

for file in *
do
    if [[ $file =~ (.+)-mask\.png ]]; then
        echo "Ignoring mask $file"
    elif [[ $file =~ (.+)\.png ]]; then
        echo "Generating mask for $file"
        basefn=${BASH_REMATCH[1]}
        convert "$basefn.png" -channel Alpha -negate -separate "$basefn-mask.png"
    fi
done
0 голосов
/ 11 мая 2014

Ввод: cam_frame-background, media_frame-foreground, media_frame_alpha - альфа. Выход: смешанный альфа-прозрачный. Если media_frame_alpha - IPL_DEPTH_8U, используйте «cv :: merge», потому что матрицы должны иметь одинаковый размер, размер и каналы. Работайте быстро, если сборка opencv с sse или avx. И еще быстрее, если вы используете cv: GpuMat, должны иметь поддержку nvidia cuda и собрать opencv с cuda. ​​

inline cv::Mat frame_mix_alpha(cv::Mat &cam_frame,
 cv::Mat &media_frame,
 cv::Mat &media_frame_alpha)
{
    Mat suba = media_frame_alpha;
    //Mat alpha = cvCreateImage(media_frame_alpha.size(), IPL_DEPTH_8U, 1);
    //cvtColor(media_frame_alpha, alpha, CV_BGR2GRAY);

    //Mat suba;
    //Mat rgba[3] = { alpha, alpha, alpha };
    //merge(rgba, 3, suba);

    Mat subb = ~suba;

    //Mat mincam = min(cam_frame, suba);
    //Mat minmedia = min(media_frame, subb);
    //Mat result = (cam_frame - mincam) + (media_frame - minmedia);
    Mat result = (cam_frame - suba) + (media_frame - subb);

    return result;
}
...