I am experiencing strange behavior with alpha compositing using OpenCV 3.4.1 and Cuda.
When I blend an all-black image with an all-zero alpha channel to another image, and repeat this process recursively, the image becomes darker, settling at around 50% brightness.
Is this some kind of bug, or am I misunderstanding something fundamental about alpha compositing? The documentation on the different blend modes is sparse.
I have written a short example code illustrating what happens. When run once, the rectangle seems to stay green. However, putting this in a loop makes the rectangle slowly fade out until it becomes dark-green.
#include <stdio.h>
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/cuda.hpp>
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/cudaarithm.hpp>
using namespace std;
using namespace cv;
int main(int argc, char *argv[])
{
Mat frame(1080, 1920, CV_8UC4, Scalar(0, 0, 0, 255));
namedWindow("test", CV_WINDOW_OPENGL);
// Drawing a green rectangle with 100% opacity
rectangle(frame, Rect(10, 10, 200, 200), Scalar(0, 255, 0, 255), CV_FILLED);
cuda::GpuMat gpuFrame(frame);
while(true){
// Creating an all-black image with 0% opacity
cuda::GpuMat gpuBlank(1080, 1920, CV_8UC4, Scalar(0, 0, 0, 0));
// Alpha-compositing them together should keep the image untouched..?
cuda::alphaComp(gpuFrame, gpuBlank, gpuFrame, cuda::ALPHA_OVER);
// Splitting the image into 4 mats, to remove any resulting opacity from the image
// Hopefully coming out with another 100% opacity image to blend again
vector<cuda::GpuMat> frameChannels;
cuda::split(gpuFrame, frameChannels);
cuda::GpuMat fullAlpha(1080, 1920, CV_8UC1, Scalar(255));
if (gpuFrame.channels() > 3) {
frameChannels.pop_back();
}
frameChannels.push_back(fullAlpha);
cuda::merge(frameChannels, gpuFrame);
imshow("test", gpuFrame);
waitKey(1);
}
while(1) {
waitKey(1);
}
}