Alpha channel in OpenCV

后端 未结 3 359
遥遥无期
遥遥无期 2020-12-10 09:19

does OpenCV support alpha-channel? Or is there any way to work with transparent png? I need to merge two images, where the first one is background and the second one is imag

相关标签:
3条回答
  • 2020-12-10 09:24

    Here is a bash script that I threw together that will perform the ImageMagick conversion given by ypnos on all of the png files in a directory. You can make it recursive by replacing the * in the third line with a find command.

    #!/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 讨论(0)
  • 2020-12-10 09:37

    Updated answer: Use CV_LOAD_IMAGE_UNCHANGED flag to load all four channels (including Alpha) from the image. Then, use mixChannels() and/or split() to separate the alpha channel from others, and threshold on it, as explained below.

    Very old answer:

    OpenCV does not support alpha channel, only masking. If you want to read in PNG with alpha, use imagemagick first to extract alpha channel:

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

    Then in OpenCV you can do sth like this:

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

    ... to get a real mask (usable as mask matrix in OpenCV operations). Or you can use it in your own operations without the thresholding. To apply the mask it may also be a good idea to extend it to three channels:

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

    After that you can test it like this:

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

    Note: This is OpenCV 2.0 code.

    0 讨论(0)
  • 2020-12-10 09:37

    Input: cam_frame-background, media_frame-foreground,media_frame_alpha - alpha. Output: mixed by alpha transparent. If media_frame_alpha is IPL_DEPTH_8U use "cv::merge", because matrices must have equal dimension, size, channels. Work fast if opencv build with sse or avx. And more faster if use cv:GpuMat, must have nvidia cuda support and build opencv with 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;
    }
    
    0 讨论(0)
提交回复
热议问题