Most Efficient Alpha Blending

asked 2015-09-14 15:23:21 -0500

mbaltus gravatar image


I am trying to take a 4 channel image with an alpha channel and superimpose it on another 4 channel image. The background image has no data in it's alpha channel. The only alpha data that is of concern is associated with the foreground image. The following is a code snippet that does the math pixel by pixel. It works but is incredibly slow. What is the best way to speed this up or do the blending more efficiently somehow else? I am using OpenCV 3.0 (just updated).

    std::vector<cv::Mat> channels;
    split(sceneFinal, channels);

    //flip the alpha channel
    bitwise_not(channels[3], channels[3]);

    uchar rF, gF, bF, rB, gB, bB;
    for (int i = 0; i < sceneFinal.rows; ++i)
        cv::Vec4b* pixelFore = sceneFinal.ptr<cv::Vec4b>(i); // pointer to row to foreground pixels
        cv::Vec4b* pixelBack = dst.ptr<cv::Vec4b>(i); // pointer to row of background pixels

        for (int j = 0; j < sceneFinal.cols; ++j)
            uchar pixelAlpha = channels[3].at<uchar>(i,j); // alpha vlaue at this pixel
            double alphaVal = (int)pixelAlpha / 255.0;

            rF = pixelFore[j][2];
            gF = pixelFore[j][1];
            bF = pixelFore[j][0];

            rB = pixelBack[j][2];
            gB = pixelBack[j][1];
            bB = pixelBack[j][0];

            pixelBack[j][2] =  (rF * alphaVal) + (rB * (1.0 - alphaVal));
            pixelBack[j][1] = (gF * alphaVal) + (gB * (1.0 - alphaVal));
            pixelBack[j][0] = (bF * alphaVal) + (bB * (1.0 - alphaVal));

edit retag flag offensive close merge delete



Is it possible to do the operation on the whole matrices? Something like multiply the foreground image by the alpha image element-wise, then multiply the background image by the inverted alpha image and then add the two together?

mbaltus gravatar imagembaltus ( 2015-09-15 12:07:39 -0500 )edit