No , there is no API in OpenCV that offers this feature nativelly. On the other hand, nothing prevents you from writing your own code for this.
A few weeks ago, some changes were made to a function that I saw somewhere on the Internet in order to be able to:
- Transfer two input images: background as BGR and foreground as BGRA ;
- Mix them together according to a simple transparency rule;
(I donβt remember where most of this code came from, sorry ... but thank you, whoever you are!)
void overlayImage(const cv::Mat &background, const cv::Mat &foreground, cv::Mat &output, cv::Point2i location, double opacity = 1.0) { background.copyTo(output); // start at the row indicated by location, or at row 0 if location.y is negative. for (int y = std::max(location.y , 0); y < background.rows; ++y) { int fY = y - location.y; // because of the translation // we are done of we have processed all rows of the foreground image. if (fY >= foreground.rows) break; // start at the column indicated by location, or at column 0 if location.x is negative. for (int x = std::max(location.x, 0); x < background.cols; ++x) { int fX = x - location.x; // because of the translation. // we are done with this row if the column is outside of the foreground image. if (fX >= foreground.cols) break; // determine the opacity of the foregrond pixel, using its fourth (alpha) channel. double opacity_level = ((double)foreground.data[fY * foreground.step + fX * foreground.channels() + 3]) / 255.; if (opacity >= 0.0 && opacity < 1.0) opacity_level *= opacity; // and now combine the background and foreground pixel, using the opacity, but only if opacity > 0. for (int c = 0; opacity_level > 0 && c < output.channels(); ++c) { unsigned char foregroundPx = foreground.data[fY * foreground.step + fX * foreground.channels() + c]; unsigned char backgroundPx = background.data[y * background.step + x * background.channels() + c]; output.data[y*output.step + output.channels()*x + c] = backgroundPx * (1.-opacity_level) + foregroundPx * opacity_level; } } } }
Below you will find the input images used for testing: on the left is the background, and the image on the right is the foreground.


To copy the foreground completely to the background, simply do:
cv::Mat background = cv::imread("road.png"); // 3-chan BGR cv::Mat foreground= cv::imread("tulip.png", -1); // 4-chan BGRA cv::Point location(0, 0); cv::Mat output; overlayImage(input_bkg, input_target, output, location, 1.0); cv::imwrite("output_alpha1.0.png", output);
and make a copy with 50% transparency:
overlayImage(input_bkg, input_target, output, location, 0.5); cv::imwrite("output_alpha0.5.png", output);
Here are the results:


This implementation is not bulletproof for production purposes, so use it at your own risk.